@greatapps/common 1.1.714 → 1.1.716

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/index.mjs.map +1 -1
  2. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs +1 -1
  3. package/dist/modules/ia-credits/handlers/list-ia-credits.handler.mjs.map +1 -1
  4. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs +27 -34
  5. package/dist/modules/ia-credits/hooks/ia-credits.hook.mjs.map +1 -1
  6. package/dist/modules/ia-credits/services/ia-credits.service.mjs +33 -11
  7. package/dist/modules/ia-credits/services/ia-credits.service.mjs.map +1 -1
  8. package/dist/modules/ia-credits/types.mjs +12 -1
  9. package/dist/modules/ia-credits/types.mjs.map +1 -1
  10. package/dist/testing/constants.mjs.map +1 -1
  11. package/dist/testing/factories/create-mock.mjs.map +1 -1
  12. package/dist/testing/factories/subscription.factory.mjs.map +1 -1
  13. package/dist/testing/index.mjs.map +1 -1
  14. package/dist/testing/msw/envelope.mjs.map +1 -1
  15. package/dist/testing/msw/session.handlers.mjs.map +1 -1
  16. package/dist/testing/react/test-query-client.mjs.map +1 -1
  17. package/package.json +11 -12
  18. package/src/index.ts +2 -0
  19. package/src/modules/ia-credits/handlers/list-ia-credits.handler.ts +1 -1
  20. package/src/modules/ia-credits/hooks/ia-credits.hook.ts +33 -46
  21. package/src/modules/ia-credits/services/ia-credits.service.ts +73 -37
  22. package/src/modules/ia-credits/types.ts +30 -1
  23. package/src/testing/constants.ts +3 -12
  24. package/src/testing/factories/create-mock.ts +3 -8
  25. package/src/testing/factories/subscription.factory.ts +1 -2
  26. package/src/testing/index.ts +4 -8
  27. package/src/testing/msw/envelope.ts +1 -5
  28. package/src/testing/msw/session.handlers.ts +3 -7
  29. package/src/testing/react/test-query-client.ts +1 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\n// Style types now come from whitelabel schema directly\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\nexport {\n NavigationProvider,\n useNavigationFallback,\n} from \"./providers/navigation.provider\";\n\n// Navigation (safe drop-in replacement for next/navigation)\nexport { useRouter } from \"./hooks/useRouter\";\nexport type { SafeAppRouter } from \"./hooks/useRouter\";\nexport {\n usePathname,\n useSearchParams,\n useParams,\n redirect,\n notFound,\n} from \"./utils/next-navigation\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport {\n useListAllAccountUsers,\n LIST_ALL_ACCOUNT_USERS_QUERY_KEY,\n LIST_ALL_ACCOUNT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-all-account-users.hook\";\nexport {\n useProjects,\n PROJECTS_BASE_KEY,\n PROJECTS_QUERY_KEY,\n} from \"./modules/projects/hooks/list-projects.hook\";\nexport {\n useInfiniteProjects,\n INFINITE_PROJECTS_QUERY_KEY,\n} from \"./modules/projects/hooks/list-infinite-projects.hook\";\nexport { useProject } from \"./modules/projects/hooks/find-project.hook\";\nexport { useCreateProject } from \"./modules/projects/hooks/create-project.hook\";\nexport { useUpdateProject } from \"./modules/projects/hooks/update-project.hook\";\nexport { useDeleteProject } from \"./modules/projects/hooks/delete-project.hook\";\nexport type {\n Project,\n ProjectsPage,\n CreateProjectRequest,\n UpdateProjectRequest,\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport { ProjectSchema } from \"./modules/projects/types\";\nexport type { ListProjectsActionParams } from \"./modules/projects/actions/list-projects.action\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport { useManagementPermissions } from \"./modules/auth/hooks/useManagementPermissions\";\nexport type { ManagementPermission } from \"./modules/auth/types/management-permission.type\";\nexport { useSocialGoogleLogin } from \"./modules/auth/hooks/social-google-login.hook\";\nexport { useSocialGoogleOnboarding } from \"./modules/auth/hooks/social-google-onboarding.hook\";\nexport { useUnlinkGoogle } from \"./modules/auth/hooks/unlink-google.hook\";\nexport { useSubscriptions } from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport {\n SUBSCRIPTIONS_QUERY_KEY,\n CHARGES_QUERY_KEY,\n} from \"./modules/subscriptions/constants/query-keys.constants\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useCancelledSubscriptionGuard } from \"./modules/subscriptions/hooks/use-cancelled-subscription-guard\";\nexport { usePlanById } from \"./modules/plans/hooks/use-plan-by-id.hook\";\nexport { useHasPlanAddon } from \"./modules/plans/hooks/use-has-plan-addon.hook\";\nexport { useCalculateSubscription } from \"./modules/subscriptions/hooks/calculate-subscription.hook\";\nexport { useUpdateSubscriptionPlan } from \"./modules/subscriptions/hooks/update-subscription-plan.hook\";\nexport { useUpdateSubscriptionPayment } from \"./modules/subscriptions/hooks/update-subscription-payment.hook\";\nexport { useCards, CARDS_QUERY_KEY } from \"./modules/cards/hooks/cards.hook\";\nexport { useCardById } from \"./modules/cards/hooks/card-by-id.hook\";\nexport { useCreateCard } from \"./modules/cards/hooks/create-card.hook\";\nexport { useCreateSetupIntent } from \"./modules/cards/hooks/create-setup-intent.hook\";\nexport { useSetDefaultCard } from \"./modules/cards/hooks/set-default-card.hook\";\nexport { useDeleteCard } from \"./modules/cards/hooks/delete-card.hook\";\nexport { useDeleteConfirmation } from \"./modules/cards/hooks/delete-confirmation.hook\";\nexport type { DeleteConfirmationFormData } from \"./modules/cards/hooks/delete-confirmation.hook\";\nexport { useHandleDeleteCard } from \"./modules/cards/hooks/handle-delete-card.hook\";\nexport { useCharges } from \"./modules/charges/hooks/charges.hook\";\nexport { useChargeById } from \"./modules/charges/hooks/charge-by-id.hook\";\nexport { useChargeAction } from \"./modules/charges/hooks/charge-action.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n ADDON_IDS,\n AI_CREDIT_OPTIONS,\n AI_CREDIT_VALUES,\n} from \"./modules/subscriptions/constants/addons.constants\";\nexport type {\n AddonKindEnum,\n AiCreditOption,\n} from \"./modules/subscriptions/constants/addons.constants\";\nexport type {\n Plan,\n PlanItem,\n UiPlan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n PlanTooltips,\n} from \"./modules/plans/types/plan.type\";\nexport { PlanSchema, PlanItemSchema } from \"./modules/plans/types/plan.type\";\nexport {\n mapApiPlanToUiPlan,\n mapApiPlanToUiPlanForCurrency,\n} from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport type { PlanBillingPeriod } from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport {\n usePlans,\n PLANS_QUERY_KEY,\n} from \"./modules/plans/hooks/list-plans.hook\";\nexport type { BillingPeriod } from \"./modules/subscriptions/types/billing-period.type\";\nexport type {\n CalculateSubscriptionRequest,\n CalculateSubscriptionResponse,\n UpdateSubscriptionPlanRequest,\n} from \"./modules/subscriptions/types/calculate-subscription.type\";\nexport {\n PixPendingDataSchema,\n SubscriptionPendingPixResponseSchema,\n isSubscriptionPendingPixResponse,\n} from \"./modules/subscriptions/types/pix-pending.type\";\nexport type {\n PixPendingData,\n SubscriptionPendingPixResponse,\n} from \"./modules/subscriptions/types/pix-pending.type\";\nexport type {\n Card as PaymentCard,\n CreateCardRequest,\n FindCardsParams,\n SetupIntent,\n} from \"./modules/cards/types\";\nexport {\n CardSchema as PaymentCardSchema,\n CreateCardRequestSchema,\n FindCardsParamsSchema,\n SetupIntentSchema,\n} from \"./modules/cards/types\";\nexport type {\n Charge,\n FindChargesParams,\n PayChargeInput,\n} from \"./modules/charges/types/charge.type\";\nexport {\n ChargeSchema,\n FindChargesParamsSchema,\n PayChargeInputSchema,\n} from \"./modules/charges/types/charge.type\";\nexport { buildPlanExtras } from \"./modules/subscriptions/utils/build-plan-extras\";\nexport { hasSubscriptionExpired } from \"./modules/subscriptions/utils/has-subscription-expired\";\nexport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"./modules/subscriptions/constants/subscription.constants\";\nexport {\n useCountPages,\n COUNT_PAGES_QUERY_KEY,\n} from \"./modules/pages/hooks/count-pages.hook\";\nexport { PAGES_QUERY_KEY } from \"./modules/pages/constants/query-keys.constants\";\nexport {\n getPriceFromCalculatedData,\n getOriginalPriceFromCalculatedData,\n periodicityToBillingPeriod,\n} from \"./modules/subscriptions/utils/periodicity\";\nexport { useBuyCreditsModal } from \"./store/useBuyCreditsModal\";\nexport { useCreditsDisabledModal } from \"./store/useCreditsDisabledModal\";\nexport { usePaidPlanRequiredModal } from \"./store/usePaidPlanRequiredModal\";\nexport { useHexaPromoModal } from \"./store/useHexaPromoModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as CreditsDisabledModal } from \"./components/modals/CreditsDisabledModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as HexaPromoModal } from \"./components/modals/HexaPromoModal\";\nexport { default as HexaPromoModalGate } from \"./components/modals/HexaPromoModalGate\";\nexport { default as AddCardModal } from \"./components/modals/cards/AddCardModal\";\nexport { DeleteCardModal } from \"./components/modals/cards/DeleteCardModal\";\nexport { CannotDeleteCardModal } from \"./components/modals/cards/CannotDeleteCardModal\";\nexport {\n CardFormFields,\n cardFormSchema,\n buildCardFormSchema,\n} from \"./components/modals/cards/CardFormFields\";\nexport type { CardFormData } from \"./components/modals/cards/CardFormFields\";\nexport { Skeleton } from \"./components/ui/feedback/Skeleton\";\nexport { PaymentInfoCard } from \"./components/ui/data-display/PaymentInfoCard\";\nexport { CardBrandIcon } from \"./components/ui/data-display/CardBrandIcons\";\nexport { CardItem } from \"./components/ui/data-display/CardItem\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { formatShortDate, formatDateTime, calendarDateSchema, toCalendarDate, daysBetween } from \"./infra/utils/date\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\nexport { resolveSafeRedirect, sameHostOr } from \"./utils/redirect\";\nexport { COUNTRIES, flagUrl } from \"./utils/countries\";\nexport type { Country } from \"./utils/countries\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { NotFoundPage } from \"./components/pages/NotFoundPage\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { default as WhitelabelCodes } from \"./components/layouts/WhitelabelCodes\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from \"./components/navigation/AppNavigation\";\nexport { CancelledSubscriptionBanner } from \"./components/navigation/CancelledSubscriptionBanner\";\nexport { SubscriptionBanner } from \"./components/navigation/SubscriptionBanner\";\nexport { OverdueInvoiceBanner } from \"./components/navigation/OverdueInvoiceBanner\";\nexport { UpcomingInvoiceBanner } from \"./components/navigation/UpcomingInvoiceBanner\";\nexport { TrialBanner } from \"./components/navigation/TrialBanner\";\nexport type { NavItemConfig } from \"./components/navigation/subcomponents/NavItems\";\nexport { useMobileNavbarSheet } from \"./store/useMobileNavbarSheet\";\n\n// Auth Query Key Utilities\nexport {\n useAuthQueryKey,\n useWlQueryKey,\n useWlId,\n} from \"./hooks/useAuthQueryKey\";\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport { useBrandLoadingIcon } from \"./hooks/useBrandLoadingIcon\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Embeds\nexport { FrillEmbed } from \"./components/embeds/FrillEmbed\";\nexport {\n CrispEmbed,\n openCrispHelpdesk,\n hideCrisp,\n showCrisp,\n updateCrispUser,\n} from \"./components/embeds/CrispEmbed\";\nexport { EmbedWidgets } from \"./components/embeds/EmbedWidgets\";\nexport { ClarityEmbed } from \"./components/embeds/ClarityEmbed\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useDesktopSidebarStore } from \"./store/useDesktopSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCNPJ,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport {\n formatCurrency,\n formatCurrencyNumber,\n parseCurrencyToNumber,\n getCurrencyForGateway,\n} from \"./utils/format/currency\";\nexport type { CurrencyCode } from \"./utils/format/currency\";\nexport { isValidCPF, isValidCNPJ, isValidTaxId } from \"./utils/validators/common\";\nexport { BR_STATE_OPTIONS } from \"./utils/constants/br-states\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport { useCurrencyFormatter } from \"./modules/accounts/hooks/use-currency-formatter.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n ACCOUNT_USERS_QUERY_KEY,\n} from \"./modules/accounts/hooks/useAccountManagement\";\nexport { useViaCep } from \"./modules/accounts/hooks/useViaCep\";\nexport { useAccountToken } from \"./modules/accounts/hooks/use-account-token.hook\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n\n// Image Upload\nexport {\n ImageUpload,\n ImageCropModal,\n ImageTooSmallModal,\n} from \"./components/widgets/ImageUpload\";\nexport {\n useImageUpload,\n type ImageTooSmallError,\n} from \"./modules/images/hooks/use-image-upload.hook\";\nexport {\n ACCEPTED_IMAGE_FORMATS,\n ACCEPTED_IMAGE_FORMATS_STRING,\n MAX_FILE_SIZE_MB,\n} from \"./modules/images/constants/image.constants\";\nexport type {\n ImageConfig,\n CropArea,\n ProcessedImage,\n CompressImageOptions,\n} from \"./modules/images/types/image.type\";\nexport { compressImage } from \"./modules/images/utils/compress-image\";\nexport { cropImageToCanvas } from \"./modules/images/utils/crop-image\";\nexport { base64ToFile, fileToBase64 } from \"./modules/images/utils/base64\";\nexport {\n validateImage,\n validateImageFormat,\n validateImageSize,\n getImageDimensions,\n} from \"./modules/images/utils/validate-image\";\n"],"mappings":"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","names":["default","LANGUAGE_OPTIONS"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Types\nexport * from \"./modules/auth/schema\";\nexport * from \"./modules/users/schema\";\nexport * from \"./modules/whitelabel/schema\";\n// Style types now come from whitelabel schema directly\nexport * from \"./infra/api/types\";\n\n// Contexts\nexport * from \"./providers/query.provider\";\nexport * from \"./providers/auth.provider\";\nexport * from \"./providers/whitelabel.provider\";\nexport {\n NavigationProvider,\n useNavigationFallback,\n} from \"./providers/navigation.provider\";\n\n// Navigation (safe drop-in replacement for next/navigation)\nexport { useRouter } from \"./hooks/useRouter\";\nexport type { SafeAppRouter } from \"./hooks/useRouter\";\nexport {\n usePathname,\n useSearchParams,\n useParams,\n redirect,\n notFound,\n} from \"./utils/next-navigation\";\n\n// Hooks\nexport {\n useListProjectUsers,\n LIST_PROJECT_USERS_QUERY_KEY,\n LIST_PROJECT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-project-users.hook\";\nexport {\n useListAvailableUsers,\n LIST_AVAILABLE_USERS_QUERY_KEY,\n LIST_AVAILABLE_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-available-users.hook\";\nexport {\n useListAllAccountUsers,\n LIST_ALL_ACCOUNT_USERS_QUERY_KEY,\n LIST_ALL_ACCOUNT_USERS_BASE_KEY,\n} from \"./modules/projects/hooks/list-all-account-users.hook\";\nexport {\n useProjects,\n PROJECTS_BASE_KEY,\n PROJECTS_QUERY_KEY,\n} from \"./modules/projects/hooks/list-projects.hook\";\nexport {\n useInfiniteProjects,\n INFINITE_PROJECTS_QUERY_KEY,\n} from \"./modules/projects/hooks/list-infinite-projects.hook\";\nexport { useProject } from \"./modules/projects/hooks/find-project.hook\";\nexport { useCreateProject } from \"./modules/projects/hooks/create-project.hook\";\nexport { useUpdateProject } from \"./modules/projects/hooks/update-project.hook\";\nexport { useDeleteProject } from \"./modules/projects/hooks/delete-project.hook\";\nexport type {\n Project,\n ProjectsPage,\n CreateProjectRequest,\n UpdateProjectRequest,\n ProjectUser,\n AccountUser,\n AddRemoveProjectUsersParams,\n ListUsersParams,\n UsersPage,\n} from \"./modules/projects/types\";\nexport { ProjectSchema } from \"./modules/projects/types\";\nexport type { ListProjectsActionParams } from \"./modules/projects/actions/list-projects.action\";\nexport {\n useUserQuery,\n useUserValidateSession,\n useInvalidateUser,\n useSetUserData,\n useTwoFactorVerify,\n USER_QUERY_KEY,\n} from \"./modules/auth/hooks/useUserQuery\";\nexport { useManagementPermissions } from \"./modules/auth/hooks/useManagementPermissions\";\nexport type { ManagementPermission } from \"./modules/auth/types/management-permission.type\";\nexport { useSocialGoogleLogin } from \"./modules/auth/hooks/social-google-login.hook\";\nexport { useSocialGoogleOnboarding } from \"./modules/auth/hooks/social-google-onboarding.hook\";\nexport { useUnlinkGoogle } from \"./modules/auth/hooks/unlink-google.hook\";\nexport { useSubscriptions } from \"./modules/subscriptions/hooks/list-subscriptions.hook\";\nexport {\n SUBSCRIPTIONS_QUERY_KEY,\n CHARGES_QUERY_KEY,\n} from \"./modules/subscriptions/constants/query-keys.constants\";\nexport { useActiveSubscription } from \"./modules/subscriptions/hooks/find-active-subscription.hook\";\nexport { useCancelledSubscriptionGuard } from \"./modules/subscriptions/hooks/use-cancelled-subscription-guard\";\nexport { usePlanById } from \"./modules/plans/hooks/use-plan-by-id.hook\";\nexport { useHasPlanAddon } from \"./modules/plans/hooks/use-has-plan-addon.hook\";\nexport { useCalculateSubscription } from \"./modules/subscriptions/hooks/calculate-subscription.hook\";\nexport { useUpdateSubscriptionPlan } from \"./modules/subscriptions/hooks/update-subscription-plan.hook\";\nexport { useUpdateSubscriptionPayment } from \"./modules/subscriptions/hooks/update-subscription-payment.hook\";\nexport { useCards, CARDS_QUERY_KEY } from \"./modules/cards/hooks/cards.hook\";\nexport { useCardById } from \"./modules/cards/hooks/card-by-id.hook\";\nexport { useCreateCard } from \"./modules/cards/hooks/create-card.hook\";\nexport { useCreateSetupIntent } from \"./modules/cards/hooks/create-setup-intent.hook\";\nexport { useSetDefaultCard } from \"./modules/cards/hooks/set-default-card.hook\";\nexport { useDeleteCard } from \"./modules/cards/hooks/delete-card.hook\";\nexport { useDeleteConfirmation } from \"./modules/cards/hooks/delete-confirmation.hook\";\nexport type { DeleteConfirmationFormData } from \"./modules/cards/hooks/delete-confirmation.hook\";\nexport { useHandleDeleteCard } from \"./modules/cards/hooks/handle-delete-card.hook\";\nexport { useCharges } from \"./modules/charges/hooks/charges.hook\";\nexport { useChargeById } from \"./modules/charges/hooks/charge-by-id.hook\";\nexport { useChargeAction } from \"./modules/charges/hooks/charge-action.hook\";\nexport { useIaCredits } from \"./modules/ia-credits/hooks/ia-credits.hook\";\nexport type {\n IaCreditsSummary,\n IaCreditsSummaryData,\n IaCreditAddBatch,\n IaCreditOperation,\n} from \"./modules/ia-credits/types\";\nexport type {\n Subscription,\n SubscriptionItem,\n FindSubscriptionsParams,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n SubscriptionSchema,\n SubscriptionItemSchema,\n} from \"./modules/subscriptions/types/subscription.type\";\nexport {\n ADDON_IDS,\n AI_CREDIT_OPTIONS,\n AI_CREDIT_VALUES,\n} from \"./modules/subscriptions/constants/addons.constants\";\nexport type {\n AddonKindEnum,\n AiCreditOption,\n} from \"./modules/subscriptions/constants/addons.constants\";\nexport type {\n Plan,\n PlanItem,\n UiPlan,\n PlanFeature,\n PlanMainFeatures,\n PlanPricingByPeriod,\n PlanTooltips,\n} from \"./modules/plans/types/plan.type\";\nexport { PlanSchema, PlanItemSchema } from \"./modules/plans/types/plan.type\";\nexport {\n mapApiPlanToUiPlan,\n mapApiPlanToUiPlanForCurrency,\n} from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport type { PlanBillingPeriod } from \"./modules/plans/utils/map-api-plan-to-ui\";\nexport {\n usePlans,\n PLANS_QUERY_KEY,\n} from \"./modules/plans/hooks/list-plans.hook\";\nexport type { BillingPeriod } from \"./modules/subscriptions/types/billing-period.type\";\nexport type {\n CalculateSubscriptionRequest,\n CalculateSubscriptionResponse,\n UpdateSubscriptionPlanRequest,\n} from \"./modules/subscriptions/types/calculate-subscription.type\";\nexport {\n PixPendingDataSchema,\n SubscriptionPendingPixResponseSchema,\n isSubscriptionPendingPixResponse,\n} from \"./modules/subscriptions/types/pix-pending.type\";\nexport type {\n PixPendingData,\n SubscriptionPendingPixResponse,\n} from \"./modules/subscriptions/types/pix-pending.type\";\nexport type {\n Card as PaymentCard,\n CreateCardRequest,\n FindCardsParams,\n SetupIntent,\n} from \"./modules/cards/types\";\nexport {\n CardSchema as PaymentCardSchema,\n CreateCardRequestSchema,\n FindCardsParamsSchema,\n SetupIntentSchema,\n} from \"./modules/cards/types\";\nexport type {\n Charge,\n FindChargesParams,\n PayChargeInput,\n} from \"./modules/charges/types/charge.type\";\nexport {\n ChargeSchema,\n FindChargesParamsSchema,\n PayChargeInputSchema,\n} from \"./modules/charges/types/charge.type\";\nexport { buildPlanExtras } from \"./modules/subscriptions/utils/build-plan-extras\";\nexport { hasSubscriptionExpired } from \"./modules/subscriptions/utils/has-subscription-expired\";\nexport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"./modules/subscriptions/constants/subscription.constants\";\nexport {\n useCountPages,\n COUNT_PAGES_QUERY_KEY,\n} from \"./modules/pages/hooks/count-pages.hook\";\nexport { PAGES_QUERY_KEY } from \"./modules/pages/constants/query-keys.constants\";\nexport {\n getPriceFromCalculatedData,\n getOriginalPriceFromCalculatedData,\n periodicityToBillingPeriod,\n} from \"./modules/subscriptions/utils/periodicity\";\nexport { useBuyCreditsModal } from \"./store/useBuyCreditsModal\";\nexport { useCreditsDisabledModal } from \"./store/useCreditsDisabledModal\";\nexport { usePaidPlanRequiredModal } from \"./store/usePaidPlanRequiredModal\";\nexport { useHexaPromoModal } from \"./store/useHexaPromoModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as CreditsDisabledModal } from \"./components/modals/CreditsDisabledModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as HexaPromoModal } from \"./components/modals/HexaPromoModal\";\nexport { default as HexaPromoModalGate } from \"./components/modals/HexaPromoModalGate\";\nexport { default as AddCardModal } from \"./components/modals/cards/AddCardModal\";\nexport { DeleteCardModal } from \"./components/modals/cards/DeleteCardModal\";\nexport { CannotDeleteCardModal } from \"./components/modals/cards/CannotDeleteCardModal\";\nexport {\n CardFormFields,\n cardFormSchema,\n buildCardFormSchema,\n} from \"./components/modals/cards/CardFormFields\";\nexport type { CardFormData } from \"./components/modals/cards/CardFormFields\";\nexport { Skeleton } from \"./components/ui/feedback/Skeleton\";\nexport { PaymentInfoCard } from \"./components/ui/data-display/PaymentInfoCard\";\nexport { CardBrandIcon } from \"./components/ui/data-display/CardBrandIcons\";\nexport { CardItem } from \"./components/ui/data-display/CardItem\";\n\n// Providers\nexport { QueryProvider } from \"./providers/query.provider\";\n\n// Middleware\nexport { createAuthMiddleware } from \"./middlewares/create-auth-middleware\";\nexport { createMiddlewareChain } from \"./middlewares/chain\";\nexport { continueChain, stopChain } from \"./middlewares/types\";\nexport type {\n MiddlewareFunction,\n MiddlewareConfig,\n MiddlewareResult,\n} from \"./middlewares/types\";\n\n// Utils\nexport { cn } from \"./infra/utils/clsx\";\nexport { formatShortDate, formatDateTime, calendarDateSchema, toCalendarDate, daysBetween } from \"./infra/utils/date\";\nexport { buildQueryParams } from \"./infra/utils/params\";\nexport { parseSchema, parseResult } from \"./infra/utils/parser\";\nexport { withAction } from \"./utils/withAction\";\nexport { resolveSafeRedirect, sameHostOr } from \"./utils/redirect\";\nexport { COUNTRIES, flagUrl } from \"./utils/countries\";\nexport type { Country } from \"./utils/countries\";\n\n// Layout\nexport {\n MainLayout,\n MainLayoutContent,\n MainLayoutSpacer,\n MainLayoutMain,\n} from \"./components/layouts/MainLayout\";\nexport { NavBar } from \"./components/layouts/NavBar\";\nexport type { NavBarProps } from \"./components/layouts/NavBar\";\nexport { AppNavBar } from \"./components/layouts/AppNavBar\";\nexport type { AppNavBarProps } from \"./components/layouts/AppNavBar\";\nexport { AppMobileNavBar } from \"./components/layouts/AppMobileNavBar\";\nexport type { AppMobileNavBarProps } from \"./components/layouts/AppMobileNavBar\";\nexport { SideBarNavigation } from \"./components/layouts/SideBarNavigation\";\nexport { MdSideBarNavigation } from \"./components/layouts/MdSideBarNavigation\";\nexport { default as NotificationCard } from \"./components/widgets/notifications/NotificationCard\";\nexport type { NotificationCardProps } from \"./components/widgets/notifications/NotificationCard\";\nexport { NotificationsPopover } from \"./components/layouts/NotificationsPopover\";\nexport type { NotificationsPopoverProps } from \"./components/layouts/NotificationsPopover\";\nexport { NotificationPageContent } from \"./components/pages/notifications/Notifications\";\nexport { NotFoundPage } from \"./components/pages/NotFoundPage\";\nexport { UsersSelectorPopover } from \"./components/layouts/UsersSelectorPopover\";\nexport type { UsersSelectorPopoverProps } from \"./components/layouts/UsersSelectorPopover\";\nexport { ProfilePopover } from \"./components/layouts/ProfilePopover\";\nexport type {\n ProfilePopoverProps,\n ProfileMenuItem,\n} from \"./components/layouts/ProfilePopover\";\nexport { default as WhitelabelCodes } from \"./components/layouts/WhitelabelCodes\";\nexport { NavBarItem } from \"./components/layouts/NavBarItem\";\nexport type { NavBarItemProps } from \"./components/layouts/NavBarItem\";\n\n// Navigation\nexport { AppNavigation } from \"./components/navigation/AppNavigation\";\nexport { CancelledSubscriptionBanner } from \"./components/navigation/CancelledSubscriptionBanner\";\nexport { SubscriptionBanner } from \"./components/navigation/SubscriptionBanner\";\nexport { OverdueInvoiceBanner } from \"./components/navigation/OverdueInvoiceBanner\";\nexport { UpcomingInvoiceBanner } from \"./components/navigation/UpcomingInvoiceBanner\";\nexport { TrialBanner } from \"./components/navigation/TrialBanner\";\nexport type { NavItemConfig } from \"./components/navigation/subcomponents/NavItems\";\nexport { useMobileNavbarSheet } from \"./store/useMobileNavbarSheet\";\n\n// Auth Query Key Utilities\nexport {\n useAuthQueryKey,\n useWlQueryKey,\n useWlId,\n} from \"./hooks/useAuthQueryKey\";\n\n// Hooks\nexport { default as useCopyToClipboard } from \"./hooks/copy-to-clipboard.hook\";\n\n// UI - Buttons\nexport { Button, buttonVariants } from \"./components/ui/buttons/Button\";\nexport { CopyButton } from \"./components/ui/buttons/CopyButton\";\nexport { default as CancelButton } from \"./components/ui/buttons/CancelButton\";\n\n// UI - Data Display\nexport {\n Accordion,\n AccordionItem,\n AccordionTrigger,\n AccordionContent,\n} from \"./components/ui/data-display/Accordion\";\nexport { Badge, badgeVariants } from \"./components/ui/data-display/Badge\";\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n} from \"./components/ui/data-display/Card\";\nexport {\n Pagination,\n PaginationContent,\n PaginationLink,\n PaginationItem,\n PaginationPrevious,\n PaginationNext,\n PaginationEllipsis,\n} from \"./components/ui/data-display/Pagination\";\nexport { ScrollArea, ScrollBar } from \"./components/ui/data-display/ScrollArea\";\nexport { Separator } from \"./components/ui/data-display/Separator\";\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n} from \"./components/ui/data-display/Table\";\nexport {\n Tabs,\n TabsList,\n TabsTrigger,\n TabsContent,\n} from \"./components/ui/data-display/Tabs\";\nexport { UserAvatar } from \"./components/ui/data-display/UserAvatar\";\nexport type { UserAvatarProps } from \"./components/ui/data-display/UserAvatar\";\n\n// UI - Feedback\nexport { default as CircularProgress } from \"./components/ui/feedback/CircularProgress\";\nexport { default as DefaultCircularProgress } from \"./components/ui/feedback/DefaultCircularProgress\";\nexport { Progress } from \"./components/ui/feedback/Progress\";\nexport { LoadingOverlay } from \"./components/ui/feedback/LoadingOverlay\";\nexport { useBrandLoadingIcon } from \"./hooks/useBrandLoadingIcon\";\nexport {\n Toast,\n toastVariants,\n toastIconContainerVariants,\n} from \"./components/ui/feedback/Toast\";\nexport type { ToastProps } from \"./components/ui/feedback/Toast\";\n\n// UI - Form\nexport { Calendar, CalendarDayButton } from \"./components/ui/form/Calendar\";\nexport { Checkbox } from \"./components/ui/form/Checkbox\";\nexport { DatePicker } from \"./components/ui/form/DatePicker\";\nexport { DateRangePicker } from \"./components/ui/form/DateRangePicker\";\nexport { Input } from \"./components/ui/form/Input\";\nexport {\n InputOTP,\n InputOTPGroup,\n InputOTPSlot,\n InputOTPSeparator,\n} from \"./components/ui/form/InputOtp\";\nexport { RadioGroup, RadioGroupItem } from \"./components/ui/form/RadioGroup\";\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n} from \"./components/ui/form/Select\";\nexport { Switch } from \"./components/ui/form/Switch\";\nexport { Textarea } from \"./components/ui/form/Textarea\";\n\n// UI - Overlay\nexport {\n Command,\n CommandDialog,\n CommandInput,\n CommandList,\n CommandEmpty,\n CommandGroup,\n CommandItem,\n CommandShortcut,\n CommandSeparator,\n} from \"./components/ui/overlay/Command\";\nexport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n} from \"./components/ui/overlay/Dialog\";\nexport {\n Popover,\n PopoverTrigger,\n PopoverContent,\n PopoverAnchor,\n} from \"./components/ui/overlay/Popover\";\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n} from \"./components/ui/overlay/Sheet\";\nexport {\n Tooltip,\n TooltipTrigger,\n TooltipContent,\n TooltipProvider,\n} from \"./components/ui/overlay/Tooltip\";\n\n// Embeds\nexport { FrillEmbed } from \"./components/embeds/FrillEmbed\";\nexport {\n CrispEmbed,\n openCrispHelpdesk,\n hideCrisp,\n showCrisp,\n updateCrispUser,\n} from \"./components/embeds/CrispEmbed\";\nexport { EmbedWidgets } from \"./components/embeds/EmbedWidgets\";\nexport { ClarityEmbed } from \"./components/embeds/ClarityEmbed\";\n\n// Store\nexport { useMdSidebarStore } from \"./store/useMdSidebarStore\";\nexport { useDesktopSidebarStore } from \"./store/useDesktopSidebarStore\";\nexport { useModalManager } from \"./store/useModalManager\";\nexport type { ModalData } from \"./store/useModalManager\";\n\n// Enums\nexport { AccountSectionType } from \"./enums/AccountSectionType\";\n\n// Hooks\nexport { default as usePasswordVisibility } from \"./hooks/usePasswordVisibility\";\nexport { default as useCountdownTimer } from \"./hooks/useCountdownTimer\";\nexport { default as useIsMobile } from \"./hooks/useIsMobile\";\nexport { useDebounce } from \"./hooks/useDebounce\";\nexport { useDebouncedEffect } from \"./hooks/useDebouncedEffect\";\nexport { useDebounceState } from \"./hooks/useDebounceState\";\n\n// Utils\nexport {\n formatPhone,\n formatTimer,\n formatFullName,\n formatCPF,\n formatCNPJ,\n formatCardNumber,\n} from \"./utils/format/masks\";\nexport {\n formatCurrency,\n formatCurrencyNumber,\n parseCurrencyToNumber,\n getCurrencyForGateway,\n} from \"./utils/format/currency\";\nexport type { CurrencyCode } from \"./utils/format/currency\";\nexport { isValidCPF, isValidCNPJ, isValidTaxId } from \"./utils/validators/common\";\nexport { BR_STATE_OPTIONS } from \"./utils/constants/br-states\";\nexport type { TimezoneOption } from \"./modules/accounts/services/timezone.service\";\nexport {\n buildLocaleOptions,\n LANGUAGE_OPTIONS as LOCALE_LANGUAGE_OPTIONS,\n} from \"./utils/intl/locales\";\nexport type { LocaleOption } from \"./utils/intl/locales\";\nexport { copyToClipboard, readFromClipboard } from \"./utils/browser/clipboard\";\n\n// UI - Form (new widgets)\nexport { FormField } from \"./components/ui/form/FormField\";\nexport { SelectField } from \"./components/ui/form/SelectField\";\nexport { ComboboxField } from \"./components/ui/form/ComboboxField\";\nexport type { ComboboxOption } from \"./components/ui/form/ComboboxField\";\nexport { default as PhoneInput } from \"./components/ui/form/PhoneInput\";\nexport { default as SwitchOptionFieldWithIcon } from \"./components/ui/form/SwitchOptionFieldWithIcon\";\nexport { TextAreaField } from \"./components/ui/form/TextAreaField\";\n\n// Account Module - Hooks\nexport {\n useCurrentAccount,\n ACCOUNT_QUERY_KEY,\n} from \"./modules/accounts/hooks/current-account.hook\";\nexport { useCurrencyFormatter } from \"./modules/accounts/hooks/use-currency-formatter.hook\";\nexport {\n useUpdateAccount,\n useUpdateAccountUser,\n useUpdateAccountUserById,\n useDeleteAccountUser,\n useDeleteAccount,\n ACCOUNT_USERS_QUERY_KEY,\n} from \"./modules/accounts/hooks/useAccountManagement\";\nexport { useViaCep } from \"./modules/accounts/hooks/useViaCep\";\nexport { useAccountToken } from \"./modules/accounts/hooks/use-account-token.hook\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateAccountUserRequest,\n ChangePasswordRequest,\n DeleteAccountActionResult,\n DeleteUserActionResult,\n UpdateAccountActionResult,\n UpdateUserActionResult,\n TwoFactorGenerateResult,\n TwoFactorActionResult,\n ContactResetResult,\n} from \"./modules/accounts/types\";\n\nexport { default as AccountModals } from \"./components/account/AccountModals\";\nexport { useAccountModals } from \"./store/useAccountModals\";\nexport type { AccountModalsConfig } from \"./store/useAccountModals\";\n\nexport { ModalManager } from \"./components/modals/ModalManager\";\nexport { Modals } from \"./components/modals/Modals\";\n\nexport { default as TwoFactorAuthModal } from \"./components/account/TwoFactorAuthModal\";\nexport { default as DisableTwoFactorAuthModal } from \"./components/account/DisableTwoFactorAuthModal\";\nexport { default as ConfirmGlobalPreferencesModal } from \"./components/account/ConfirmGlobalPreferencesModal\";\nexport { MyProfileSection } from \"./components/account/sections/MyProfileSection\";\nexport { PreferencesSection } from \"./components/account/sections/PreferencesSection\";\nexport { SecuritySection } from \"./components/account/sections/SecuritySection\";\nexport { ChangePasswordSection } from \"./components/account/sections/ChangePasswordSection\";\nexport { ChangeEmailModal } from \"./components/account/sections/ChangeEmailModal\";\nexport { ChangePhoneModal } from \"./components/account/sections/ChangePhoneModal\";\n\n// Account Constants\nexport {\n GENDER_OPTIONS,\n CURRENCY_OPTIONS,\n TIME_FORMAT_OPTIONS,\n NOTIFICATION_TYPES,\n LANGUAGE_OPTIONS,\n} from \"./components/account/constants\";\n\n// Image Upload\nexport {\n ImageUpload,\n ImageCropModal,\n ImageTooSmallModal,\n} from \"./components/widgets/ImageUpload\";\nexport {\n useImageUpload,\n type ImageTooSmallError,\n} from \"./modules/images/hooks/use-image-upload.hook\";\nexport {\n ACCEPTED_IMAGE_FORMATS,\n ACCEPTED_IMAGE_FORMATS_STRING,\n MAX_FILE_SIZE_MB,\n} from \"./modules/images/constants/image.constants\";\nexport type {\n ImageConfig,\n CropArea,\n ProcessedImage,\n CompressImageOptions,\n} from \"./modules/images/types/image.type\";\nexport { compressImage } from \"./modules/images/utils/compress-image\";\nexport { cropImageToCanvas } from \"./modules/images/utils/crop-image\";\nexport { base64ToFile, fileToBase64 } from \"./modules/images/utils/base64\";\nexport {\n validateImage,\n validateImageFormat,\n validateImageSize,\n getImageDimensions,\n} from \"./modules/images/utils/validate-image\";\n"],"mappings":"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","names":["default","LANGUAGE_OPTIONS"]}
@@ -5,7 +5,7 @@ function createListIaCreditsHandler() {
5
5
  return async function GET(_req, { params }) {
6
6
  return safeRouteHandler(async () => {
7
7
  const { id } = await params;
8
- return iaCreditsService.listOperations(id);
8
+ return iaCreditsService.getSummaryData(id);
9
9
  });
10
10
  };
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/ia-credits/handlers/list-ia-credits.handler.ts"],"sourcesContent":["import 'server-only';\n\nimport type { NextRequest } from 'next/server';\nimport { safeRouteHandler } from '../../../infra/route/safe-route-handler';\nimport { iaCreditsService } from '../services/ia-credits.service';\n\nexport function createListIaCreditsHandler() {\n return async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {\n return safeRouteHandler(async () => {\n const { id } = await params;\n return iaCreditsService.listOperations(id);\n });\n };\n}\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AAE1B,SAAS,6BAA6B;AAC3C,SAAO,eAAe,IAAI,MAAmB,EAAE,OAAO,GAAwC;AAC5F,WAAO,iBAAiB,YAAY;AAClC,YAAM,EAAE,GAAG,IAAI,MAAM;AACrB,aAAO,iBAAiB,eAAe,EAAE;AAAA,IAC3C,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/ia-credits/handlers/list-ia-credits.handler.ts"],"sourcesContent":["import 'server-only';\n\nimport type { NextRequest } from 'next/server';\nimport { safeRouteHandler } from '../../../infra/route/safe-route-handler';\nimport { iaCreditsService } from '../services/ia-credits.service';\n\nexport function createListIaCreditsHandler() {\n return async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {\n return safeRouteHandler(async () => {\n const { id } = await params;\n return iaCreditsService.getSummaryData(id);\n });\n };\n}\n"],"mappings":"AAAA,OAAO;AAGP,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AAE1B,SAAS,6BAA6B;AAC3C,SAAO,eAAe,IAAI,MAAmB,EAAE,OAAO,GAAwC;AAC5F,WAAO,iBAAiB,YAAY;AAClC,YAAM,EAAE,GAAG,IAAI,MAAM;AACrB,aAAO,iBAAiB,eAAe,EAAE;AAAA,IAC3C,CAAC;AAAA,EACH;AACF;","names":[]}
@@ -4,46 +4,40 @@ import { useQuery } from "@tanstack/react-query";
4
4
  import { apiFetch } from "../../../infra/http/api-fetch";
5
5
  import { useActiveSubscription } from "../../subscriptions/hooks/find-active-subscription.hook";
6
6
  import { useAuthQueryKey } from "../../../hooks/useAuthQueryKey";
7
- function calculateSummary(operations) {
8
- const today = /* @__PURE__ */ new Date();
9
- const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
10
- const adds = operations.filter((op) => op.operation === "add");
11
- const subtracts = operations.filter((op) => op.operation === "subtract");
7
+ const MS_PER_DAY = 1e3 * 60 * 60 * 24;
8
+ const EMPTY_SUMMARY = {
9
+ totalCredits: 0,
10
+ usedCredits: 0,
11
+ availableCredits: 0,
12
+ nextExpiringCredits: null,
13
+ nextExpirationInDays: null
14
+ };
15
+ function startOfDay(date) {
16
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
17
+ }
18
+ function calculateSummary(data) {
19
+ if (!data) return EMPTY_SUMMARY;
20
+ const today = startOfDay(/* @__PURE__ */ new Date());
12
21
  let totalCredits = 0;
13
22
  let usedCredits = 0;
14
23
  let nextExpirationInDays = null;
15
24
  let nextExpiringCredits = null;
16
- for (const add of adds) {
17
- const expirationRaw = add.expiration_time;
18
- if (!expirationRaw) continue;
19
- const expiration = new Date(expirationRaw);
20
- const expirationDate = new Date(
21
- expiration.getFullYear(),
22
- expiration.getMonth(),
23
- expiration.getDate()
24
- );
25
- const expiredByDate = expirationDate.getTime() < todayDate.getTime();
26
- const hasExpired = add.has_expired || expiredByDate;
27
- if (hasExpired) continue;
28
- const addedCredits = add.operation_value;
29
- const consumedForAdd = subtracts.filter((sub) => String(sub.consumed_from_add_id) === String(add.id)).reduce((sum, sub) => sum + sub.operation_value, 0);
30
- const remainingForAdd = Math.max(0, addedCredits - consumedForAdd);
31
- totalCredits += addedCredits;
32
- usedCredits += consumedForAdd;
33
- const diffMs = expirationDate.getTime() - todayDate.getTime();
34
- const days = Math.max(0, Math.ceil(diffMs / (1e3 * 60 * 60 * 24)));
35
- if (remainingForAdd > 0) {
36
- if (nextExpirationInDays === null || days < nextExpirationInDays) {
37
- nextExpirationInDays = days;
38
- nextExpiringCredits = remainingForAdd;
39
- }
25
+ for (const batch of data.addBatches) {
26
+ if (batch.has_expired) continue;
27
+ totalCredits += batch.added_credits;
28
+ usedCredits += batch.consumed_credits;
29
+ if (batch.remaining_credits <= 0 || !batch.expiration_time) continue;
30
+ const expirationDate = startOfDay(new Date(batch.expiration_time));
31
+ const days = Math.max(0, Math.ceil((expirationDate.getTime() - today.getTime()) / MS_PER_DAY));
32
+ if (nextExpirationInDays === null || days < nextExpirationInDays) {
33
+ nextExpirationInDays = days;
34
+ nextExpiringCredits = batch.remaining_credits;
40
35
  }
41
36
  }
42
- const availableCredits = Math.max(0, totalCredits - usedCredits);
43
37
  return {
44
38
  totalCredits,
45
39
  usedCredits,
46
- availableCredits,
40
+ availableCredits: Math.max(0, data.availableCredits),
47
41
  nextExpiringCredits,
48
42
  nextExpirationInDays
49
43
  };
@@ -62,11 +56,10 @@ function useIaCredits(options = {}) {
62
56
  enabled: subscriptionId != null,
63
57
  refetchInterval: options.refetchInterval ?? false
64
58
  });
65
- const operations = query.data?.data ?? [];
66
- const summary = useMemo(() => calculateSummary(operations), [operations]);
59
+ const summaryData = query.data?.data ?? null;
60
+ const summary = useMemo(() => calculateSummary(summaryData), [summaryData]);
67
61
  return {
68
62
  subscription,
69
- operations,
70
63
  summary,
71
64
  isLoading: isSubscriptionLoading || query.isPending,
72
65
  isSubscriptionLoading,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/ia-credits/hooks/ia-credits.hook.ts"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { apiFetch } from '../../../infra/http/api-fetch';\nimport type { PaginatedSuccessResult } from '../../../infra/api/types';\nimport type { IaCreditOperation, IaCreditsSummary } from '../types';\nimport { useActiveSubscription } from '../../subscriptions/hooks/find-active-subscription.hook';\nimport { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';\n\nfunction calculateSummary(operations: IaCreditOperation[]): IaCreditsSummary {\n const today = new Date();\n const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());\n\n const adds = operations.filter((op) => op.operation === 'add');\n const subtracts = operations.filter((op) => op.operation === 'subtract');\n\n let totalCredits = 0;\n let usedCredits = 0;\n let nextExpirationInDays: number | null = null;\n let nextExpiringCredits: number | null = null;\n\n for (const add of adds) {\n const expirationRaw = add.expiration_time;\n if (!expirationRaw) continue;\n\n const expiration = new Date(expirationRaw);\n const expirationDate = new Date(\n expiration.getFullYear(),\n expiration.getMonth(),\n expiration.getDate()\n );\n\n const expiredByDate = expirationDate.getTime() < todayDate.getTime();\n const hasExpired = add.has_expired || expiredByDate;\n\n if (hasExpired) continue;\n\n const addedCredits = add.operation_value;\n\n const consumedForAdd = subtracts\n .filter((sub) => String(sub.consumed_from_add_id) === String(add.id))\n .reduce((sum, sub) => sum + sub.operation_value, 0);\n\n const remainingForAdd = Math.max(0, addedCredits - consumedForAdd);\n\n totalCredits += addedCredits;\n usedCredits += consumedForAdd;\n\n const diffMs = expirationDate.getTime() - todayDate.getTime();\n const days = Math.max(0, Math.ceil(diffMs / (1000 * 60 * 60 * 24)));\n\n if (remainingForAdd > 0) {\n if (nextExpirationInDays === null || days < nextExpirationInDays) {\n nextExpirationInDays = days;\n nextExpiringCredits = remainingForAdd;\n }\n }\n }\n\n const availableCredits = Math.max(0, totalCredits - usedCredits);\n\n return {\n totalCredits,\n usedCredits,\n availableCredits,\n nextExpiringCredits,\n nextExpirationInDays,\n };\n}\n\nexport interface UseIaCreditsOptions {\n refetchInterval?: number | false;\n}\n\nexport function useIaCredits(options: UseIaCreditsOptions = {}) {\n const { data: subscriptionData, isPending: isSubscriptionLoading } = useActiveSubscription();\n const subscription = subscriptionData?.data?.[0] ?? null;\n const subscriptionId = subscription?.id;\n const queryKey = useAuthQueryKey(['ia-credits', subscriptionId]);\n\n const query = useQuery({\n queryKey,\n queryFn: ({ signal }) =>\n apiFetch<PaginatedSuccessResult<IaCreditOperation>>(\n `/api/subscriptions/${subscriptionId}/ia-credits`,\n { signal }\n ),\n enabled: subscriptionId != null,\n refetchInterval: options.refetchInterval ?? false,\n });\n\n const operations = query.data?.data ?? [];\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n const summary = useMemo(() => calculateSummary(operations), [operations]);\n\n return {\n subscription,\n operations,\n summary,\n isLoading: isSubscriptionLoading || query.isPending,\n isSubscriptionLoading,\n isCreditsLoading: query.isPending,\n isError: query.isError,\n error: query.error,\n };\n}\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAGzB,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAEhC,SAAS,iBAAiB,YAAmD;AAC3E,QAAM,QAAQ,oBAAI,KAAK;AACvB,QAAM,YAAY,IAAI,KAAK,MAAM,YAAY,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC;AAEjF,QAAM,OAAO,WAAW,OAAO,CAAC,OAAO,GAAG,cAAc,KAAK;AAC7D,QAAM,YAAY,WAAW,OAAO,CAAC,OAAO,GAAG,cAAc,UAAU;AAEvE,MAAI,eAAe;AACnB,MAAI,cAAc;AAClB,MAAI,uBAAsC;AAC1C,MAAI,sBAAqC;AAEzC,aAAW,OAAO,MAAM;AACtB,UAAM,gBAAgB,IAAI;AAC1B,QAAI,CAAC,cAAe;AAEpB,UAAM,aAAa,IAAI,KAAK,aAAa;AACzC,UAAM,iBAAiB,IAAI;AAAA,MACzB,WAAW,YAAY;AAAA,MACvB,WAAW,SAAS;AAAA,MACpB,WAAW,QAAQ;AAAA,IACrB;AAEA,UAAM,gBAAgB,eAAe,QAAQ,IAAI,UAAU,QAAQ;AACnE,UAAM,aAAa,IAAI,eAAe;AAEtC,QAAI,WAAY;AAEhB,UAAM,eAAe,IAAI;AAEzB,UAAM,iBAAiB,UACpB,OAAO,CAAC,QAAQ,OAAO,IAAI,oBAAoB,MAAM,OAAO,IAAI,EAAE,CAAC,EACnE,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,iBAAiB,CAAC;AAEpD,UAAM,kBAAkB,KAAK,IAAI,GAAG,eAAe,cAAc;AAEjE,oBAAgB;AAChB,mBAAe;AAEf,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,QAAQ;AAC5D,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,UAAU,MAAO,KAAK,KAAK,GAAG,CAAC;AAElE,QAAI,kBAAkB,GAAG;AACvB,UAAI,yBAAyB,QAAQ,OAAO,sBAAsB;AAChE,+BAAuB;AACvB,8BAAsB;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,KAAK,IAAI,GAAG,eAAe,WAAW;AAE/D,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,aAAa,UAA+B,CAAC,GAAG;AAC9D,QAAM,EAAE,MAAM,kBAAkB,WAAW,sBAAsB,IAAI,sBAAsB;AAC3F,QAAM,eAAe,kBAAkB,OAAO,CAAC,KAAK;AACpD,QAAM,iBAAiB,cAAc;AACrC,QAAM,WAAW,gBAAgB,CAAC,cAAc,cAAc,CAAC;AAE/D,QAAM,QAAQ,SAAS;AAAA,IACrB;AAAA,IACA,SAAS,CAAC,EAAE,OAAO,MACjB;AAAA,MACE,sBAAsB,cAAc;AAAA,MACpC,EAAE,OAAO;AAAA,IACX;AAAA,IACF,SAAS,kBAAkB;AAAA,IAC3B,iBAAiB,QAAQ,mBAAmB;AAAA,EAC9C,CAAC;AAED,QAAM,aAAa,MAAM,MAAM,QAAQ,CAAC;AAGxC,QAAM,UAAU,QAAQ,MAAM,iBAAiB,UAAU,GAAG,CAAC,UAAU,CAAC;AAExE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,yBAAyB,MAAM;AAAA,IAC1C;AAAA,IACA,kBAAkB,MAAM;AAAA,IACxB,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,EACf;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/ia-credits/hooks/ia-credits.hook.ts"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { apiFetch } from '../../../infra/http/api-fetch';\nimport type { SuccessResult } from '../../../infra/api/types';\nimport type { IaCreditsSummary, IaCreditsSummaryData } from '../types';\nimport { useActiveSubscription } from '../../subscriptions/hooks/find-active-subscription.hook';\nimport { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';\n\nconst MS_PER_DAY = 1000 * 60 * 60 * 24;\n\nconst EMPTY_SUMMARY: IaCreditsSummary = {\n totalCredits: 0,\n usedCredits: 0,\n availableCredits: 0,\n nextExpiringCredits: null,\n nextExpirationInDays: null,\n};\n\nfunction startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate());\n}\n\nfunction calculateSummary(data: IaCreditsSummaryData | null): IaCreditsSummary {\n if (!data) return EMPTY_SUMMARY;\n\n const today = startOfDay(new Date());\n\n let totalCredits = 0;\n let usedCredits = 0;\n let nextExpirationInDays: number | null = null;\n let nextExpiringCredits: number | null = null;\n\n for (const batch of data.addBatches) {\n if (batch.has_expired) continue;\n\n totalCredits += batch.added_credits;\n usedCredits += batch.consumed_credits;\n\n if (batch.remaining_credits <= 0 || !batch.expiration_time) continue;\n\n const expirationDate = startOfDay(new Date(batch.expiration_time));\n const days = Math.max(0, Math.ceil((expirationDate.getTime() - today.getTime()) / MS_PER_DAY));\n\n if (nextExpirationInDays === null || days < nextExpirationInDays) {\n nextExpirationInDays = days;\n nextExpiringCredits = batch.remaining_credits;\n }\n }\n\n return {\n totalCredits,\n usedCredits,\n availableCredits: Math.max(0, data.availableCredits),\n nextExpiringCredits,\n nextExpirationInDays,\n };\n}\n\nexport interface UseIaCreditsOptions {\n refetchInterval?: number | false;\n}\n\nexport function useIaCredits(options: UseIaCreditsOptions = {}) {\n const { data: subscriptionData, isPending: isSubscriptionLoading } = useActiveSubscription();\n const subscription = subscriptionData?.data?.[0] ?? null;\n const subscriptionId = subscription?.id;\n const queryKey = useAuthQueryKey(['ia-credits', subscriptionId]);\n\n const query = useQuery({\n queryKey,\n queryFn: ({ signal }) =>\n apiFetch<SuccessResult<IaCreditsSummaryData>>(\n `/api/subscriptions/${subscriptionId}/ia-credits`,\n { signal }\n ),\n enabled: subscriptionId != null,\n refetchInterval: options.refetchInterval ?? false,\n });\n\n const summaryData = query.data?.data ?? null;\n\n const summary = useMemo(() => calculateSummary(summaryData), [summaryData]);\n\n return {\n subscription,\n summary,\n isLoading: isSubscriptionLoading || query.isPending,\n isSubscriptionLoading,\n isCreditsLoading: query.isPending,\n isError: query.isError,\n error: query.error,\n };\n}\n"],"mappings":";AAEA,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AAGzB,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAEhC,MAAM,aAAa,MAAO,KAAK,KAAK;AAEpC,MAAM,gBAAkC;AAAA,EACtC,cAAc;AAAA,EACd,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,qBAAqB;AAAA,EACrB,sBAAsB;AACxB;AAEA,SAAS,WAAW,MAAkB;AACpC,SAAO,IAAI,KAAK,KAAK,YAAY,GAAG,KAAK,SAAS,GAAG,KAAK,QAAQ,CAAC;AACrE;AAEA,SAAS,iBAAiB,MAAqD;AAC7E,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,QAAQ,WAAW,oBAAI,KAAK,CAAC;AAEnC,MAAI,eAAe;AACnB,MAAI,cAAc;AAClB,MAAI,uBAAsC;AAC1C,MAAI,sBAAqC;AAEzC,aAAW,SAAS,KAAK,YAAY;AACnC,QAAI,MAAM,YAAa;AAEvB,oBAAgB,MAAM;AACtB,mBAAe,MAAM;AAErB,QAAI,MAAM,qBAAqB,KAAK,CAAC,MAAM,gBAAiB;AAE5D,UAAM,iBAAiB,WAAW,IAAI,KAAK,MAAM,eAAe,CAAC;AACjE,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,eAAe,QAAQ,IAAI,MAAM,QAAQ,KAAK,UAAU,CAAC;AAE7F,QAAI,yBAAyB,QAAQ,OAAO,sBAAsB;AAChE,6BAAuB;AACvB,4BAAsB,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,kBAAkB,KAAK,IAAI,GAAG,KAAK,gBAAgB;AAAA,IACnD;AAAA,IACA;AAAA,EACF;AACF;AAMO,SAAS,aAAa,UAA+B,CAAC,GAAG;AAC9D,QAAM,EAAE,MAAM,kBAAkB,WAAW,sBAAsB,IAAI,sBAAsB;AAC3F,QAAM,eAAe,kBAAkB,OAAO,CAAC,KAAK;AACpD,QAAM,iBAAiB,cAAc;AACrC,QAAM,WAAW,gBAAgB,CAAC,cAAc,cAAc,CAAC;AAE/D,QAAM,QAAQ,SAAS;AAAA,IACrB;AAAA,IACA,SAAS,CAAC,EAAE,OAAO,MACjB;AAAA,MACE,sBAAsB,cAAc;AAAA,MACpC,EAAE,OAAO;AAAA,IACX;AAAA,IACF,SAAS,kBAAkB;AAAA,IAC3B,iBAAiB,QAAQ,mBAAmB;AAAA,EAC9C,CAAC;AAED,QAAM,cAAc,MAAM,MAAM,QAAQ;AAExC,QAAM,UAAU,QAAQ,MAAM,iBAAiB,WAAW,GAAG,CAAC,WAAW,CAAC;AAE1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW,yBAAyB,MAAM;AAAA,IAC1C;AAAA,IACA,kBAAkB,MAAM;AAAA,IACxB,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,EACf;AACF;","names":[]}
@@ -2,26 +2,48 @@ import "server-only";
2
2
  import { api } from "../../../infra/api/client";
3
3
  import { ApiError } from "../../../infra/api/types";
4
4
  import { getUserContext } from "../../auth/utils/get-user-context";
5
- import { IaCreditOperationSchema } from "../types";
5
+ import {
6
+ IaCreditAddBatchSchema
7
+ } from "../types";
6
8
  class IaCreditsService {
7
- async listOperations(subscriptionId) {
9
+ async getSummaryData(subscriptionId) {
8
10
  const { id_account } = await getUserContext();
9
- const endpoint = `/accounts/${id_account}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=20&sort=id:DESC`;
11
+ const [availableCredits, addBatches] = await Promise.all([
12
+ this.fetchCurrentBalance(id_account, subscriptionId),
13
+ this.fetchAddBatches(id_account, subscriptionId)
14
+ ]);
15
+ return { success: true, data: { availableCredits, addBatches } };
16
+ }
17
+ // Saldo atual = balance_after_operation da última operação do extrato
18
+ // (sort id:DESC, limit=1). Já é o saldo do usuário, não precisa recalcular.
19
+ async fetchCurrentBalance(idAccount, subscriptionId) {
20
+ const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=1&sort=id:DESC`;
21
+ const response = await api.apps.get(endpoint);
22
+ if (response.status === 0) {
23
+ throw new ApiError(
24
+ response.message || "Erro ao consultar saldo de cr\xE9ditos de IA",
25
+ "GET_IA_CREDITS_BALANCE_FAILED",
26
+ 400
27
+ );
28
+ }
29
+ const balance = (response.data ?? [])[0]?.balance_after_operation;
30
+ return balance == null ? 0 : Number(balance);
31
+ }
32
+ // Lotes de adição com added/consumed/remaining já agregados pelo backend.
33
+ // sort id:DESC garante que os lotes mais recentes (não expirados) entram
34
+ // primeiro no limite; lotes expirados são filtrados no hook.
35
+ async fetchAddBatches(idAccount, subscriptionId) {
36
+ const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list/add?page=1&limit=100&sort=id:DESC`;
10
37
  const response = await api.apps.get(endpoint);
11
38
  if (response.status === 0) {
12
39
  throw new ApiError(
13
- response.message || "Erro ao listar cr\xE9ditos de IA",
14
- "LIST_IA_CREDITS_FAILED",
40
+ response.message || "Erro ao listar lotes de cr\xE9ditos de IA",
41
+ "LIST_IA_CREDITS_ADDS_FAILED",
15
42
  400
16
43
  );
17
44
  }
18
45
  const raw = response.data ?? [];
19
- const data = raw.map((item) => IaCreditOperationSchema.parse(item));
20
- return {
21
- data,
22
- total: response.total ?? data.length,
23
- success: true
24
- };
46
+ return raw.map((item) => IaCreditAddBatchSchema.parse(item));
25
47
  }
26
48
  }
27
49
  const iaCreditsService = new IaCreditsService();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/ia-credits/services/ia-credits.service.ts"],"sourcesContent":["import 'server-only';\r\n\r\nimport { api } from '../../../infra/api/client';\r\nimport { ApiError, ApiPaginatedActionResult, PaginatedSuccessResult } from '../../../infra/api/types';\r\nimport { getUserContext } from '../../auth/utils/get-user-context';\r\nimport { IaCreditOperation, IaCreditOperationSchema } from '../types';\r\n\r\nclass IaCreditsService {\r\n async listOperations(\r\n subscriptionId: number | string\r\n ): Promise<PaginatedSuccessResult<IaCreditOperation>> {\r\n const { id_account } = await getUserContext();\r\n\r\n const endpoint = `/accounts/${id_account}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=20&sort=id:DESC`;\r\n\r\n const response = await api.apps.get<ApiPaginatedActionResult<IaCreditOperation>>(endpoint);\r\n\r\n if (response.status === 0) {\r\n throw new ApiError(\r\n response.message || 'Erro ao listar créditos de IA',\r\n 'LIST_IA_CREDITS_FAILED',\r\n 400\r\n );\r\n }\r\n\r\n const raw = response.data ?? [];\r\n const data = raw.map((item) => IaCreditOperationSchema.parse(item));\r\n\r\n return {\r\n data,\r\n total: response.total ?? data.length,\r\n success: true,\r\n };\r\n }\r\n}\r\n\r\nexport const iaCreditsService = new IaCreditsService();\r\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,WAAW;AACpB,SAAS,gBAAkE;AAC3E,SAAS,sBAAsB;AAC/B,SAA4B,+BAA+B;AAE3D,MAAM,iBAAiB;AAAA,EACrB,MAAM,eACJ,gBACoD;AACpD,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,WAAW,aAAa,UAAU,kBAAkB,cAAc;AAExE,UAAM,WAAW,MAAM,IAAI,KAAK,IAAiD,QAAQ;AAEzF,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,SAAS,QAAQ,CAAC;AAC9B,UAAM,OAAO,IAAI,IAAI,CAAC,SAAS,wBAAwB,MAAM,IAAI,CAAC;AAElE,WAAO;AAAA,MACL;AAAA,MACA,OAAO,SAAS,SAAS,KAAK;AAAA,MAC9B,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAEO,MAAM,mBAAmB,IAAI,iBAAiB;","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/ia-credits/services/ia-credits.service.ts"],"sourcesContent":["import 'server-only';\n\nimport { api } from '../../../infra/api/client';\nimport { ApiError, ApiPaginatedActionResult, SuccessResult } from '../../../infra/api/types';\nimport { getUserContext } from '../../auth/utils/get-user-context';\nimport {\n IaCreditAddBatch,\n IaCreditAddBatchSchema,\n IaCreditOperation,\n IaCreditsSummaryData,\n} from '../types';\n\nclass IaCreditsService {\n async getSummaryData(\n subscriptionId: number | string\n ): Promise<SuccessResult<IaCreditsSummaryData>> {\n const { id_account } = await getUserContext();\n\n const [availableCredits, addBatches] = await Promise.all([\n this.fetchCurrentBalance(id_account, subscriptionId),\n this.fetchAddBatches(id_account, subscriptionId),\n ]);\n\n return { success: true, data: { availableCredits, addBatches } };\n }\n\n // Saldo atual = balance_after_operation da última operação do extrato\n // (sort id:DESC, limit=1). Já é o saldo do usuário, não precisa recalcular.\n private async fetchCurrentBalance(\n idAccount: number | string,\n subscriptionId: number | string\n ): Promise<number> {\n const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=1&sort=id:DESC`;\n\n const response = await api.apps.get<ApiPaginatedActionResult<IaCreditOperation>>(endpoint);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao consultar saldo de créditos de IA',\n 'GET_IA_CREDITS_BALANCE_FAILED',\n 400\n );\n }\n\n const balance = (response.data ?? [])[0]?.balance_after_operation;\n return balance == null ? 0 : Number(balance);\n }\n\n // Lotes de adição com added/consumed/remaining já agregados pelo backend.\n // sort id:DESC garante que os lotes mais recentes (não expirados) entram\n // primeiro no limite; lotes expirados são filtrados no hook.\n private async fetchAddBatches(\n idAccount: number | string,\n subscriptionId: number | string\n ): Promise<IaCreditAddBatch[]> {\n const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list/add?page=1&limit=100&sort=id:DESC`;\n\n const response = await api.apps.get<ApiPaginatedActionResult<IaCreditAddBatch>>(endpoint);\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || 'Erro ao listar lotes de créditos de IA',\n 'LIST_IA_CREDITS_ADDS_FAILED',\n 400\n );\n }\n\n const raw = response.data ?? [];\n return raw.map((item) => IaCreditAddBatchSchema.parse(item));\n }\n}\n\nexport const iaCreditsService = new IaCreditsService();\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,WAAW;AACpB,SAAS,gBAAyD;AAClE,SAAS,sBAAsB;AAC/B;AAAA,EAEE;AAAA,OAGK;AAEP,MAAM,iBAAiB;AAAA,EACrB,MAAM,eACJ,gBAC8C;AAC9C,UAAM,EAAE,WAAW,IAAI,MAAM,eAAe;AAE5C,UAAM,CAAC,kBAAkB,UAAU,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvD,KAAK,oBAAoB,YAAY,cAAc;AAAA,MACnD,KAAK,gBAAgB,YAAY,cAAc;AAAA,IACjD,CAAC;AAED,WAAO,EAAE,SAAS,MAAM,MAAM,EAAE,kBAAkB,WAAW,EAAE;AAAA,EACjE;AAAA;AAAA;AAAA,EAIA,MAAc,oBACZ,WACA,gBACiB;AACjB,UAAM,WAAW,aAAa,SAAS,kBAAkB,cAAc;AAEvE,UAAM,WAAW,MAAM,IAAI,KAAK,IAAiD,QAAQ;AAEzF,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,SAAS,QAAQ,CAAC,GAAG,CAAC,GAAG;AAC1C,WAAO,WAAW,OAAO,IAAI,OAAO,OAAO;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,gBACZ,WACA,gBAC6B;AAC7B,UAAM,WAAW,aAAa,SAAS,kBAAkB,cAAc;AAEvE,UAAM,WAAW,MAAM,IAAI,KAAK,IAAgD,QAAQ;AAExF,QAAI,SAAS,WAAW,GAAG;AACzB,YAAM,IAAI;AAAA,QACR,SAAS,WAAW;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,MAAM,SAAS,QAAQ,CAAC;AAC9B,WAAO,IAAI,IAAI,CAAC,SAAS,uBAAuB,MAAM,IAAI,CAAC;AAAA,EAC7D;AACF;AAEO,MAAM,mBAAmB,IAAI,iBAAiB;","names":[]}
@@ -1,4 +1,5 @@
1
1
  import z from "zod";
2
+ const hasExpiredSchema = z.boolean().nullish().transform((v) => v ?? false);
2
3
  const IaCreditOperationSchema = z.object({
3
4
  id: z.union([z.number(), z.string()]),
4
5
  deleted: z.number(),
@@ -14,12 +15,22 @@ const IaCreditOperationSchema = z.object({
14
15
  operation_ref: z.string().nullable().optional(),
15
16
  operation_origin: z.string().nullable().optional(),
16
17
  expiration_time: z.string().nullable(),
17
- has_expired: z.boolean(),
18
+ has_expired: hasExpiredSchema,
18
19
  consumed_from_add_id: z.union([z.number(), z.string()]).nullable(),
19
20
  id_user_add: z.union([z.number(), z.string()]).nullable(),
20
21
  user_name: z.string().nullable().optional()
21
22
  }).passthrough();
23
+ const IaCreditAddBatchSchema = z.object({
24
+ id: z.union([z.number(), z.string()]),
25
+ added_credits: z.coerce.number(),
26
+ consumed_credits: z.coerce.number(),
27
+ remaining_credits: z.coerce.number(),
28
+ datetime_add: z.string().nullable(),
29
+ expiration_time: z.string().nullable(),
30
+ has_expired: hasExpiredSchema
31
+ }).passthrough();
22
32
  export {
33
+ IaCreditAddBatchSchema,
23
34
  IaCreditOperationSchema
24
35
  };
25
36
  //# sourceMappingURL=types.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/ia-credits/types.ts"],"sourcesContent":["import z from 'zod';\r\n\r\nexport const IaCreditOperationSchema = z\r\n .object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_add: z.coerce.date().nullable(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number(),\r\n operation: z.string(), // 'add' | 'subtract'\r\n operation_value: z.union([z.number(), z.string()]).transform((v) => Number(v)),\r\n balance_after_operation: z.union([z.number(), z.string()]).optional(),\r\n balance_before_operation: z.union([z.number(), z.string()]).optional(),\r\n operation_ref: z.string().nullable().optional(),\r\n operation_origin: z.string().nullable().optional(),\r\n expiration_time: z.string().nullable(),\r\n has_expired: z.boolean(),\r\n consumed_from_add_id: z.union([z.number(), z.string()]).nullable(),\r\n id_user_add: z.union([z.number(), z.string()]).nullable(),\r\n user_name: z.string().nullable().optional(),\r\n })\r\n .passthrough();\r\n\r\nexport type IaCreditOperation = z.infer<typeof IaCreditOperationSchema>;\r\n\r\nexport type IaCreditsSummary = {\r\n totalCredits: number;\r\n usedCredits: number;\r\n availableCredits: number;\r\n nextExpiringCredits: number | null;\r\n nextExpirationInDays: number | null;\r\n};\r\n"],"mappings":"AAAA,OAAO,OAAO;AAEP,MAAM,0BAA0B,EACpC,OAAO;AAAA,EACN,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,SAAS,EAAE,OAAO;AAAA,EAClB,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS;AAAA,EACvC,OAAO,EAAE,OAAO;AAAA,EAChB,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACjD,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,OAAO;AAAA;AAAA,EACpB,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,OAAO,CAAC,CAAC;AAAA,EAC7E,yBAAyB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACpE,0BAA0B,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACrE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACjD,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,aAAa,EAAE,QAAQ;AAAA,EACvB,sBAAsB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACjE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACxD,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC,EACA,YAAY;","names":[]}
1
+ {"version":3,"sources":["../../../src/modules/ia-credits/types.ts"],"sourcesContent":["import z from 'zod';\r\n\r\n// has_expired pode vir null (ou ausente) da API — normaliza para boolean.\r\nconst hasExpiredSchema = z\r\n .boolean()\r\n .nullish()\r\n .transform((v) => v ?? false);\r\n\r\nexport const IaCreditOperationSchema = z\r\n .object({\r\n id: z.union([z.number(), z.string()]),\r\n deleted: z.number(),\r\n datetime_add: z.coerce.date().nullable(),\r\n id_wl: z.number(),\r\n id_subscription: z.union([z.number(), z.string()]),\r\n id_addon: z.number(),\r\n operation: z.string(), // 'add' | 'subtract'\r\n operation_value: z.union([z.number(), z.string()]).transform((v) => Number(v)),\r\n balance_after_operation: z.union([z.number(), z.string()]).optional(),\r\n balance_before_operation: z.union([z.number(), z.string()]).optional(),\r\n operation_ref: z.string().nullable().optional(),\r\n operation_origin: z.string().nullable().optional(),\r\n expiration_time: z.string().nullable(),\r\n has_expired: hasExpiredSchema,\r\n consumed_from_add_id: z.union([z.number(), z.string()]).nullable(),\r\n id_user_add: z.union([z.number(), z.string()]).nullable(),\r\n user_name: z.string().nullable().optional(),\r\n })\r\n .passthrough();\r\n\r\nexport type IaCreditOperation = z.infer<typeof IaCreditOperationSchema>;\r\n\r\n// Lote de créditos adicionados — agregado pelo backend em\r\n// /items/balance/list/add (added/consumed/remaining já calculados).\r\nexport const IaCreditAddBatchSchema = z\r\n .object({\r\n id: z.union([z.number(), z.string()]),\r\n added_credits: z.coerce.number(),\r\n consumed_credits: z.coerce.number(),\r\n remaining_credits: z.coerce.number(),\r\n datetime_add: z.string().nullable(),\r\n expiration_time: z.string().nullable(),\r\n has_expired: hasExpiredSchema,\r\n })\r\n .passthrough();\r\n\r\nexport type IaCreditAddBatch = z.infer<typeof IaCreditAddBatchSchema>;\r\n\r\n// Payload servido pelo route handler: saldo atual (balance_after_operation)\r\n// + lotes de adição, de onde o hook deriva o restante do sumário.\r\nexport type IaCreditsSummaryData = {\r\n availableCredits: number;\r\n addBatches: IaCreditAddBatch[];\r\n};\r\n\r\nexport type IaCreditsSummary = {\r\n totalCredits: number;\r\n usedCredits: number;\r\n availableCredits: number;\r\n nextExpiringCredits: number | null;\r\n nextExpirationInDays: number | null;\r\n};\r\n"],"mappings":"AAAA,OAAO,OAAO;AAGd,MAAM,mBAAmB,EACtB,QAAQ,EACR,QAAQ,EACR,UAAU,CAAC,MAAM,KAAK,KAAK;AAEvB,MAAM,0BAA0B,EACpC,OAAO;AAAA,EACN,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,SAAS,EAAE,OAAO;AAAA,EAClB,cAAc,EAAE,OAAO,KAAK,EAAE,SAAS;AAAA,EACvC,OAAO,EAAE,OAAO;AAAA,EAChB,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACjD,UAAU,EAAE,OAAO;AAAA,EACnB,WAAW,EAAE,OAAO;AAAA;AAAA,EACpB,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,OAAO,CAAC,CAAC;AAAA,EAC7E,yBAAyB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACpE,0BAA0B,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACrE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EAC9C,kBAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAAA,EACjD,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,aAAa;AAAA,EACb,sBAAsB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACjE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;AAAA,EACxD,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS;AAC5C,CAAC,EACA,YAAY;AAMR,MAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,IAAI,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;AAAA,EACpC,eAAe,EAAE,OAAO,OAAO;AAAA,EAC/B,kBAAkB,EAAE,OAAO,OAAO;AAAA,EAClC,mBAAmB,EAAE,OAAO,OAAO;AAAA,EACnC,cAAc,EAAE,OAAO,EAAE,SAAS;AAAA,EAClC,iBAAiB,EAAE,OAAO,EAAE,SAAS;AAAA,EACrC,aAAa;AACf,CAAC,EACA,YAAY;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/testing/constants.ts"],"sourcesContent":["// Fixed identity and endpoints used across the test infra. Single source of truth: the same\n// object feeds DUMMY_AUTH_TOKEN (via createTestJwt), the factories and the request handlers, and\n// consumer apps must mirror it in their test env (GAPPS_R3_API_URL etc.) so the URL the ApiClient\n// builds matches the one the handlers expect.\nexport const TEST_IDS = {\n wl: 1,\n account: 123,\n user: 456,\n page: 789,\n} as const;\n\n// Bases the apps MUST export as test env:\n// GAPPS_R3_API_URL = TEST_API.gapps\n// GPAGES_R3_API_URL = TEST_API.gpages\n// WHITELABEL_TOKEN_MASTER = TEST_API.masterToken\n// WHITELABEL_DOMAIN = TEST_API.domain\n// `.test` domains never resolve on the real network, so a leaked unhandled request fails loudly\n// instead of hitting a real backend.\nexport const TEST_API = {\n gapps: 'https://gapps.test',\n gpages: 'https://gpages.test',\n masterToken: 'test-master-token',\n domain: 'app.test',\n} as const;\n\n// Fixed locale and version the ApiClient uses to build the URL (`/v1/pt-br/{wl}`).\nexport const TEST_API_VERSION = 'v1';\nexport const TEST_API_LOCALE = 'pt-br';\n"],"mappings":"AAIO,MAAM,WAAW;AAAA,EACtB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AACR;AASO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAGO,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;","names":[]}
1
+ {"version":3,"sources":["../../src/testing/constants.ts"],"sourcesContent":["// Single source of truth shared by the JWT, factories and request handlers. Apps must mirror it\n// in their test env (GAPPS_R3_API_URL etc.) so the URL the ApiClient builds matches the handlers.\n// `.test` domains never resolve, so a leaked unhandled request fails loudly.\nexport const TEST_IDS = {\n wl: 1,\n account: 123,\n user: 456,\n page: 789,\n} as const;\n\nexport const TEST_API = {\n gapps: 'https://gapps.test',\n gpages: 'https://gpages.test',\n masterToken: 'test-master-token',\n domain: 'app.test',\n} as const;\n\nexport const TEST_API_VERSION = 'v1';\nexport const TEST_API_LOCALE = 'pt-br';\n"],"mappings":"AAGO,MAAM,WAAW;AAAA,EACtB,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AACR;AAEO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AACV;AAEO,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/testing/factories/create-mock.ts"],"sourcesContent":["type Factory<T, O> = (overrides?: O) => T;\n\n// Reset registry for the cached defaults. Runner-agnostic on purpose: these factories also run\n// under `next dev` (E2E request handlers) where vitest's `beforeEach` does not exist, so the app\n// calls `resetMocks()` from its own `beforeEach`.\nconst resetters = new Set<() => void>();\n\n// createMock(factory) returns a getter that:\n// - without overrides returns the SAME default instance within a test (stable for asserts);\n// - with overrides → returns a NEW instance with those fields replaced.\n// Between tests, `resetMocks()` refreshes the defaults.\nexport function createMock<T, O = Partial<T>>(factory: Factory<T, O>): Factory<T, O> {\n let instance = factory();\n resetters.add(() => {\n instance = factory();\n });\n return (overrides?: O): T => (overrides ? factory(overrides) : instance);\n}\n\n// Refreshes every default cached by createMock. Call it from the setup's beforeEach.\nexport function resetMocks(): void {\n for (const reset of resetters) reset();\n}\n"],"mappings":"AAKA,MAAM,YAAY,oBAAI,IAAgB;AAM/B,SAAS,WAA8B,SAAuC;AACnF,MAAI,WAAW,QAAQ;AACvB,YAAU,IAAI,MAAM;AAClB,eAAW,QAAQ;AAAA,EACrB,CAAC;AACD,SAAO,CAAC,cAAsB,YAAY,QAAQ,SAAS,IAAI;AACjE;AAGO,SAAS,aAAmB;AACjC,aAAW,SAAS,UAAW,OAAM;AACvC;","names":[]}
1
+ {"version":3,"sources":["../../../src/testing/factories/create-mock.ts"],"sourcesContent":["type Factory<T, O> = (overrides?: O) => T;\n\nconst resetters = new Set<() => void>();\n\n// Without overrides, returns the same cached default within a test (stable for asserts); with\n// overrides, a fresh instance. `resetMocks()` refreshes the defaults between tests — runner-agnostic\n// (these factories also run under `next dev` for E2E, where vitest's `beforeEach` is absent).\nexport function createMock<T, O = Partial<T>>(factory: Factory<T, O>): Factory<T, O> {\n let instance = factory();\n resetters.add(() => {\n instance = factory();\n });\n return (overrides?: O): T => (overrides ? factory(overrides) : instance);\n}\n\nexport function resetMocks(): void {\n for (const reset of resetters) reset();\n}\n"],"mappings":"AAEA,MAAM,YAAY,oBAAI,IAAgB;AAK/B,SAAS,WAA8B,SAAuC;AACnF,MAAI,WAAW,QAAQ;AACvB,YAAU,IAAI,MAAM;AAClB,eAAW,QAAQ;AAAA,EACrB,CAAC;AACD,SAAO,CAAC,cAAsB,YAAY,QAAQ,SAAS,IAAI;AACjE;AAEO,SAAS,aAAmB;AACjC,aAAW,SAAS,UAAW,OAAM;AACvC;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/testing/factories/subscription.factory.ts"],"sourcesContent":["import { faker } from '@faker-js/faker';\nimport { Subscription, SubscriptionItem } from '../../modules/subscriptions/types/subscription.type';\nimport { TEST_IDS } from '../constants';\nimport { createMock } from './create-mock';\n\n// Dates are Date objects (the inferred output of the schema).\nexport const createSubscriptionItemMock = createMock<SubscriptionItem, Partial<SubscriptionItem>>(\n (overrides) => ({\n id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),\n deleted: overrides?.deleted ?? 0,\n datetime_add: overrides?.datetime_add ?? new Date('2025-01-01T00:00:00Z'),\n id_wl: overrides?.id_wl ?? TEST_IDS.wl,\n id_subscription: overrides?.id_subscription ?? 1,\n id_addon: overrides?.id_addon ?? null,\n value: overrides?.value ?? 9990,\n currency: overrides?.currency ?? 'brl',\n quantity: overrides?.quantity ?? 1,\n payment_status: overrides?.payment_status ?? 1,\n id_charge: overrides?.id_charge ?? null,\n trial: overrides?.trial ?? true,\n }),\n);\n\n// Default: an active subscription with a future due date (a valid trial).\nexport const createSubscriptionMock = createMock<Subscription, Partial<Subscription>>(\n (overrides) => ({\n id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),\n deleted: overrides?.deleted ?? 0,\n datetime_add: overrides?.datetime_add ?? new Date('2025-01-01T00:00:00Z'),\n id_wl: overrides?.id_wl ?? TEST_IDS.wl,\n id_account: overrides?.id_account ?? TEST_IDS.account,\n id_card: overrides?.id_card ?? null,\n id_coupon: overrides?.id_coupon ?? null,\n type: overrides?.type ?? 'recurring',\n payment_method: overrides?.payment_method ?? 1,\n periodicity: overrides?.periodicity ?? 1,\n value: overrides?.value ?? 9990,\n id_product: overrides?.id_product ?? 1,\n id_plan: overrides?.id_plan ?? 1,\n id_gateway: overrides?.id_gateway ?? null,\n gateway_account: overrides?.gateway_account ?? null,\n date_hiring: overrides?.date_hiring ?? new Date('2025-01-01'),\n date_due: overrides?.date_due ?? new Date('2099-01-01'),\n date_cancellation: overrides?.date_cancellation ?? null,\n date_verification: overrides?.date_verification ?? null,\n cancellation_reason: overrides?.cancellation_reason ?? null,\n cancellation_description: overrides?.cancellation_description ?? null,\n active: overrides?.active ?? true,\n charged: overrides?.charged ?? true,\n items: overrides?.items ?? [createSubscriptionItemMock()],\n }),\n);\n"],"mappings":"AAAA,SAAS,aAAa;AAEtB,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAGpB,MAAM,6BAA6B;AAAA,EACxC,CAAC,eAAe;AAAA,IACd,IAAI,WAAW,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,IAC5D,SAAS,WAAW,WAAW;AAAA,IAC/B,cAAc,WAAW,gBAAgB,oBAAI,KAAK,sBAAsB;AAAA,IACxE,OAAO,WAAW,SAAS,SAAS;AAAA,IACpC,iBAAiB,WAAW,mBAAmB;AAAA,IAC/C,UAAU,WAAW,YAAY;AAAA,IACjC,OAAO,WAAW,SAAS;AAAA,IAC3B,UAAU,WAAW,YAAY;AAAA,IACjC,UAAU,WAAW,YAAY;AAAA,IACjC,gBAAgB,WAAW,kBAAkB;AAAA,IAC7C,WAAW,WAAW,aAAa;AAAA,IACnC,OAAO,WAAW,SAAS;AAAA,EAC7B;AACF;AAGO,MAAM,yBAAyB;AAAA,EACpC,CAAC,eAAe;AAAA,IACd,IAAI,WAAW,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,IAC5D,SAAS,WAAW,WAAW;AAAA,IAC/B,cAAc,WAAW,gBAAgB,oBAAI,KAAK,sBAAsB;AAAA,IACxE,OAAO,WAAW,SAAS,SAAS;AAAA,IACpC,YAAY,WAAW,cAAc,SAAS;AAAA,IAC9C,SAAS,WAAW,WAAW;AAAA,IAC/B,WAAW,WAAW,aAAa;AAAA,IACnC,MAAM,WAAW,QAAQ;AAAA,IACzB,gBAAgB,WAAW,kBAAkB;AAAA,IAC7C,aAAa,WAAW,eAAe;AAAA,IACvC,OAAO,WAAW,SAAS;AAAA,IAC3B,YAAY,WAAW,cAAc;AAAA,IACrC,SAAS,WAAW,WAAW;AAAA,IAC/B,YAAY,WAAW,cAAc;AAAA,IACrC,iBAAiB,WAAW,mBAAmB;AAAA,IAC/C,aAAa,WAAW,eAAe,oBAAI,KAAK,YAAY;AAAA,IAC5D,UAAU,WAAW,YAAY,oBAAI,KAAK,YAAY;AAAA,IACtD,mBAAmB,WAAW,qBAAqB;AAAA,IACnD,mBAAmB,WAAW,qBAAqB;AAAA,IACnD,qBAAqB,WAAW,uBAAuB;AAAA,IACvD,0BAA0B,WAAW,4BAA4B;AAAA,IACjE,QAAQ,WAAW,UAAU;AAAA,IAC7B,SAAS,WAAW,WAAW;AAAA,IAC/B,OAAO,WAAW,SAAS,CAAC,2BAA2B,CAAC;AAAA,EAC1D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/testing/factories/subscription.factory.ts"],"sourcesContent":["import { faker } from '@faker-js/faker';\nimport { Subscription, SubscriptionItem } from '../../modules/subscriptions/types/subscription.type';\nimport { TEST_IDS } from '../constants';\nimport { createMock } from './create-mock';\n\nexport const createSubscriptionItemMock = createMock<SubscriptionItem, Partial<SubscriptionItem>>(\n (overrides) => ({\n id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),\n deleted: overrides?.deleted ?? 0,\n datetime_add: overrides?.datetime_add ?? new Date('2025-01-01T00:00:00Z'),\n id_wl: overrides?.id_wl ?? TEST_IDS.wl,\n id_subscription: overrides?.id_subscription ?? 1,\n id_addon: overrides?.id_addon ?? null,\n value: overrides?.value ?? 9990,\n currency: overrides?.currency ?? 'brl',\n quantity: overrides?.quantity ?? 1,\n payment_status: overrides?.payment_status ?? 1,\n id_charge: overrides?.id_charge ?? null,\n trial: overrides?.trial ?? true,\n }),\n);\n\n// Default: active with a future due date (a valid trial).\nexport const createSubscriptionMock = createMock<Subscription, Partial<Subscription>>(\n (overrides) => ({\n id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),\n deleted: overrides?.deleted ?? 0,\n datetime_add: overrides?.datetime_add ?? new Date('2025-01-01T00:00:00Z'),\n id_wl: overrides?.id_wl ?? TEST_IDS.wl,\n id_account: overrides?.id_account ?? TEST_IDS.account,\n id_card: overrides?.id_card ?? null,\n id_coupon: overrides?.id_coupon ?? null,\n type: overrides?.type ?? 'recurring',\n payment_method: overrides?.payment_method ?? 1,\n periodicity: overrides?.periodicity ?? 1,\n value: overrides?.value ?? 9990,\n id_product: overrides?.id_product ?? 1,\n id_plan: overrides?.id_plan ?? 1,\n id_gateway: overrides?.id_gateway ?? null,\n gateway_account: overrides?.gateway_account ?? null,\n date_hiring: overrides?.date_hiring ?? new Date('2025-01-01'),\n date_due: overrides?.date_due ?? new Date('2099-01-01'),\n date_cancellation: overrides?.date_cancellation ?? null,\n date_verification: overrides?.date_verification ?? null,\n cancellation_reason: overrides?.cancellation_reason ?? null,\n cancellation_description: overrides?.cancellation_description ?? null,\n active: overrides?.active ?? true,\n charged: overrides?.charged ?? true,\n items: overrides?.items ?? [createSubscriptionItemMock()],\n }),\n);\n"],"mappings":"AAAA,SAAS,aAAa;AAEtB,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAEpB,MAAM,6BAA6B;AAAA,EACxC,CAAC,eAAe;AAAA,IACd,IAAI,WAAW,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,IAC5D,SAAS,WAAW,WAAW;AAAA,IAC/B,cAAc,WAAW,gBAAgB,oBAAI,KAAK,sBAAsB;AAAA,IACxE,OAAO,WAAW,SAAS,SAAS;AAAA,IACpC,iBAAiB,WAAW,mBAAmB;AAAA,IAC/C,UAAU,WAAW,YAAY;AAAA,IACjC,OAAO,WAAW,SAAS;AAAA,IAC3B,UAAU,WAAW,YAAY;AAAA,IACjC,UAAU,WAAW,YAAY;AAAA,IACjC,gBAAgB,WAAW,kBAAkB;AAAA,IAC7C,WAAW,WAAW,aAAa;AAAA,IACnC,OAAO,WAAW,SAAS;AAAA,EAC7B;AACF;AAGO,MAAM,yBAAyB;AAAA,EACpC,CAAC,eAAe;AAAA,IACd,IAAI,WAAW,MAAM,MAAM,OAAO,IAAI,EAAE,KAAK,GAAG,KAAK,MAAM,CAAC;AAAA,IAC5D,SAAS,WAAW,WAAW;AAAA,IAC/B,cAAc,WAAW,gBAAgB,oBAAI,KAAK,sBAAsB;AAAA,IACxE,OAAO,WAAW,SAAS,SAAS;AAAA,IACpC,YAAY,WAAW,cAAc,SAAS;AAAA,IAC9C,SAAS,WAAW,WAAW;AAAA,IAC/B,WAAW,WAAW,aAAa;AAAA,IACnC,MAAM,WAAW,QAAQ;AAAA,IACzB,gBAAgB,WAAW,kBAAkB;AAAA,IAC7C,aAAa,WAAW,eAAe;AAAA,IACvC,OAAO,WAAW,SAAS;AAAA,IAC3B,YAAY,WAAW,cAAc;AAAA,IACrC,SAAS,WAAW,WAAW;AAAA,IAC/B,YAAY,WAAW,cAAc;AAAA,IACrC,iBAAiB,WAAW,mBAAmB;AAAA,IAC/C,aAAa,WAAW,eAAe,oBAAI,KAAK,YAAY;AAAA,IAC5D,UAAU,WAAW,YAAY,oBAAI,KAAK,YAAY;AAAA,IACtD,mBAAmB,WAAW,qBAAqB;AAAA,IACnD,mBAAmB,WAAW,qBAAqB;AAAA,IACnD,qBAAqB,WAAW,uBAAuB;AAAA,IACvD,0BAA0B,WAAW,4BAA4B;AAAA,IACjE,QAAQ,WAAW,UAAU;AAAA,IAC7B,SAAS,WAAW,WAAW;AAAA,IAC/B,OAAO,WAAW,SAAS,CAAC,2BAA2B,CAAC;AAAA,EAC1D;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["// Shared test infra for the GreatApps apps. Imported as `@greatapps/common/testing`.\n//\n// This barrel is LIGHT and safe for node/E2E/handlers: only deterministic factories and session\n// request handlers. The React PROVIDERS (which pull the lib's client tree) live in a separate\n// subpath — `@greatapps/common/testing/react` so the barrel and its load-time side effects\n// (e.g. zustand stores reading localStorage) don't leak into reducer/route-handler tests.\n//\n// `msw` and `@faker-js/faker` are OPTIONAL peer dependencies: only the files here import them.\nexport { TEST_IDS, TEST_API, TEST_API_VERSION, TEST_API_LOCALE } from './constants';\nexport * from './factories';\nexport * from './msw';\n"],"mappings":"AAQA,SAAS,UAAU,UAAU,kBAAkB,uBAAuB;AACtE,cAAc;AACd,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../src/testing/index.ts"],"sourcesContent":["// `@greatapps/common/testing` light, node/E2E-safe (factories + session handlers only). The\n// React providers live in `@greatapps/common/testing/react` so the client barrel and its\n// load-time side effects (e.g. zustand stores reading localStorage) don't leak into\n// reducer/route-handler tests. `msw` and `@faker-js/faker` are optional peer dependencies.\nexport { TEST_IDS, TEST_API, TEST_API_VERSION, TEST_API_LOCALE } from './constants';\nexport * from './factories';\nexport * from './msw';\n"],"mappings":"AAIA,SAAS,UAAU,UAAU,kBAAkB,uBAAuB;AACtE,cAAc;AACd,cAAc;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/testing/msw/envelope.ts"],"sourcesContent":["import { HttpResponse } from 'msw';\n\n// The envelope GreatApps backends return. Services read `data` as an array and take `data[0]` on\n// finds (see the user/account/whitelabel/pages services), so the success default is a list. Use\n// `apiOne` when the consumer expects `data` to be a single object.\nexport function apiList<T>(items: T[], total = items.length) {\n return HttpResponse.json({ status: 1, data: items, total });\n}\n\n// Success with a single item wrapped in a list (`{ status:1, data:[item], total:1 }`).\nexport function apiFind<T>(item: T) {\n return apiList([item], 1);\n}\n\n// Success with `data` as a single object (few endpoints; most use a list).\nexport function apiOne<T>(data: T) {\n return HttpResponse.json({ status: 1, data });\n}\n\n// Backend-shaped error (`{ status:0, message }`) with an HTTP status.\nexport function apiError(message = 'test error', status = 400) {\n return HttpResponse.json({ status: 0, message }, { status });\n}\n"],"mappings":"AAAA,SAAS,oBAAoB;AAKtB,SAAS,QAAW,OAAY,QAAQ,MAAM,QAAQ;AAC3D,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAC;AAC5D;AAGO,SAAS,QAAW,MAAS;AAClC,SAAO,QAAQ,CAAC,IAAI,GAAG,CAAC;AAC1B;AAGO,SAAS,OAAU,MAAS;AACjC,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,KAAK,CAAC;AAC9C;AAGO,SAAS,SAAS,UAAU,cAAc,SAAS,KAAK;AAC7D,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,EAAE,OAAO,CAAC;AAC7D;","names":[]}
1
+ {"version":3,"sources":["../../../src/testing/msw/envelope.ts"],"sourcesContent":["import { HttpResponse } from 'msw';\n\n// The envelope GreatApps backends return. Services read `data` as an array and take `data[0]` on\n// finds, so the success default is a list; use `apiOne` for the few endpoints returning an object.\nexport function apiList<T>(items: T[], total = items.length) {\n return HttpResponse.json({ status: 1, data: items, total });\n}\n\nexport function apiFind<T>(item: T) {\n return apiList([item], 1);\n}\n\nexport function apiOne<T>(data: T) {\n return HttpResponse.json({ status: 1, data });\n}\n\nexport function apiError(message = 'test error', status = 400) {\n return HttpResponse.json({ status: 0, message }, { status });\n}\n"],"mappings":"AAAA,SAAS,oBAAoB;AAItB,SAAS,QAAW,OAAY,QAAQ,MAAM,QAAQ;AAC3D,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,MAAM,OAAO,MAAM,CAAC;AAC5D;AAEO,SAAS,QAAW,MAAS;AAClC,SAAO,QAAQ,CAAC,IAAI,GAAG,CAAC;AAC1B;AAEO,SAAS,OAAU,MAAS;AACjC,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,KAAK,CAAC;AAC9C;AAEO,SAAS,SAAS,UAAU,cAAc,SAAS,KAAK;AAC7D,SAAO,aAAa,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,EAAE,OAAO,CAAC;AAC7D;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/testing/msw/session.handlers.ts"],"sourcesContent":["import { http } from 'msw';\nimport type { Account } from '../../modules/accounts/types';\nimport type { User } from '../../modules/users/schema';\nimport type { WhitelabelTokenData } from '../../modules/whitelabel/schema';\nimport { TEST_API } from '../constants';\nimport { createAccountMock } from '../factories/account.factory';\nimport { createUserMock } from '../factories/user.factory';\nimport { createWhitelabelTokenMock } from '../factories/whitelabel.factory';\nimport { apiFind } from './envelope';\n\nexport interface SessionHandlersOptions {\n // gapps base (= GAPPS_R3_API_URL). Defaults to TEST_API.gapps.\n gappsBase?: string;\n user?: User;\n account?: Account;\n whitelabel?: WhitelabelTokenData;\n}\n\n// Handlers for the server-side session resolution any app triggers when booting an authenticated\n// route (with DUMMY_AUTH_TOKEN): whitelabel by domain, token by wl id, user and account. These are\n// what the layout prefetches and what the ApiClient needs to build the URL/header. Apps compose\n// them with their own handlers:\n// setupServer(...makeSessionHandlers(), ...myPageHandlers)\n// Paths follow the ApiClient template: `{base}/v1/{locale}/{wl}{endpoint}`.\nexport function makeSessionHandlers(opts: SessionHandlersOptions = {}) {\n const base = opts.gappsBase ?? TEST_API.gapps;\n const user = opts.user ?? createUserMock();\n const account = opts.account ?? createAccountMock();\n const whitelabel = opts.whitelabel ?? createWhitelabelTokenMock();\n\n return [\n http.get(`${base}/v1/:locale/:wl/whitelabel/:host/token`, () => apiFind(whitelabel)),\n http.get(`${base}/v1/:locale/:wl/tokens`, () => apiFind(whitelabel)),\n // The users path has more segments, so it must come before /accounts/:acc.\n http.get(`${base}/v1/:locale/:wl/accounts/:acc/users/:user`, () => apiFind(user)),\n http.get(`${base}/v1/:locale/:wl/accounts/:acc`, () => apiFind(account)),\n ];\n}\n"],"mappings":"AAAA,SAAS,YAAY;AAIrB,SAAS,gBAAgB;AACzB,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAC1C,SAAS,eAAe;AAgBjB,SAAS,oBAAoB,OAA+B,CAAC,GAAG;AACrE,QAAM,OAAO,KAAK,aAAa,SAAS;AACxC,QAAM,OAAO,KAAK,QAAQ,eAAe;AACzC,QAAM,UAAU,KAAK,WAAW,kBAAkB;AAClD,QAAM,aAAa,KAAK,cAAc,0BAA0B;AAEhE,SAAO;AAAA,IACL,KAAK,IAAI,GAAG,IAAI,0CAA0C,MAAM,QAAQ,UAAU,CAAC;AAAA,IACnF,KAAK,IAAI,GAAG,IAAI,0BAA0B,MAAM,QAAQ,UAAU,CAAC;AAAA;AAAA,IAEnE,KAAK,IAAI,GAAG,IAAI,6CAA6C,MAAM,QAAQ,IAAI,CAAC;AAAA,IAChF,KAAK,IAAI,GAAG,IAAI,iCAAiC,MAAM,QAAQ,OAAO,CAAC;AAAA,EACzE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/testing/msw/session.handlers.ts"],"sourcesContent":["import { http } from 'msw';\nimport type { Account } from '../../modules/accounts/types';\nimport type { User } from '../../modules/users/schema';\nimport type { WhitelabelTokenData } from '../../modules/whitelabel/schema';\nimport { TEST_API } from '../constants';\nimport { createAccountMock } from '../factories/account.factory';\nimport { createUserMock } from '../factories/user.factory';\nimport { createWhitelabelTokenMock } from '../factories/whitelabel.factory';\nimport { apiFind } from './envelope';\n\nexport interface SessionHandlersOptions {\n gappsBase?: string;\n user?: User;\n account?: Account;\n whitelabel?: WhitelabelTokenData;\n}\n\n// Server-side session resolution any app triggers when booting an authenticated route with\n// DUMMY_AUTH_TOKEN (whitelabel by domain, token by wl id, user, account). Compose with app\n// handlers: setupServer(...makeSessionHandlers(), ...myPageHandlers).\nexport function makeSessionHandlers(opts: SessionHandlersOptions = {}) {\n const base = opts.gappsBase ?? TEST_API.gapps;\n const user = opts.user ?? createUserMock();\n const account = opts.account ?? createAccountMock();\n const whitelabel = opts.whitelabel ?? createWhitelabelTokenMock();\n\n return [\n http.get(`${base}/v1/:locale/:wl/whitelabel/:host/token`, () => apiFind(whitelabel)),\n http.get(`${base}/v1/:locale/:wl/tokens`, () => apiFind(whitelabel)),\n // The users path has more segments, so it must come before /accounts/:acc.\n http.get(`${base}/v1/:locale/:wl/accounts/:acc/users/:user`, () => apiFind(user)),\n http.get(`${base}/v1/:locale/:wl/accounts/:acc`, () => apiFind(account)),\n ];\n}\n"],"mappings":"AAAA,SAAS,YAAY;AAIrB,SAAS,gBAAgB;AACzB,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,iCAAiC;AAC1C,SAAS,eAAe;AAYjB,SAAS,oBAAoB,OAA+B,CAAC,GAAG;AACrE,QAAM,OAAO,KAAK,aAAa,SAAS;AACxC,QAAM,OAAO,KAAK,QAAQ,eAAe;AACzC,QAAM,UAAU,KAAK,WAAW,kBAAkB;AAClD,QAAM,aAAa,KAAK,cAAc,0BAA0B;AAEhE,SAAO;AAAA,IACL,KAAK,IAAI,GAAG,IAAI,0CAA0C,MAAM,QAAQ,UAAU,CAAC;AAAA,IACnF,KAAK,IAAI,GAAG,IAAI,0BAA0B,MAAM,QAAQ,UAAU,CAAC;AAAA;AAAA,IAEnE,KAAK,IAAI,GAAG,IAAI,6CAA6C,MAAM,QAAQ,IAAI,CAAC;AAAA,IAChF,KAAK,IAAI,GAAG,IAAI,iCAAiC,MAAM,QAAQ,OAAO,CAAC;AAAA,EACzE;AACF;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/testing/react/test-query-client.ts"],"sourcesContent":["import { QueryClient } from '@tanstack/react-query';\n\n/**\n * QueryClient para testes: sem retry (erros aparecem na hora), sem cache entre testes\n * (`gcTime: 0`) e sem refetch por foco. Crie um por teste pra isolamento total.\n */\nexport function makeTestQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: { retry: false, gcTime: 0, staleTime: 0, refetchOnWindowFocus: false },\n mutations: { retry: false },\n },\n });\n}\n"],"mappings":"AAAA,SAAS,mBAAmB;AAMrB,SAAS,sBAAmC;AACjD,SAAO,IAAI,YAAY;AAAA,IACrB,gBAAgB;AAAA,MACd,SAAS,EAAE,OAAO,OAAO,QAAQ,GAAG,WAAW,GAAG,sBAAsB,MAAM;AAAA,MAC9E,WAAW,EAAE,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../../src/testing/react/test-query-client.ts"],"sourcesContent":["import { QueryClient } from '@tanstack/react-query';\n\n// retry off (errors surface immediately) and gcTime 0 (no cache across tests). Create one per test.\nexport function makeTestQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: { retry: false, gcTime: 0, staleTime: 0, refetchOnWindowFocus: false },\n mutations: { retry: false },\n },\n });\n}\n"],"mappings":"AAAA,SAAS,mBAAmB;AAGrB,SAAS,sBAAmC;AACjD,SAAO,IAAI,YAAY;AAAA,IACrB,gBAAgB;AAAA,MACd,SAAS,EAAE,OAAO,OAAO,QAAQ,GAAG,WAAW,GAAG,sBAAsB,MAAM;AAAA,MAC9E,WAAW,EAAE,OAAO,MAAM;AAAA,IAC5B;AAAA,EACF,CAAC;AACH;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.714",
3
+ "version": "1.1.716",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -46,12 +46,6 @@
46
46
  "dist",
47
47
  "src"
48
48
  ],
49
- "scripts": {
50
- "build": "tsup",
51
- "dev": "tsup --watch",
52
- "typecheck": "tsc --noEmit",
53
- "prepublishOnly": "npm run build"
54
- },
55
49
  "keywords": [],
56
50
  "author": "",
57
51
  "license": "ISC",
@@ -87,8 +81,8 @@
87
81
  "tailwind-merge": "3.5.0"
88
82
  },
89
83
  "devDependencies": {
84
+ "@faker-js/faker": "9.9.0",
90
85
  "@hookform/resolvers": "5.2.2",
91
- "zod": "4.4.3",
92
86
  "@tanstack/query-broadcast-client-experimental": "5.95.2",
93
87
  "@tanstack/react-query": "5.95.2",
94
88
  "@tanstack/react-query-devtools": "5.95.2",
@@ -98,7 +92,6 @@
98
92
  "@types/react-dom": "19.2.3",
99
93
  "glob": "13.0.6",
100
94
  "msw": "2.7.0",
101
- "@faker-js/faker": "9.9.0",
102
95
  "next": "16.2.1",
103
96
  "next-intl": "4.12.0",
104
97
  "react": "19.1.4",
@@ -106,17 +99,18 @@
106
99
  "react-hook-form": "7.72.0",
107
100
  "tsup": "8.5.1",
108
101
  "typescript": "5.9.3",
102
+ "zod": "4.4.3",
109
103
  "zustand": "5.0.12"
110
104
  },
111
105
  "peerDependencies": {
106
+ "@faker-js/faker": ">=9.0.0",
112
107
  "@hookform/resolvers": ">=3.0.0",
113
108
  "@tanstack/query-broadcast-client-experimental": ">=5.0.0",
114
109
  "@tanstack/react-query": ">=5.0.0",
115
110
  "@tanstack/react-query-persist-client": ">=5.0.0",
111
+ "msw": ">=2.0.0",
116
112
  "next": ">=16.0.0",
117
113
  "next-intl": ">=4.0.0",
118
- "@faker-js/faker": ">=9.0.0",
119
- "msw": ">=2.0.0",
120
114
  "react": ">=19.0.0",
121
115
  "react-dom": ">=19.0.0",
122
116
  "react-hook-form": ">=7.0.0",
@@ -131,5 +125,10 @@
131
125
  "@faker-js/faker": {
132
126
  "optional": true
133
127
  }
128
+ },
129
+ "scripts": {
130
+ "build": "tsup",
131
+ "dev": "tsup --watch",
132
+ "typecheck": "tsc --noEmit"
134
133
  }
135
- }
134
+ }
package/src/index.ts CHANGED
@@ -107,6 +107,8 @@ export { useChargeAction } from "./modules/charges/hooks/charge-action.hook";
107
107
  export { useIaCredits } from "./modules/ia-credits/hooks/ia-credits.hook";
108
108
  export type {
109
109
  IaCreditsSummary,
110
+ IaCreditsSummaryData,
111
+ IaCreditAddBatch,
110
112
  IaCreditOperation,
111
113
  } from "./modules/ia-credits/types";
112
114
  export type {
@@ -8,7 +8,7 @@ export function createListIaCreditsHandler() {
8
8
  return async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
9
9
  return safeRouteHandler(async () => {
10
10
  const { id } = await params;
11
- return iaCreditsService.listOperations(id);
11
+ return iaCreditsService.getSummaryData(id);
12
12
  });
13
13
  };
14
14
  }
@@ -3,67 +3,56 @@
3
3
  import { useMemo } from 'react';
4
4
  import { useQuery } from '@tanstack/react-query';
5
5
  import { apiFetch } from '../../../infra/http/api-fetch';
6
- import type { PaginatedSuccessResult } from '../../../infra/api/types';
7
- import type { IaCreditOperation, IaCreditsSummary } from '../types';
6
+ import type { SuccessResult } from '../../../infra/api/types';
7
+ import type { IaCreditsSummary, IaCreditsSummaryData } from '../types';
8
8
  import { useActiveSubscription } from '../../subscriptions/hooks/find-active-subscription.hook';
9
9
  import { useAuthQueryKey } from '../../../hooks/useAuthQueryKey';
10
10
 
11
- function calculateSummary(operations: IaCreditOperation[]): IaCreditsSummary {
12
- const today = new Date();
13
- const todayDate = new Date(today.getFullYear(), today.getMonth(), today.getDate());
11
+ const MS_PER_DAY = 1000 * 60 * 60 * 24;
14
12
 
15
- const adds = operations.filter((op) => op.operation === 'add');
16
- const subtracts = operations.filter((op) => op.operation === 'subtract');
13
+ const EMPTY_SUMMARY: IaCreditsSummary = {
14
+ totalCredits: 0,
15
+ usedCredits: 0,
16
+ availableCredits: 0,
17
+ nextExpiringCredits: null,
18
+ nextExpirationInDays: null,
19
+ };
20
+
21
+ function startOfDay(date: Date): Date {
22
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
23
+ }
24
+
25
+ function calculateSummary(data: IaCreditsSummaryData | null): IaCreditsSummary {
26
+ if (!data) return EMPTY_SUMMARY;
27
+
28
+ const today = startOfDay(new Date());
17
29
 
18
30
  let totalCredits = 0;
19
31
  let usedCredits = 0;
20
32
  let nextExpirationInDays: number | null = null;
21
33
  let nextExpiringCredits: number | null = null;
22
34
 
23
- for (const add of adds) {
24
- const expirationRaw = add.expiration_time;
25
- if (!expirationRaw) continue;
26
-
27
- const expiration = new Date(expirationRaw);
28
- const expirationDate = new Date(
29
- expiration.getFullYear(),
30
- expiration.getMonth(),
31
- expiration.getDate()
32
- );
35
+ for (const batch of data.addBatches) {
36
+ if (batch.has_expired) continue;
33
37
 
34
- const expiredByDate = expirationDate.getTime() < todayDate.getTime();
35
- const hasExpired = add.has_expired || expiredByDate;
38
+ totalCredits += batch.added_credits;
39
+ usedCredits += batch.consumed_credits;
36
40
 
37
- if (hasExpired) continue;
41
+ if (batch.remaining_credits <= 0 || !batch.expiration_time) continue;
38
42
 
39
- const addedCredits = add.operation_value;
43
+ const expirationDate = startOfDay(new Date(batch.expiration_time));
44
+ const days = Math.max(0, Math.ceil((expirationDate.getTime() - today.getTime()) / MS_PER_DAY));
40
45
 
41
- const consumedForAdd = subtracts
42
- .filter((sub) => String(sub.consumed_from_add_id) === String(add.id))
43
- .reduce((sum, sub) => sum + sub.operation_value, 0);
44
-
45
- const remainingForAdd = Math.max(0, addedCredits - consumedForAdd);
46
-
47
- totalCredits += addedCredits;
48
- usedCredits += consumedForAdd;
49
-
50
- const diffMs = expirationDate.getTime() - todayDate.getTime();
51
- const days = Math.max(0, Math.ceil(diffMs / (1000 * 60 * 60 * 24)));
52
-
53
- if (remainingForAdd > 0) {
54
- if (nextExpirationInDays === null || days < nextExpirationInDays) {
55
- nextExpirationInDays = days;
56
- nextExpiringCredits = remainingForAdd;
57
- }
46
+ if (nextExpirationInDays === null || days < nextExpirationInDays) {
47
+ nextExpirationInDays = days;
48
+ nextExpiringCredits = batch.remaining_credits;
58
49
  }
59
50
  }
60
51
 
61
- const availableCredits = Math.max(0, totalCredits - usedCredits);
62
-
63
52
  return {
64
53
  totalCredits,
65
54
  usedCredits,
66
- availableCredits,
55
+ availableCredits: Math.max(0, data.availableCredits),
67
56
  nextExpiringCredits,
68
57
  nextExpirationInDays,
69
58
  };
@@ -82,7 +71,7 @@ export function useIaCredits(options: UseIaCreditsOptions = {}) {
82
71
  const query = useQuery({
83
72
  queryKey,
84
73
  queryFn: ({ signal }) =>
85
- apiFetch<PaginatedSuccessResult<IaCreditOperation>>(
74
+ apiFetch<SuccessResult<IaCreditsSummaryData>>(
86
75
  `/api/subscriptions/${subscriptionId}/ia-credits`,
87
76
  { signal }
88
77
  ),
@@ -90,14 +79,12 @@ export function useIaCredits(options: UseIaCreditsOptions = {}) {
90
79
  refetchInterval: options.refetchInterval ?? false,
91
80
  });
92
81
 
93
- const operations = query.data?.data ?? [];
82
+ const summaryData = query.data?.data ?? null;
94
83
 
95
- // eslint-disable-next-line react-hooks/exhaustive-deps
96
- const summary = useMemo(() => calculateSummary(operations), [operations]);
84
+ const summary = useMemo(() => calculateSummary(summaryData), [summaryData]);
97
85
 
98
86
  return {
99
87
  subscription,
100
- operations,
101
88
  summary,
102
89
  isLoading: isSubscriptionLoading || query.isPending,
103
90
  isSubscriptionLoading,
@@ -1,37 +1,73 @@
1
- import 'server-only';
2
-
3
- import { api } from '../../../infra/api/client';
4
- import { ApiError, ApiPaginatedActionResult, PaginatedSuccessResult } from '../../../infra/api/types';
5
- import { getUserContext } from '../../auth/utils/get-user-context';
6
- import { IaCreditOperation, IaCreditOperationSchema } from '../types';
7
-
8
- class IaCreditsService {
9
- async listOperations(
10
- subscriptionId: number | string
11
- ): Promise<PaginatedSuccessResult<IaCreditOperation>> {
12
- const { id_account } = await getUserContext();
13
-
14
- const endpoint = `/accounts/${id_account}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=20&sort=id:DESC`;
15
-
16
- const response = await api.apps.get<ApiPaginatedActionResult<IaCreditOperation>>(endpoint);
17
-
18
- if (response.status === 0) {
19
- throw new ApiError(
20
- response.message || 'Erro ao listar créditos de IA',
21
- 'LIST_IA_CREDITS_FAILED',
22
- 400
23
- );
24
- }
25
-
26
- const raw = response.data ?? [];
27
- const data = raw.map((item) => IaCreditOperationSchema.parse(item));
28
-
29
- return {
30
- data,
31
- total: response.total ?? data.length,
32
- success: true,
33
- };
34
- }
35
- }
36
-
37
- export const iaCreditsService = new IaCreditsService();
1
+ import 'server-only';
2
+
3
+ import { api } from '../../../infra/api/client';
4
+ import { ApiError, ApiPaginatedActionResult, SuccessResult } from '../../../infra/api/types';
5
+ import { getUserContext } from '../../auth/utils/get-user-context';
6
+ import {
7
+ IaCreditAddBatch,
8
+ IaCreditAddBatchSchema,
9
+ IaCreditOperation,
10
+ IaCreditsSummaryData,
11
+ } from '../types';
12
+
13
+ class IaCreditsService {
14
+ async getSummaryData(
15
+ subscriptionId: number | string
16
+ ): Promise<SuccessResult<IaCreditsSummaryData>> {
17
+ const { id_account } = await getUserContext();
18
+
19
+ const [availableCredits, addBatches] = await Promise.all([
20
+ this.fetchCurrentBalance(id_account, subscriptionId),
21
+ this.fetchAddBatches(id_account, subscriptionId),
22
+ ]);
23
+
24
+ return { success: true, data: { availableCredits, addBatches } };
25
+ }
26
+
27
+ // Saldo atual = balance_after_operation da última operação do extrato
28
+ // (sort id:DESC, limit=1). Já é o saldo do usuário, não precisa recalcular.
29
+ private async fetchCurrentBalance(
30
+ idAccount: number | string,
31
+ subscriptionId: number | string
32
+ ): Promise<number> {
33
+ const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list?page=1&limit=1&sort=id:DESC`;
34
+
35
+ const response = await api.apps.get<ApiPaginatedActionResult<IaCreditOperation>>(endpoint);
36
+
37
+ if (response.status === 0) {
38
+ throw new ApiError(
39
+ response.message || 'Erro ao consultar saldo de créditos de IA',
40
+ 'GET_IA_CREDITS_BALANCE_FAILED',
41
+ 400
42
+ );
43
+ }
44
+
45
+ const balance = (response.data ?? [])[0]?.balance_after_operation;
46
+ return balance == null ? 0 : Number(balance);
47
+ }
48
+
49
+ // Lotes de adição com added/consumed/remaining já agregados pelo backend.
50
+ // sort id:DESC garante que os lotes mais recentes (não expirados) entram
51
+ // primeiro no limite; lotes expirados são filtrados no hook.
52
+ private async fetchAddBatches(
53
+ idAccount: number | string,
54
+ subscriptionId: number | string
55
+ ): Promise<IaCreditAddBatch[]> {
56
+ const endpoint = `/accounts/${idAccount}/subscriptions/${subscriptionId}/items/balance/list/add?page=1&limit=100&sort=id:DESC`;
57
+
58
+ const response = await api.apps.get<ApiPaginatedActionResult<IaCreditAddBatch>>(endpoint);
59
+
60
+ if (response.status === 0) {
61
+ throw new ApiError(
62
+ response.message || 'Erro ao listar lotes de créditos de IA',
63
+ 'LIST_IA_CREDITS_ADDS_FAILED',
64
+ 400
65
+ );
66
+ }
67
+
68
+ const raw = response.data ?? [];
69
+ return raw.map((item) => IaCreditAddBatchSchema.parse(item));
70
+ }
71
+ }
72
+
73
+ export const iaCreditsService = new IaCreditsService();
@@ -1,5 +1,11 @@
1
1
  import z from 'zod';
2
2
 
3
+ // has_expired pode vir null (ou ausente) da API — normaliza para boolean.
4
+ const hasExpiredSchema = z
5
+ .boolean()
6
+ .nullish()
7
+ .transform((v) => v ?? false);
8
+
3
9
  export const IaCreditOperationSchema = z
4
10
  .object({
5
11
  id: z.union([z.number(), z.string()]),
@@ -15,7 +21,7 @@ export const IaCreditOperationSchema = z
15
21
  operation_ref: z.string().nullable().optional(),
16
22
  operation_origin: z.string().nullable().optional(),
17
23
  expiration_time: z.string().nullable(),
18
- has_expired: z.boolean(),
24
+ has_expired: hasExpiredSchema,
19
25
  consumed_from_add_id: z.union([z.number(), z.string()]).nullable(),
20
26
  id_user_add: z.union([z.number(), z.string()]).nullable(),
21
27
  user_name: z.string().nullable().optional(),
@@ -24,6 +30,29 @@ export const IaCreditOperationSchema = z
24
30
 
25
31
  export type IaCreditOperation = z.infer<typeof IaCreditOperationSchema>;
26
32
 
33
+ // Lote de créditos adicionados — agregado pelo backend em
34
+ // /items/balance/list/add (added/consumed/remaining já calculados).
35
+ export const IaCreditAddBatchSchema = z
36
+ .object({
37
+ id: z.union([z.number(), z.string()]),
38
+ added_credits: z.coerce.number(),
39
+ consumed_credits: z.coerce.number(),
40
+ remaining_credits: z.coerce.number(),
41
+ datetime_add: z.string().nullable(),
42
+ expiration_time: z.string().nullable(),
43
+ has_expired: hasExpiredSchema,
44
+ })
45
+ .passthrough();
46
+
47
+ export type IaCreditAddBatch = z.infer<typeof IaCreditAddBatchSchema>;
48
+
49
+ // Payload servido pelo route handler: saldo atual (balance_after_operation)
50
+ // + lotes de adição, de onde o hook deriva o restante do sumário.
51
+ export type IaCreditsSummaryData = {
52
+ availableCredits: number;
53
+ addBatches: IaCreditAddBatch[];
54
+ };
55
+
27
56
  export type IaCreditsSummary = {
28
57
  totalCredits: number;
29
58
  usedCredits: number;
@@ -1,7 +1,6 @@
1
- // Fixed identity and endpoints used across the test infra. Single source of truth: the same
2
- // object feeds DUMMY_AUTH_TOKEN (via createTestJwt), the factories and the request handlers, and
3
- // consumer apps must mirror it in their test env (GAPPS_R3_API_URL etc.) so the URL the ApiClient
4
- // builds matches the one the handlers expect.
1
+ // Single source of truth shared by the JWT, factories and request handlers. Apps must mirror it
2
+ // in their test env (GAPPS_R3_API_URL etc.) so the URL the ApiClient builds matches the handlers.
3
+ // `.test` domains never resolve, so a leaked unhandled request fails loudly.
5
4
  export const TEST_IDS = {
6
5
  wl: 1,
7
6
  account: 123,
@@ -9,13 +8,6 @@ export const TEST_IDS = {
9
8
  page: 789,
10
9
  } as const;
11
10
 
12
- // Bases the apps MUST export as test env:
13
- // GAPPS_R3_API_URL = TEST_API.gapps
14
- // GPAGES_R3_API_URL = TEST_API.gpages
15
- // WHITELABEL_TOKEN_MASTER = TEST_API.masterToken
16
- // WHITELABEL_DOMAIN = TEST_API.domain
17
- // `.test` domains never resolve on the real network, so a leaked unhandled request fails loudly
18
- // instead of hitting a real backend.
19
11
  export const TEST_API = {
20
12
  gapps: 'https://gapps.test',
21
13
  gpages: 'https://gpages.test',
@@ -23,6 +15,5 @@ export const TEST_API = {
23
15
  domain: 'app.test',
24
16
  } as const;
25
17
 
26
- // Fixed locale and version the ApiClient uses to build the URL (`/v1/pt-br/{wl}`).
27
18
  export const TEST_API_VERSION = 'v1';
28
19
  export const TEST_API_LOCALE = 'pt-br';
@@ -1,14 +1,10 @@
1
1
  type Factory<T, O> = (overrides?: O) => T;
2
2
 
3
- // Reset registry for the cached defaults. Runner-agnostic on purpose: these factories also run
4
- // under `next dev` (E2E request handlers) where vitest's `beforeEach` does not exist, so the app
5
- // calls `resetMocks()` from its own `beforeEach`.
6
3
  const resetters = new Set<() => void>();
7
4
 
8
- // createMock(factory) returns a getter that:
9
- // - without overrides returns the SAME default instance within a test (stable for asserts);
10
- // - with overrides returns a NEW instance with those fields replaced.
11
- // Between tests, `resetMocks()` refreshes the defaults.
5
+ // Without overrides, returns the same cached default within a test (stable for asserts); with
6
+ // overrides, a fresh instance. `resetMocks()` refreshes the defaults between tests runner-agnostic
7
+ // (these factories also run under `next dev` for E2E, where vitest's `beforeEach` is absent).
12
8
  export function createMock<T, O = Partial<T>>(factory: Factory<T, O>): Factory<T, O> {
13
9
  let instance = factory();
14
10
  resetters.add(() => {
@@ -17,7 +13,6 @@ export function createMock<T, O = Partial<T>>(factory: Factory<T, O>): Factory<T
17
13
  return (overrides?: O): T => (overrides ? factory(overrides) : instance);
18
14
  }
19
15
 
20
- // Refreshes every default cached by createMock. Call it from the setup's beforeEach.
21
16
  export function resetMocks(): void {
22
17
  for (const reset of resetters) reset();
23
18
  }
@@ -3,7 +3,6 @@ import { Subscription, SubscriptionItem } from '../../modules/subscriptions/type
3
3
  import { TEST_IDS } from '../constants';
4
4
  import { createMock } from './create-mock';
5
5
 
6
- // Dates are Date objects (the inferred output of the schema).
7
6
  export const createSubscriptionItemMock = createMock<SubscriptionItem, Partial<SubscriptionItem>>(
8
7
  (overrides) => ({
9
8
  id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),
@@ -21,7 +20,7 @@ export const createSubscriptionItemMock = createMock<SubscriptionItem, Partial<S
21
20
  }),
22
21
  );
23
22
 
24
- // Default: an active subscription with a future due date (a valid trial).
23
+ // Default: active with a future due date (a valid trial).
25
24
  export const createSubscriptionMock = createMock<Subscription, Partial<Subscription>>(
26
25
  (overrides) => ({
27
26
  id: overrides?.id ?? faker.number.int({ min: 1, max: 99999 }),
@@ -1,11 +1,7 @@
1
- // Shared test infra for the GreatApps apps. Imported as `@greatapps/common/testing`.
2
- //
3
- // This barrel is LIGHT and safe for node/E2E/handlers: only deterministic factories and session
4
- // request handlers. The React PROVIDERS (which pull the lib's client tree) live in a separate
5
- // subpath — `@greatapps/common/testing/react` — so the barrel and its load-time side effects
6
- // (e.g. zustand stores reading localStorage) don't leak into reducer/route-handler tests.
7
- //
8
- // `msw` and `@faker-js/faker` are OPTIONAL peer dependencies: only the files here import them.
1
+ // `@greatapps/common/testing` light, node/E2E-safe (factories + session handlers only). The
2
+ // React providers live in `@greatapps/common/testing/react` so the client barrel and its
3
+ // load-time side effects (e.g. zustand stores reading localStorage) don't leak into
4
+ // reducer/route-handler tests. `msw` and `@faker-js/faker` are optional peer dependencies.
9
5
  export { TEST_IDS, TEST_API, TEST_API_VERSION, TEST_API_LOCALE } from './constants';
10
6
  export * from './factories';
11
7
  export * from './msw';
@@ -1,23 +1,19 @@
1
1
  import { HttpResponse } from 'msw';
2
2
 
3
3
  // The envelope GreatApps backends return. Services read `data` as an array and take `data[0]` on
4
- // finds (see the user/account/whitelabel/pages services), so the success default is a list. Use
5
- // `apiOne` when the consumer expects `data` to be a single object.
4
+ // finds, so the success default is a list; use `apiOne` for the few endpoints returning an object.
6
5
  export function apiList<T>(items: T[], total = items.length) {
7
6
  return HttpResponse.json({ status: 1, data: items, total });
8
7
  }
9
8
 
10
- // Success with a single item wrapped in a list (`{ status:1, data:[item], total:1 }`).
11
9
  export function apiFind<T>(item: T) {
12
10
  return apiList([item], 1);
13
11
  }
14
12
 
15
- // Success with `data` as a single object (few endpoints; most use a list).
16
13
  export function apiOne<T>(data: T) {
17
14
  return HttpResponse.json({ status: 1, data });
18
15
  }
19
16
 
20
- // Backend-shaped error (`{ status:0, message }`) with an HTTP status.
21
17
  export function apiError(message = 'test error', status = 400) {
22
18
  return HttpResponse.json({ status: 0, message }, { status });
23
19
  }
@@ -9,19 +9,15 @@ import { createWhitelabelTokenMock } from '../factories/whitelabel.factory';
9
9
  import { apiFind } from './envelope';
10
10
 
11
11
  export interface SessionHandlersOptions {
12
- // gapps base (= GAPPS_R3_API_URL). Defaults to TEST_API.gapps.
13
12
  gappsBase?: string;
14
13
  user?: User;
15
14
  account?: Account;
16
15
  whitelabel?: WhitelabelTokenData;
17
16
  }
18
17
 
19
- // Handlers for the server-side session resolution any app triggers when booting an authenticated
20
- // route (with DUMMY_AUTH_TOKEN): whitelabel by domain, token by wl id, user and account. These are
21
- // what the layout prefetches and what the ApiClient needs to build the URL/header. Apps compose
22
- // them with their own handlers:
23
- // setupServer(...makeSessionHandlers(), ...myPageHandlers)
24
- // Paths follow the ApiClient template: `{base}/v1/{locale}/{wl}{endpoint}`.
18
+ // Server-side session resolution any app triggers when booting an authenticated route with
19
+ // DUMMY_AUTH_TOKEN (whitelabel by domain, token by wl id, user, account). Compose with app
20
+ // handlers: setupServer(...makeSessionHandlers(), ...myPageHandlers).
25
21
  export function makeSessionHandlers(opts: SessionHandlersOptions = {}) {
26
22
  const base = opts.gappsBase ?? TEST_API.gapps;
27
23
  const user = opts.user ?? createUserMock();
@@ -1,9 +1,6 @@
1
1
  import { QueryClient } from '@tanstack/react-query';
2
2
 
3
- /**
4
- * QueryClient para testes: sem retry (erros aparecem na hora), sem cache entre testes
5
- * (`gcTime: 0`) e sem refetch por foco. Crie um por teste pra isolamento total.
6
- */
3
+ // retry off (errors surface immediately) and gcTime 0 (no cache across tests). Create one per test.
7
4
  export function makeTestQueryClient(): QueryClient {
8
5
  return new QueryClient({
9
6
  defaultOptions: {