@greatapps/common 1.1.779 → 1.1.780

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.
@@ -7,7 +7,9 @@ import { useRouter } from "next/navigation";
7
7
  import { toast } from "sonner";
8
8
  import { IconLock } from "@tabler/icons-react";
9
9
  import { cn } from "../../../infra/utils/clsx";
10
+ import { isLocale } from "../../../i18n/config";
10
11
  import { setLocaleCookie } from "../../../utils/intl/locale-cookie";
12
+ import { localeToApiLanguage } from "../../../utils/intl/locales";
11
13
  import { Button } from "../../ui/buttons/Button";
12
14
  import { Separator } from "../../ui/data-display/Separator";
13
15
  import { Toast } from "../../ui/feedback/Toast";
@@ -86,7 +88,7 @@ function PreferencesSection({ onClose }) {
86
88
  const doSave = async (data, accountFields) => {
87
89
  setIsSaving(true);
88
90
  try {
89
- const apiLanguage = LANGUAGE_OPTIONS.find((o) => o.value === data.language)?.apiValue ?? data.language.toLowerCase();
91
+ const apiLanguage = isLocale(data.language) ? localeToApiLanguage(data.language) : data.language.toLowerCase();
90
92
  await updateAccountUser.mutateAsync({
91
93
  language: apiLanguage,
92
94
  receive_sms: data.receive_sms,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/account/sections/PreferencesSection.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslations, useLocale } from 'next-intl';\nimport { useRouter } from 'next/navigation';\nimport { toast } from 'sonner';\nimport { IconLock } from '@tabler/icons-react';\nimport { cn } from '../../../infra/utils/clsx';\nimport type { Locale } from '../../../i18n/config';\nimport { setLocaleCookie } from '../../../utils/intl/locale-cookie';\nimport { Button } from '../../ui/buttons/Button';\nimport { Separator } from '../../ui/data-display/Separator';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { FormField } from '../../ui/form/FormField';\nimport { ComboboxField } from '../../ui/form/ComboboxField';\nimport { SelectField } from '../../ui/form/SelectField';\nimport ConfirmGlobalPreferencesModal from '../ConfirmGlobalPreferencesModal';\nimport { useAuth } from '../../../providers/auth.provider';\nimport { useWhitelabel } from '../../../providers/whitelabel.provider';\nimport { UserProfile } from '../../../modules/users/schema';\nimport type { UpdateAccountRequest } from '../../../modules/accounts/types';\nimport {\n useUpdateAccountUser,\n useUpdateAccount,\n} from '../../../modules/accounts/hooks/useAccountManagement';\nimport {\n LANGUAGE_OPTIONS,\n TIME_FORMAT_OPTIONS,\n} from '../constants';\nimport { useTimezones } from '../../../modules/accounts/hooks/useTimezones';\nimport { useCurrencies } from '../../../modules/accounts/hooks/useCurrencies';\nimport { getCurrencyForGateway } from '../../../utils/format/currency';\n\ninterface PreferencesFormValues {\n companyName: string;\n language: string;\n currency: string;\n timezone: string;\n timeFormat: string;\n receive_sms: boolean;\n receive_email: boolean;\n}\n\ninterface PreferencesSectionProps {\n onClose: () => void;\n}\n\nexport function PreferencesSection({ onClose }: PreferencesSectionProps) {\n // Padrão raiz: um único `translate` chamado pela chave inteira (`common.<modulo>.<chave>`).\n const translate = useTranslations();\n // Exceção: chave dinâmica (option.value) numa lista → namespace escopado.\n const translateLanguage = useTranslations('common.languages');\n const currentLocale = useLocale();\n const router = useRouter();\n const { data: timezones = [] } = useTimezones();\n const { data: currencies = [] } = useCurrencies();\n const { user, account } = useAuth();\n const { whitelabel } = useWhitelabel();\n const languageOptions = LANGUAGE_OPTIONS.map((option) => ({\n ...option,\n label: translateLanguage(option.value as Locale),\n displayValue: translateLanguage(option.value as Locale),\n }));\n const timeFormatOptions = TIME_FORMAT_OPTIONS.map((option) => ({\n ...option,\n label: translate(\n `common.preferences.timeFormatOptions.${option.value === '24h' ? 'h24' : 'h12'}`,\n ),\n }));\n const isOwner = user?.profile === UserProfile.owner;\n const canEditPreferences = isOwner || user?.profile === UserProfile.admin;\n const updateAccountUser = useUpdateAccountUser();\n const updateAccount = useUpdateAccount();\n const [confirmGlobalOpen, setConfirmGlobalOpen] = useState(false);\n const [pendingSubmit, setPendingSubmit] = useState<{\n data: PreferencesFormValues;\n accountFields: UpdateAccountRequest;\n } | null>(null);\n const [isSaving, setIsSaving] = useState(false);\n\n const { watch, setValue, handleSubmit, reset, formState: { dirtyFields } } =\n useForm<PreferencesFormValues>({\n defaultValues: {\n companyName: '',\n language: '',\n currency: '',\n timezone: '',\n timeFormat: '24h',\n receive_sms: false,\n receive_email: false,\n },\n });\n\n useEffect(() => {\n if (!user || !account) return;\n reset({\n companyName: account.name ?? '',\n language: LANGUAGE_OPTIONS.find(\n (o) => o.apiValue === user.language?.toLowerCase()\n )?.value ?? 'pt-br',\n // A moeda é derivada do gateway da conta (read-only para o usuário) —\n // espelha o que useCurrencyFormatter usa no display de preços.\n currency: getCurrencyForGateway(account.gateway).toUpperCase(),\n timezone: account.timezone,\n timeFormat: '24h',\n receive_sms: user.receive_sms ?? false,\n receive_email: user.receive_email ?? false,\n });\n }, [user, account, reset]);\n\n const doSave = async (data: PreferencesFormValues, accountFields: UpdateAccountRequest) => {\n setIsSaving(true);\n try {\n const apiLanguage = LANGUAGE_OPTIONS.find((o) => o.value === data.language)?.apiValue ?? data.language.toLowerCase();\n await updateAccountUser.mutateAsync({\n language: apiLanguage,\n receive_sms: data.receive_sms,\n receive_email: data.receive_email,\n });\n\n if (canEditPreferences && Object.keys(accountFields).length > 0) {\n await updateAccount.mutateAsync(accountFields);\n }\n\n reset(data);\n toast.custom((toastId) => (\n <Toast variant=\"success\" message={translate('common.preferences.savedSuccess')} toastId={toastId} />\n ));\n onClose();\n if (data.language !== currentLocale) {\n setLocaleCookie(data.language, whitelabel?.domain);\n router.refresh();\n }\n } catch (error) {\n toast.custom((toastId) => (\n <Toast\n variant=\"error\"\n message={error instanceof Error ? error.message : translate('common.preferences.saveError')}\n toastId={toastId}\n />\n ));\n } finally {\n setIsSaving(false);\n }\n };\n\n const onSubmit = (data: PreferencesFormValues) => {\n const accountFields: UpdateAccountRequest = {\n ...(isOwner && dirtyFields.companyName && { name: data.companyName }),\n // currency é read-only (derivada do gateway) — não enviada no update.\n ...(canEditPreferences && dirtyFields.timezone && { timezone: data.timezone }),\n };\n const globalFieldChanged = Object.keys(accountFields).length > 0;\n\n if (globalFieldChanged) {\n setPendingSubmit({ data, accountFields });\n setConfirmGlobalOpen(true);\n } else {\n doSave(data, accountFields);\n }\n };\n\n const handleConfirmGlobal = () => {\n setConfirmGlobalOpen(false);\n if (pendingSubmit) {\n doSave(pendingSubmit.data, pendingSubmit.accountFields);\n setPendingSubmit(null);\n }\n };\n\n const handleCancelGlobal = () => {\n setConfirmGlobalOpen(false);\n setPendingSubmit(null);\n };\n\n return (\n <>\n <form onSubmit={handleSubmit(onSubmit)} className=\"flex flex-col h-full\">\n <div className=\"overflow-y-auto overscroll-contain px-4 pb-4 lg:p-5 flex flex-col gap-5 lg:gap-6 flex-1\">\n <span className=\"paragraph-medium-semibold text-gray-950\">{translate('common.preferences.title')}</span>\n <div className=\"flex flex-col gap-8\">\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <FormField\n label={translate('common.preferences.companyName')}\n placeholder={translate('common.preferences.companyNamePlaceholder')}\n classnameContainer={cn('w-full', !isOwner && 'cursor-not-allowed opacity-50')}\n value={watch('companyName')}\n onChange={(e) => setValue('companyName', e.target.value, { shouldDirty: true })}\n disabled={!isOwner}\n />\n </div>\n\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <ComboboxField\n label={translate('common.preferences.language')}\n placeholder={translate('common.preferences.languagePlaceholder')}\n searchPlaceholder={translate('common.preferences.languageSearch')}\n containerClassName=\"w-full\"\n options={languageOptions}\n value={watch('language')}\n onChange={(value) => setValue('language', value, { shouldDirty: true })}\n />\n <ComboboxField\n label={translate('common.preferences.currency')}\n placeholder={translate('common.preferences.currencyPlaceholder')}\n searchPlaceholder={translate('common.preferences.currencySearch')}\n containerClassName=\"w-full\"\n options={currencies}\n value={watch('currency')}\n onChange={() => undefined}\n icon={<IconLock className=\"size-4 text-gray-400\" />}\n disabled\n />\n </div>\n\n <Separator />\n\n <div className=\"flex flex-col gap-4\">\n <span className=\"paragraph-medium-semibold text-gray-950\">{translate('common.preferences.timeDisplay')}</span>\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <ComboboxField\n label={translate('common.preferences.timezone')}\n placeholder={translate('common.preferences.timezonePlaceholder')}\n searchPlaceholder={translate('common.preferences.timezoneSearch')}\n containerClassName=\"w-full\"\n options={timezones}\n value={watch('timezone')}\n onChange={(value) => setValue('timezone', value, { shouldDirty: true })}\n icon={!canEditPreferences ? <IconLock className=\"size-4 text-gray-400\" /> : undefined}\n disabled={!canEditPreferences}\n />\n <SelectField\n label={translate('common.preferences.timeFormat')}\n placeholder={translate('common.preferences.timeFormatPlaceholder')}\n className=\"h-10!\"\n containerClassName=\"w-full\"\n options={timeFormatOptions}\n value={watch('timeFormat')}\n onChange={(value) =>\n setValue('timeFormat', value as string, { shouldDirty: true })\n }\n icon={<IconLock className=\"size-4 text-gray-400\" />}\n disabled\n />\n </div>\n </div>\n\n </div>\n </div>\n\n <div className=\"fixed bottom-0 left-0 right-0 lg:absolute flex items-center h-20 px-4 lg:px-5 border-t border-gray-200 justify-between bg-white z-10\">\n <Button\n variant=\"secondary\"\n className=\"h-10!\"\n type=\"button\"\n disabled={isSaving}\n onClick={() => {\n reset();\n onClose();\n }}\n >\n {translate('common.actions.cancel')}\n </Button>\n <Button className=\"h-10!\" type=\"submit\" disabled={isSaving}>\n {isSaving ? translate('common.actions.saving') : translate('common.actions.saveChanges')}\n </Button>\n </div>\n </form>\n\n <ConfirmGlobalPreferencesModal\n open={confirmGlobalOpen}\n onConfirm={handleConfirmGlobal}\n onCancel={handleCancelGlobal}\n />\n </>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/components/account/sections/PreferencesSection.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslations, useLocale } from 'next-intl';\nimport { useRouter } from 'next/navigation';\nimport { toast } from 'sonner';\nimport { IconLock } from '@tabler/icons-react';\nimport { cn } from '../../../infra/utils/clsx';\nimport { isLocale, type Locale } from '../../../i18n/config';\nimport { setLocaleCookie } from '../../../utils/intl/locale-cookie';\nimport { localeToApiLanguage } from '../../../utils/intl/locales';\nimport { Button } from '../../ui/buttons/Button';\nimport { Separator } from '../../ui/data-display/Separator';\nimport { Toast } from '../../ui/feedback/Toast';\nimport { FormField } from '../../ui/form/FormField';\nimport { ComboboxField } from '../../ui/form/ComboboxField';\nimport { SelectField } from '../../ui/form/SelectField';\nimport ConfirmGlobalPreferencesModal from '../ConfirmGlobalPreferencesModal';\nimport { useAuth } from '../../../providers/auth.provider';\nimport { useWhitelabel } from '../../../providers/whitelabel.provider';\nimport { UserProfile } from '../../../modules/users/schema';\nimport type { UpdateAccountRequest } from '../../../modules/accounts/types';\nimport {\n useUpdateAccountUser,\n useUpdateAccount,\n} from '../../../modules/accounts/hooks/useAccountManagement';\nimport {\n LANGUAGE_OPTIONS,\n TIME_FORMAT_OPTIONS,\n} from '../constants';\nimport { useTimezones } from '../../../modules/accounts/hooks/useTimezones';\nimport { useCurrencies } from '../../../modules/accounts/hooks/useCurrencies';\nimport { getCurrencyForGateway } from '../../../utils/format/currency';\n\ninterface PreferencesFormValues {\n companyName: string;\n language: string;\n currency: string;\n timezone: string;\n timeFormat: string;\n receive_sms: boolean;\n receive_email: boolean;\n}\n\ninterface PreferencesSectionProps {\n onClose: () => void;\n}\n\nexport function PreferencesSection({ onClose }: PreferencesSectionProps) {\n // Padrão raiz: um único `translate` chamado pela chave inteira (`common.<modulo>.<chave>`).\n const translate = useTranslations();\n // Exceção: chave dinâmica (option.value) numa lista → namespace escopado.\n const translateLanguage = useTranslations('common.languages');\n const currentLocale = useLocale();\n const router = useRouter();\n const { data: timezones = [] } = useTimezones();\n const { data: currencies = [] } = useCurrencies();\n const { user, account } = useAuth();\n const { whitelabel } = useWhitelabel();\n const languageOptions = LANGUAGE_OPTIONS.map((option) => ({\n ...option,\n label: translateLanguage(option.value as Locale),\n displayValue: translateLanguage(option.value as Locale),\n }));\n const timeFormatOptions = TIME_FORMAT_OPTIONS.map((option) => ({\n ...option,\n label: translate(\n `common.preferences.timeFormatOptions.${option.value === '24h' ? 'h24' : 'h12'}`,\n ),\n }));\n const isOwner = user?.profile === UserProfile.owner;\n const canEditPreferences = isOwner || user?.profile === UserProfile.admin;\n const updateAccountUser = useUpdateAccountUser();\n const updateAccount = useUpdateAccount();\n const [confirmGlobalOpen, setConfirmGlobalOpen] = useState(false);\n const [pendingSubmit, setPendingSubmit] = useState<{\n data: PreferencesFormValues;\n accountFields: UpdateAccountRequest;\n } | null>(null);\n const [isSaving, setIsSaving] = useState(false);\n\n const { watch, setValue, handleSubmit, reset, formState: { dirtyFields } } =\n useForm<PreferencesFormValues>({\n defaultValues: {\n companyName: '',\n language: '',\n currency: '',\n timezone: '',\n timeFormat: '24h',\n receive_sms: false,\n receive_email: false,\n },\n });\n\n useEffect(() => {\n if (!user || !account) return;\n reset({\n companyName: account.name ?? '',\n language: LANGUAGE_OPTIONS.find(\n (o) => o.apiValue === user.language?.toLowerCase()\n )?.value ?? 'pt-br',\n // A moeda é derivada do gateway da conta (read-only para o usuário) —\n // espelha o que useCurrencyFormatter usa no display de preços.\n currency: getCurrencyForGateway(account.gateway).toUpperCase(),\n timezone: account.timezone,\n timeFormat: '24h',\n receive_sms: user.receive_sms ?? false,\n receive_email: user.receive_email ?? false,\n });\n }, [user, account, reset]);\n\n const doSave = async (data: PreferencesFormValues, accountFields: UpdateAccountRequest) => {\n setIsSaving(true);\n try {\n const apiLanguage = isLocale(data.language) ? localeToApiLanguage(data.language) : data.language.toLowerCase();\n await updateAccountUser.mutateAsync({\n language: apiLanguage,\n receive_sms: data.receive_sms,\n receive_email: data.receive_email,\n });\n\n if (canEditPreferences && Object.keys(accountFields).length > 0) {\n await updateAccount.mutateAsync(accountFields);\n }\n\n reset(data);\n toast.custom((toastId) => (\n <Toast variant=\"success\" message={translate('common.preferences.savedSuccess')} toastId={toastId} />\n ));\n onClose();\n if (data.language !== currentLocale) {\n setLocaleCookie(data.language, whitelabel?.domain);\n router.refresh();\n }\n } catch (error) {\n toast.custom((toastId) => (\n <Toast\n variant=\"error\"\n message={error instanceof Error ? error.message : translate('common.preferences.saveError')}\n toastId={toastId}\n />\n ));\n } finally {\n setIsSaving(false);\n }\n };\n\n const onSubmit = (data: PreferencesFormValues) => {\n const accountFields: UpdateAccountRequest = {\n ...(isOwner && dirtyFields.companyName && { name: data.companyName }),\n // currency é read-only (derivada do gateway) — não enviada no update.\n ...(canEditPreferences && dirtyFields.timezone && { timezone: data.timezone }),\n };\n const globalFieldChanged = Object.keys(accountFields).length > 0;\n\n if (globalFieldChanged) {\n setPendingSubmit({ data, accountFields });\n setConfirmGlobalOpen(true);\n } else {\n doSave(data, accountFields);\n }\n };\n\n const handleConfirmGlobal = () => {\n setConfirmGlobalOpen(false);\n if (pendingSubmit) {\n doSave(pendingSubmit.data, pendingSubmit.accountFields);\n setPendingSubmit(null);\n }\n };\n\n const handleCancelGlobal = () => {\n setConfirmGlobalOpen(false);\n setPendingSubmit(null);\n };\n\n return (\n <>\n <form onSubmit={handleSubmit(onSubmit)} className=\"flex flex-col h-full\">\n <div className=\"overflow-y-auto overscroll-contain px-4 pb-4 lg:p-5 flex flex-col gap-5 lg:gap-6 flex-1\">\n <span className=\"paragraph-medium-semibold text-gray-950\">{translate('common.preferences.title')}</span>\n <div className=\"flex flex-col gap-8\">\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <FormField\n label={translate('common.preferences.companyName')}\n placeholder={translate('common.preferences.companyNamePlaceholder')}\n classnameContainer={cn('w-full', !isOwner && 'cursor-not-allowed opacity-50')}\n value={watch('companyName')}\n onChange={(e) => setValue('companyName', e.target.value, { shouldDirty: true })}\n disabled={!isOwner}\n />\n </div>\n\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <ComboboxField\n label={translate('common.preferences.language')}\n placeholder={translate('common.preferences.languagePlaceholder')}\n searchPlaceholder={translate('common.preferences.languageSearch')}\n containerClassName=\"w-full\"\n options={languageOptions}\n value={watch('language')}\n onChange={(value) => setValue('language', value, { shouldDirty: true })}\n />\n <ComboboxField\n label={translate('common.preferences.currency')}\n placeholder={translate('common.preferences.currencyPlaceholder')}\n searchPlaceholder={translate('common.preferences.currencySearch')}\n containerClassName=\"w-full\"\n options={currencies}\n value={watch('currency')}\n onChange={() => undefined}\n icon={<IconLock className=\"size-4 text-gray-400\" />}\n disabled\n />\n </div>\n\n <Separator />\n\n <div className=\"flex flex-col gap-4\">\n <span className=\"paragraph-medium-semibold text-gray-950\">{translate('common.preferences.timeDisplay')}</span>\n <div className=\"flex flex-col lg:flex-row items-center gap-3\">\n <ComboboxField\n label={translate('common.preferences.timezone')}\n placeholder={translate('common.preferences.timezonePlaceholder')}\n searchPlaceholder={translate('common.preferences.timezoneSearch')}\n containerClassName=\"w-full\"\n options={timezones}\n value={watch('timezone')}\n onChange={(value) => setValue('timezone', value, { shouldDirty: true })}\n icon={!canEditPreferences ? <IconLock className=\"size-4 text-gray-400\" /> : undefined}\n disabled={!canEditPreferences}\n />\n <SelectField\n label={translate('common.preferences.timeFormat')}\n placeholder={translate('common.preferences.timeFormatPlaceholder')}\n className=\"h-10!\"\n containerClassName=\"w-full\"\n options={timeFormatOptions}\n value={watch('timeFormat')}\n onChange={(value) =>\n setValue('timeFormat', value as string, { shouldDirty: true })\n }\n icon={<IconLock className=\"size-4 text-gray-400\" />}\n disabled\n />\n </div>\n </div>\n\n </div>\n </div>\n\n <div className=\"fixed bottom-0 left-0 right-0 lg:absolute flex items-center h-20 px-4 lg:px-5 border-t border-gray-200 justify-between bg-white z-10\">\n <Button\n variant=\"secondary\"\n className=\"h-10!\"\n type=\"button\"\n disabled={isSaving}\n onClick={() => {\n reset();\n onClose();\n }}\n >\n {translate('common.actions.cancel')}\n </Button>\n <Button className=\"h-10!\" type=\"submit\" disabled={isSaving}>\n {isSaving ? translate('common.actions.saving') : translate('common.actions.saveChanges')}\n </Button>\n </div>\n </form>\n\n <ConfirmGlobalPreferencesModal\n open={confirmGlobalOpen}\n onConfirm={handleConfirmGlobal}\n onCancel={handleCancelGlobal}\n />\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ function useDomMutationGuardHit(onHit) {
4
+ const onHitRef = useRef(onHit);
5
+ onHitRef.current = onHit;
6
+ useEffect(() => {
7
+ let reported = false;
8
+ const report = (kind) => {
9
+ if (reported) return;
10
+ reported = true;
11
+ window.__gpDomGuardOnHit = null;
12
+ onHitRef.current({
13
+ kind,
14
+ language: navigator.language,
15
+ languages: navigator.languages?.join(",") ?? "",
16
+ documentLang: document.documentElement.lang,
17
+ // <font> sem classe é a assinatura do Google Tradutor
18
+ translatedNodes: document.querySelectorAll("font[style]").length,
19
+ path: window.location.pathname
20
+ });
21
+ };
22
+ const already = window.__gpDomGuard;
23
+ if (already && (already.removeChild > 0 || already.insertBefore > 0)) {
24
+ report(already.insertBefore > 0 ? "insertBefore" : "removeChild");
25
+ return;
26
+ }
27
+ window.__gpDomGuardOnHit = report;
28
+ return () => {
29
+ window.__gpDomGuardOnHit = null;
30
+ };
31
+ }, []);
32
+ }
33
+ export {
34
+ useDomMutationGuardHit
35
+ };
36
+ //# sourceMappingURL=useDomMutationGuardHit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/hooks/useDomMutationGuardHit.ts"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\n\nexport type DomMutationGuardHit = {\n kind: 'removeChild' | 'insertBefore';\n language: string;\n languages: string;\n documentLang: string;\n translatedNodes: number;\n path: string;\n}\n\n/**\n * Reporta quando a guarda de mutação de DOM (`DOM_MUTATION_GUARD_SCRIPT`) entra em ação.\n *\n * Sem isso a correção fica cega: o app para de cair, mas ninguém descobre quantos clientes estão\n * navegando com o tradutor do navegador ligado. Reporta UMA vez por sessão — o objetivo é medir\n * quantas sessões são afetadas, não quantas operações de DOM foram salvas.\n */\nexport function useDomMutationGuardHit(onHit: (hit: DomMutationGuardHit) => void): void {\n const onHitRef = useRef(onHit);\n onHitRef.current = onHit;\n\n useEffect(() => {\n let reported = false;\n\n const report = (kind: 'removeChild' | 'insertBefore') => {\n if (reported) return;\n reported = true;\n window.__gpDomGuardOnHit = null;\n onHitRef.current({\n kind,\n language: navigator.language,\n languages: navigator.languages?.join(',') ?? '',\n documentLang: document.documentElement.lang,\n // <font> sem classe é a assinatura do Google Tradutor\n translatedNodes: document.querySelectorAll('font[style]').length,\n path: window.location.pathname,\n });\n };\n\n // Disparos que aconteceram antes deste componente montar.\n const already = window.__gpDomGuard;\n if (already && (already.removeChild > 0 || already.insertBefore > 0)) {\n report(already.insertBefore > 0 ? 'insertBefore' : 'removeChild');\n return;\n }\n\n window.__gpDomGuardOnHit = report;\n return () => {\n window.__gpDomGuardOnHit = null;\n };\n }, []);\n}\n"],"mappings":";AAEA,SAAS,WAAW,cAAc;AAkB3B,SAAS,uBAAuB,OAAiD;AACtF,QAAM,WAAW,OAAO,KAAK;AAC7B,WAAS,UAAU;AAEnB,YAAU,MAAM;AACd,QAAI,WAAW;AAEf,UAAM,SAAS,CAAC,SAAyC;AACvD,UAAI,SAAU;AACd,iBAAW;AACX,aAAO,oBAAoB;AAC3B,eAAS,QAAQ;AAAA,QACf;AAAA,QACA,UAAU,UAAU;AAAA,QACpB,WAAW,UAAU,WAAW,KAAK,GAAG,KAAK;AAAA,QAC7C,cAAc,SAAS,gBAAgB;AAAA;AAAA,QAEvC,iBAAiB,SAAS,iBAAiB,aAAa,EAAE;AAAA,QAC1D,MAAM,OAAO,SAAS;AAAA,MACxB,CAAC;AAAA,IACH;AAGA,UAAM,UAAU,OAAO;AACvB,QAAI,YAAY,QAAQ,cAAc,KAAK,QAAQ,eAAe,IAAI;AACpE,aAAO,QAAQ,eAAe,IAAI,iBAAiB,aAAa;AAChE;AAAA,IACF;AAEA,WAAO,oBAAoB;AAC3B,WAAO,MAAM;AACX,aAAO,oBAAoB;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,CAAC;AACP;","names":[]}
@@ -19,6 +19,14 @@ function decodeJwtLocaleInfo(token) {
19
19
  return null;
20
20
  }
21
21
  }
22
+ function localeFromAcceptLanguage(header) {
23
+ if (!header) return null;
24
+ for (const entry of header.split(",")) {
25
+ const locale = normalizeLocale(entry.split(";")[0].trim());
26
+ if (locale) return locale;
27
+ }
28
+ return null;
29
+ }
22
30
  async function resolveLocale(options = {}) {
23
31
  const cookieStore = await cookies();
24
32
  const token = process.env.DUMMY_AUTH_TOKEN || cookieStore.get(AUTH_COOKIE)?.value;
@@ -32,6 +40,8 @@ async function resolveLocale(options = {}) {
32
40
  const fromCookie = normalizeLocale(cookieStore.get(LOCALE_COOKIE)?.value);
33
41
  if (fromCookie) return fromCookie;
34
42
  const headersList = await headers();
43
+ const fromAcceptLanguage = localeFromAcceptLanguage(headersList.get("accept-language"));
44
+ if (fromAcceptLanguage) return fromAcceptLanguage;
35
45
  const country = jwt?.country ?? headersList.get(GEO_HEADER);
36
46
  const fromGeo = localeFromCountry(country);
37
47
  if (fromGeo) return fromGeo;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/i18n/resolve-locale.ts"],"sourcesContent":["import 'server-only';\n\nimport { cookies, headers } from 'next/headers';\nimport { DEFAULT_LOCALE, Locale, LOCALE_COOKIE } from './config';\nimport { localeFromCountry } from './country-language';\nimport { normalizeLocale } from './normalize';\nimport { decodeJwtPayload } from '../utils/jwt-payload';\n\nconst AUTH_COOKIE = 'greatapps';\nconst GEO_HEADER = 'cf-ipcountry';\nconst DEFAULT_WHITELABEL_ID = 1;\n\ninterface JwtLocaleInfo {\n id_wl?: number;\n country?: string | null;\n}\n\n/** Lê id_wl e país do JWT sem custo de rede (best-effort). */\nfunction decodeJwtLocaleInfo(token?: string | null): JwtLocaleInfo | null {\n if (!token) return null;\n try {\n const payload = decodeJwtPayload<{ id_wl?: number | string; session?: { location?: { country?: string | null } } }>(token);\n return {\n id_wl: payload?.id_wl != null ? Number(payload.id_wl) : undefined,\n country: payload?.session?.location?.country ?? null,\n };\n } catch {\n return null;\n }\n}\n\nexport interface ResolveLocaleOptions {\n /**\n * Whitelabel id já resolvido (ex.: via `findWhitelabel()`), com prioridade sobre o JWT.\n * Permite detectar domínio whitelabel mesmo para visitante não-logado.\n */\n whitelabelId?: number | null;\n /** Idioma da conta (`user.language`), quando já conhecido pelo chamador. */\n userLanguage?: string | null;\n}\n\n/**\n * Resolve o locale da requisição (server-side). Ordem de prioridade:\n *\n * 1. **Whitelabel não-padrão** (`id_wl != 1`) → `pt` (por enquanto, whitelabels não são localizadas).\n * 2. **Preferência da conta** (`userLanguage`), quando fornecida.\n * 3. **Cookie `NEXT_LOCALE`** — cache da preferência ou escolha manual do visitante.\n * 4. **Inferência por país** — JWT (`session.location.country`) ou header `CF-IPCountry`.\n * 5. **Fallback** → {@link DEFAULT_LOCALE}.\n */\nexport async function resolveLocale(options: ResolveLocaleOptions = {}): Promise<Locale> {\n const cookieStore = await cookies();\n const token = process.env.DUMMY_AUTH_TOKEN || cookieStore.get(AUTH_COOKIE)?.value;\n const jwt = decodeJwtLocaleInfo(token);\n\n // 1. Whitelabel não-padrão → português\n const whitelabelId = options.whitelabelId ?? jwt?.id_wl ?? null;\n if (whitelabelId != null && whitelabelId !== DEFAULT_WHITELABEL_ID) {\n return 'pt-br';\n }\n\n // 2. Preferência explícita da conta\n const fromUser = normalizeLocale(options.userLanguage);\n if (fromUser) return fromUser;\n\n // 3. Cookie persistido\n const fromCookie = normalizeLocale(cookieStore.get(LOCALE_COOKIE)?.value);\n if (fromCookie) return fromCookie;\n\n // 4. Inferência por país (geo)\n const headersList = await headers();\n const country = jwt?.country ?? headersList.get(GEO_HEADER);\n const fromGeo = localeFromCountry(country);\n if (fromGeo) return fromGeo;\n\n // 5. Fallback\n return DEFAULT_LOCALE;\n}\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,SAAS,eAAe;AACjC,SAAS,gBAAwB,qBAAqB;AACtD,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AAEjC,MAAM,cAAc;AACpB,MAAM,aAAa;AACnB,MAAM,wBAAwB;AAQ9B,SAAS,oBAAoB,OAA6C;AACxE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,UAAU,iBAAoG,KAAK;AACzH,WAAO;AAAA,MACL,OAAO,SAAS,SAAS,OAAO,OAAO,QAAQ,KAAK,IAAI;AAAA,MACxD,SAAS,SAAS,SAAS,UAAU,WAAW;AAAA,IAClD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAqBA,eAAsB,cAAc,UAAgC,CAAC,GAAoB;AACvF,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,QAAQ,IAAI,oBAAoB,YAAY,IAAI,WAAW,GAAG;AAC5E,QAAM,MAAM,oBAAoB,KAAK;AAGrC,QAAM,eAAe,QAAQ,gBAAgB,KAAK,SAAS;AAC3D,MAAI,gBAAgB,QAAQ,iBAAiB,uBAAuB;AAClE,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,gBAAgB,QAAQ,YAAY;AACrD,MAAI,SAAU,QAAO;AAGrB,QAAM,aAAa,gBAAgB,YAAY,IAAI,aAAa,GAAG,KAAK;AACxE,MAAI,WAAY,QAAO;AAGvB,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,UAAU,KAAK,WAAW,YAAY,IAAI,UAAU;AAC1D,QAAM,UAAU,kBAAkB,OAAO;AACzC,MAAI,QAAS,QAAO;AAGpB,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/i18n/resolve-locale.ts"],"sourcesContent":["import 'server-only';\n\nimport { cookies, headers } from 'next/headers';\nimport { DEFAULT_LOCALE, Locale, LOCALE_COOKIE } from './config';\nimport { localeFromCountry } from './country-language';\nimport { normalizeLocale } from './normalize';\nimport { decodeJwtPayload } from '../utils/jwt-payload';\n\nconst AUTH_COOKIE = 'greatapps';\nconst GEO_HEADER = 'cf-ipcountry';\nconst DEFAULT_WHITELABEL_ID = 1;\n\ninterface JwtLocaleInfo {\n id_wl?: number;\n country?: string | null;\n}\n\n/** Lê id_wl e país do JWT sem custo de rede (best-effort). */\nfunction decodeJwtLocaleInfo(token?: string | null): JwtLocaleInfo | null {\n if (!token) return null;\n try {\n const payload = decodeJwtPayload<{ id_wl?: number | string; session?: { location?: { country?: string | null } } }>(token);\n return {\n id_wl: payload?.id_wl != null ? Number(payload.id_wl) : undefined,\n country: payload?.session?.location?.country ?? null,\n };\n } catch {\n return null;\n }\n}\n\nexport interface ResolveLocaleOptions {\n /**\n * Whitelabel id já resolvido (ex.: via `findWhitelabel()`), com prioridade sobre o JWT.\n * Permite detectar domínio whitelabel mesmo para visitante não-logado.\n */\n whitelabelId?: number | null;\n /** Idioma da conta (`user.language`), quando já conhecido pelo chamador. */\n userLanguage?: string | null;\n}\n\nfunction localeFromAcceptLanguage(header: string | null): Locale | null {\n if (!header) return null;\n for (const entry of header.split(',')) {\n const locale = normalizeLocale(entry.split(';')[0].trim());\n if (locale) return locale;\n }\n return null;\n}\n\n/**\n * Resolve o locale da requisição (server-side). Ordem de prioridade:\n *\n * 1. **Whitelabel não-padrão** (`id_wl != 1`) → `pt` (por enquanto, whitelabels não são localizadas).\n * 2. **Preferência da conta** (`userLanguage`), quando fornecida.\n * 3. **Cookie `NEXT_LOCALE`** — cache da preferência ou escolha manual do visitante.\n * 4. **Header `Accept-Language`** do navegador.\n * 5. **Inferência por país** — JWT (`session.location.country`) ou header `CF-IPCountry`.\n * 6. **Fallback** → {@link DEFAULT_LOCALE}.\n */\nexport async function resolveLocale(options: ResolveLocaleOptions = {}): Promise<Locale> {\n const cookieStore = await cookies();\n const token = process.env.DUMMY_AUTH_TOKEN || cookieStore.get(AUTH_COOKIE)?.value;\n const jwt = decodeJwtLocaleInfo(token);\n\n // 1. Whitelabel não-padrão → português\n const whitelabelId = options.whitelabelId ?? jwt?.id_wl ?? null;\n if (whitelabelId != null && whitelabelId !== DEFAULT_WHITELABEL_ID) {\n return 'pt-br';\n }\n\n // 2. Preferência explícita da conta\n const fromUser = normalizeLocale(options.userLanguage);\n if (fromUser) return fromUser;\n\n // 3. Cookie persistido\n const fromCookie = normalizeLocale(cookieStore.get(LOCALE_COOKIE)?.value);\n if (fromCookie) return fromCookie;\n\n const headersList = await headers();\n\n // 4. Header Accept-Language do navegador\n const fromAcceptLanguage = localeFromAcceptLanguage(headersList.get('accept-language'));\n if (fromAcceptLanguage) return fromAcceptLanguage;\n\n // 5. Inferência por país (geo)\n const country = jwt?.country ?? headersList.get(GEO_HEADER);\n const fromGeo = localeFromCountry(country);\n if (fromGeo) return fromGeo;\n\n // 6. Fallback\n return DEFAULT_LOCALE;\n}\n"],"mappings":"AAAA,OAAO;AAEP,SAAS,SAAS,eAAe;AACjC,SAAS,gBAAwB,qBAAqB;AACtD,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;AAEjC,MAAM,cAAc;AACpB,MAAM,aAAa;AACnB,MAAM,wBAAwB;AAQ9B,SAAS,oBAAoB,OAA6C;AACxE,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI;AACF,UAAM,UAAU,iBAAoG,KAAK;AACzH,WAAO;AAAA,MACL,OAAO,SAAS,SAAS,OAAO,OAAO,QAAQ,KAAK,IAAI;AAAA,MACxD,SAAS,SAAS,SAAS,UAAU,WAAW;AAAA,IAClD;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAYA,SAAS,yBAAyB,QAAsC;AACtE,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,SAAS,OAAO,MAAM,GAAG,GAAG;AACrC,UAAM,SAAS,gBAAgB,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC;AACzD,QAAI,OAAQ,QAAO;AAAA,EACrB;AACA,SAAO;AACT;AAYA,eAAsB,cAAc,UAAgC,CAAC,GAAoB;AACvF,QAAM,cAAc,MAAM,QAAQ;AAClC,QAAM,QAAQ,QAAQ,IAAI,oBAAoB,YAAY,IAAI,WAAW,GAAG;AAC5E,QAAM,MAAM,oBAAoB,KAAK;AAGrC,QAAM,eAAe,QAAQ,gBAAgB,KAAK,SAAS;AAC3D,MAAI,gBAAgB,QAAQ,iBAAiB,uBAAuB;AAClE,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,gBAAgB,QAAQ,YAAY;AACrD,MAAI,SAAU,QAAO;AAGrB,QAAM,aAAa,gBAAgB,YAAY,IAAI,aAAa,GAAG,KAAK;AACxE,MAAI,WAAY,QAAO;AAEvB,QAAM,cAAc,MAAM,QAAQ;AAGlC,QAAM,qBAAqB,yBAAyB,YAAY,IAAI,iBAAiB,CAAC;AACtF,MAAI,mBAAoB,QAAO;AAG/B,QAAM,UAAU,KAAK,WAAW,YAAY,IAAI,UAAU;AAC1D,QAAM,UAAU,kBAAkB,OAAO;AACzC,MAAI,QAAS,QAAO;AAGpB,SAAO;AACT;","names":[]}
package/dist/index.mjs CHANGED
@@ -380,6 +380,8 @@ import { default as default16 } from "./hooks/usePasswordVisibility";
380
380
  import { default as default17 } from "./hooks/useCountdownTimer";
381
381
  import { default as default18 } from "./hooks/useIsMobile";
382
382
  import { useDebounce } from "./hooks/useDebounce";
383
+ import { useDomMutationGuardHit } from "./hooks/useDomMutationGuardHit";
384
+ import { DOM_MUTATION_GUARD_SCRIPT } from "./utils/dom/dom-mutation-guard";
383
385
  import { useDebouncedEffect } from "./hooks/useDebouncedEffect";
384
386
  import { useDebounceState } from "./hooks/useDebounceState";
385
387
  import {
@@ -554,6 +556,7 @@ export {
554
556
  CreateCardRequestSchema,
555
557
  default4 as CreditsDisabledModal,
556
558
  CrispEmbed,
559
+ DOM_MUTATION_GUARD_SCRIPT,
557
560
  DatePicker,
558
561
  DateRangePicker,
559
562
  default15 as DefaultCircularProgress,
@@ -824,6 +827,7 @@ export {
824
827
  useDeleteProject,
825
828
  useDesktopSidebarStore,
826
829
  useDialogLayer,
830
+ useDomMutationGuardHit,
827
831
  useFreezeNotice,
828
832
  useHandleDeleteCard,
829
833
  useHasPlanAddon,
@@ -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 FREEZE_NOTICE_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 { useAccountFreeze } from \"./modules/subscriptions/hooks/use-account-freeze.hook\";\nexport { useFreezeNotice } from \"./modules/subscriptions/hooks/use-freeze-notice.hook\";\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 { usePurchaseIaCredits } from \"./modules/ia-credits/hooks/purchase-ia-credits.hook\";\nexport { useAiCreditsOfferEligibility } from \"./modules/ia-credits/hooks/use-offer-eligibility.hook\";\nexport {\n AI_CREDITS_FIRST_PURCHASE_OFFER,\n AI_CREDITS_OFFER_ELIGIBILITY_QUERY_KEY,\n AI_CREDITS_OFFER_MAX_REPEATS,\n AiCreditsOfferStage,\n PAYMENT_METHOD_CARD,\n PAYMENT_METHOD_PIX,\n} from \"./modules/ia-credits/constants/ai-credits-offer.constants\";\nexport type {\n AiCreditsOfferEligibility,\n AiCreditsOfferEligibilityResponse,\n AiCreditsOfferIneligibilityReason,\n PurchaseIaCreditsInput,\n PurchaseIaCreditsResult,\n} from \"./modules/ia-credits/types/ai-credits-offer.type\";\nexport {\n readOfferStageCookie,\n writeOfferStageCookie,\n} from \"./modules/ia-credits/utils/offer-stage-cookie\";\nexport type { OfferStageRecord } from \"./modules/ia-credits/utils/offer-stage-cookie\";\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 aiCreditUnitPrice,\n AI_CREDIT_SIZES,\n AI_CREDIT_VALUES,\n buildAiCreditOptions,\n resolveAiCreditPrice,\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 { hasActivePaidSubscription } from \"./modules/subscriptions/utils/has-active-paid-subscription\";\nexport { hasPaidSubscription } from \"./modules/subscriptions/utils/has-paid-subscription\";\nexport {\n confirmPaymentIfRequired,\n PaymentAuthenticationError,\n} from \"./modules/subscriptions/utils/confirm-payment-if-required\";\nexport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"./modules/subscriptions/constants/subscription.constants\";\nexport { getSubscriptionCancellationState } from \"./modules/subscriptions/utils/get-subscription-cancellation-state\";\nexport type { SubscriptionCancellationState } from \"./modules/subscriptions/utils/get-subscription-cancellation-state\";\nexport {\n ACCOUNT_FREEZE_AFTER_DAYS,\n FREEZE_WARNING_DAYS_BEFORE,\n} from \"./modules/subscriptions/constants/subscription.constants\";\nexport { getAccountFreezeState } from \"./modules/subscriptions/utils/get-account-freeze-state\";\nexport type { AccountFreezeState } from \"./modules/subscriptions/utils/get-account-freeze-state\";\nexport { getAccountFreezeDate } from \"./modules/subscriptions/utils/get-account-freeze-date\";\nexport type { FreezeNotice } from \"./modules/subscriptions/types/freeze-notice.type\";\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 { useAccountDeletionWarningModal } from \"./store/useAccountDeletionWarningModal\";\nexport { useAiCreditsOfferModal } from \"./store/useAiCreditsOfferModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as AiCreditsOfferModal } from \"./components/modals/promo/AiCreditsOfferModal\";\nexport { AiCreditsOfferGate } from \"./components/layouts/AiCreditsOfferGate\";\nexport type { AiCreditsOfferGateProps } from \"./components/layouts/AiCreditsOfferGate\";\nexport { default as CreditsDisabledModal } from \"./components/modals/CreditsDisabledModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as AccountFrozenModal } from \"./components/modals/AccountFrozenModal\";\nexport { default as AccountDeletionWarningModal } from \"./components/modals/AccountDeletionWarningModal\";\nexport { default as RequiredBillingDataModal } from \"./components/modals/billing/RequiredBillingDataModal\";\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 { GoogleIcon } from \"./components/ui/data-display/GoogleIcon\";\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 { FrozenAccountBanner } from \"./components/navigation/FrozenAccountBanner\";\nexport { FreezeWarningBanner } from \"./components/navigation/FreezeWarningBanner\";\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 { DialogLayer, useDialogLayer } from \"./components/ui/overlay/layers\";\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 getLocaleForCurrency,\n} from \"./utils/format/currency\";\nexport type { CurrencyCode } from \"./utils/format/currency\";\nexport {\n USD_GATEWAY,\n isUsdGateway,\n isUsdAccount,\n allowedPaymentMethods,\n isPaymentMethodAllowed,\n canBuyStandaloneAiCredits,\n} from \"./utils/format/gateway\";\nexport type { AccountGatewayLike, PaymentMethodKind } from \"./utils/format/gateway\";\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 useUpdateBillingData,\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\";\nexport { useRequiredBillingData } from \"./modules/accounts/hooks/use-required-billing-data.hook\";\nexport {\n hasCompleteBillingData,\n isBrazilianBillingAccount,\n} from \"./modules/accounts/utils/billing-data\";\nexport type { BillingDataSnapshot } from \"./modules/accounts/utils/billing-data\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateBillingDataRequest,\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 FREEZE_NOTICE_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 { useAccountFreeze } from \"./modules/subscriptions/hooks/use-account-freeze.hook\";\nexport { useFreezeNotice } from \"./modules/subscriptions/hooks/use-freeze-notice.hook\";\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 { usePurchaseIaCredits } from \"./modules/ia-credits/hooks/purchase-ia-credits.hook\";\nexport { useAiCreditsOfferEligibility } from \"./modules/ia-credits/hooks/use-offer-eligibility.hook\";\nexport {\n AI_CREDITS_FIRST_PURCHASE_OFFER,\n AI_CREDITS_OFFER_ELIGIBILITY_QUERY_KEY,\n AI_CREDITS_OFFER_MAX_REPEATS,\n AiCreditsOfferStage,\n PAYMENT_METHOD_CARD,\n PAYMENT_METHOD_PIX,\n} from \"./modules/ia-credits/constants/ai-credits-offer.constants\";\nexport type {\n AiCreditsOfferEligibility,\n AiCreditsOfferEligibilityResponse,\n AiCreditsOfferIneligibilityReason,\n PurchaseIaCreditsInput,\n PurchaseIaCreditsResult,\n} from \"./modules/ia-credits/types/ai-credits-offer.type\";\nexport {\n readOfferStageCookie,\n writeOfferStageCookie,\n} from \"./modules/ia-credits/utils/offer-stage-cookie\";\nexport type { OfferStageRecord } from \"./modules/ia-credits/utils/offer-stage-cookie\";\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 aiCreditUnitPrice,\n AI_CREDIT_SIZES,\n AI_CREDIT_VALUES,\n buildAiCreditOptions,\n resolveAiCreditPrice,\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 { hasActivePaidSubscription } from \"./modules/subscriptions/utils/has-active-paid-subscription\";\nexport { hasPaidSubscription } from \"./modules/subscriptions/utils/has-paid-subscription\";\nexport {\n confirmPaymentIfRequired,\n PaymentAuthenticationError,\n} from \"./modules/subscriptions/utils/confirm-payment-if-required\";\nexport { SUBSCRIPTION_GRACE_PERIOD_DAYS } from \"./modules/subscriptions/constants/subscription.constants\";\nexport { getSubscriptionCancellationState } from \"./modules/subscriptions/utils/get-subscription-cancellation-state\";\nexport type { SubscriptionCancellationState } from \"./modules/subscriptions/utils/get-subscription-cancellation-state\";\nexport {\n ACCOUNT_FREEZE_AFTER_DAYS,\n FREEZE_WARNING_DAYS_BEFORE,\n} from \"./modules/subscriptions/constants/subscription.constants\";\nexport { getAccountFreezeState } from \"./modules/subscriptions/utils/get-account-freeze-state\";\nexport type { AccountFreezeState } from \"./modules/subscriptions/utils/get-account-freeze-state\";\nexport { getAccountFreezeDate } from \"./modules/subscriptions/utils/get-account-freeze-date\";\nexport type { FreezeNotice } from \"./modules/subscriptions/types/freeze-notice.type\";\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 { useAccountDeletionWarningModal } from \"./store/useAccountDeletionWarningModal\";\nexport { useAiCreditsOfferModal } from \"./store/useAiCreditsOfferModal\";\nexport { default as BuyCreditsModal } from \"./components/modals/BuyCreditsModal\";\nexport { default as AiCreditsOfferModal } from \"./components/modals/promo/AiCreditsOfferModal\";\nexport { AiCreditsOfferGate } from \"./components/layouts/AiCreditsOfferGate\";\nexport type { AiCreditsOfferGateProps } from \"./components/layouts/AiCreditsOfferGate\";\nexport { default as CreditsDisabledModal } from \"./components/modals/CreditsDisabledModal\";\nexport { default as PaidPlanRequiredModal } from \"./components/modals/PaidPlanRequiredModal\";\nexport { default as AccountFrozenModal } from \"./components/modals/AccountFrozenModal\";\nexport { default as AccountDeletionWarningModal } from \"./components/modals/AccountDeletionWarningModal\";\nexport { default as RequiredBillingDataModal } from \"./components/modals/billing/RequiredBillingDataModal\";\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 { GoogleIcon } from \"./components/ui/data-display/GoogleIcon\";\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 { FrozenAccountBanner } from \"./components/navigation/FrozenAccountBanner\";\nexport { FreezeWarningBanner } from \"./components/navigation/FreezeWarningBanner\";\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 { DialogLayer, useDialogLayer } from \"./components/ui/overlay/layers\";\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 { useDomMutationGuardHit } from \"./hooks/useDomMutationGuardHit\";\nexport type { DomMutationGuardHit } from \"./hooks/useDomMutationGuardHit\";\nexport { DOM_MUTATION_GUARD_SCRIPT } from \"./utils/dom/dom-mutation-guard\";\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 getLocaleForCurrency,\n} from \"./utils/format/currency\";\nexport type { CurrencyCode } from \"./utils/format/currency\";\nexport {\n USD_GATEWAY,\n isUsdGateway,\n isUsdAccount,\n allowedPaymentMethods,\n isPaymentMethodAllowed,\n canBuyStandaloneAiCredits,\n} from \"./utils/format/gateway\";\nexport type { AccountGatewayLike, PaymentMethodKind } from \"./utils/format/gateway\";\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 useUpdateBillingData,\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\";\nexport { useRequiredBillingData } from \"./modules/accounts/hooks/use-required-billing-data.hook\";\nexport {\n hasCompleteBillingData,\n isBrazilianBillingAccount,\n} from \"./modules/accounts/utils/billing-data\";\nexport type { BillingDataSnapshot } from \"./modules/accounts/utils/billing-data\";\n\n// Account Types\nexport type {\n UpdateAccountRequest,\n UpdateBillingDataRequest,\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"]}
@@ -4,6 +4,8 @@ import { ApiError } from "../../../infra/api/types";
4
4
  import { whitelabelService } from "../../whitelabel/services/whitelabel.service";
5
5
  import { buildWlOverrideFromJwt } from "../utils/build-wl-override";
6
6
  import { findWhitelabel } from "../../../server";
7
+ import { resolveLocale } from "../../../i18n/resolve-locale";
8
+ import { localeToApiLanguage } from "../../../utils/intl/locales";
7
9
  const AUTH_COOKIE_NAME = "greatapps";
8
10
  const COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
9
11
  const FREE_PLAN_ID = 5;
@@ -184,12 +186,14 @@ class AuthService {
184
186
  const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);
185
187
  trialEndDate.setDate(today.getDate() + trialDays);
186
188
  const idPlan = await this.resolvePlanId(data.idPlan);
189
+ const whitelabel = await findWhitelabel().catch(() => null);
190
+ const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));
187
191
  const payload = {
188
192
  onboarding_token: data.onboardingToken,
189
193
  name: data.user.name,
190
194
  bussiness_type: data.businessType ?? 0,
191
- language: "pt-br",
192
- timezone: "America/Sao_Paulo",
195
+ language,
196
+ timezone: clientInfo.timezone,
193
197
  currency: "BRL",
194
198
  location: clientInfo.location,
195
199
  ip: clientInfo.ip,
@@ -206,7 +210,7 @@ class AuthService {
206
210
  ddi: data.user.ddi || "55",
207
211
  phone: data.user.phone || "",
208
212
  profile: "owner",
209
- language: "pt-br"
213
+ language
210
214
  },
211
215
  subscription: isFreePlan(idPlan) ? {
212
216
  type: "free",
@@ -279,11 +283,13 @@ class AuthService {
279
283
  const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);
280
284
  trialEndDate.setDate(today.getDate() + trialDays);
281
285
  const idPlan = await this.resolvePlanId(data.idPlan);
286
+ const whitelabel = await findWhitelabel().catch(() => null);
287
+ const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));
282
288
  const payload = {
283
289
  name: data.accountName,
284
290
  bussiness_type: data.businessType ?? 0,
285
- language: "pt-br",
286
- timezone: "America/Sao_Paulo",
291
+ language,
292
+ timezone: clientInfo.timezone,
287
293
  currency: "BRL",
288
294
  location: clientInfo.location,
289
295
  ip: clientInfo.ip,
@@ -301,7 +307,7 @@ class AuthService {
301
307
  phone: data.phone,
302
308
  password: data.password,
303
309
  profile: "owner",
304
- language: "pt-br"
310
+ language
305
311
  },
306
312
  subscription: isFreePlan(idPlan) ? {
307
313
  type: "free",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/auth/services/auth.service.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\n\nimport { api, type RequestConfig } from \"../../../infra/api/client\";\nimport { ApiError } from \"../../../infra/api/types\";\nimport { whitelabelService } from \"../../whitelabel/services/whitelabel.service\";\nimport { buildWlOverrideFromJwt } from \"../utils/build-wl-override\";\nimport {\n ClientInfo,\n ForgotPasswordRequest,\n ForgotPasswordResponse,\n GeoLocation,\n LoginApiResponse,\n LoginRequest,\n LoginResponse,\n LogoutApiResponse,\n LogoutRequest,\n LogoutResponse,\n RegisterApiRequest,\n RegisterApiResponse,\n RegisterRequest,\n RegisterResponse,\n ResendVerificationRequest,\n ResendVerificationResponse,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SearchPlansApiResponse,\n SessionKeepRequest,\n SessionKeepResponse,\n SocialGoogleApiResponse,\n SocialGoogleResponse,\n SocialOnboardingApiResponse,\n SocialOnboardingRequest,\n SocialOnboardingResponse,\n IsolatedLoginResponse,\n TwoFactorApiResponse,\n TwoFactorRequest,\n TwoFactorResponse,\n UnlinkGoogleApiResponse,\n UnlinkGoogleResponse,\n VerifyEmailRequest,\n VerifyEmailResponse,\n} from \"../schema\";\nimport { findWhitelabel } from \"../../../server\";\n\nconst AUTH_COOKIE_NAME = \"greatapps\";\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 30;\n\n/** Plano Free (ID fixo). */\nconst FREE_PLAN_ID = 5;\n\n/**\n * O cadastro pede o Free de duas formas, e as duas valem: ausência de plano (que o\n * `resolvePlanId` traduz para o sentinela -1) e o id do próprio Free.\n *\n * Olhar só o sentinela fazia `?id_plan=5` cair no ramo `trial` e criar um trial de 7 dias\n * do plano gratuito, com `date_due` e `trial_days` — estado que não existe no produto.\n */\nfunction isFreePlan(idPlan: number): boolean {\n return idPlan === -1 || idPlan === FREE_PLAN_ID;\n}\n\nconst COOKIE_OPTIONS = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n};\n\nclass AuthService {\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n ): Promise<LoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options: { setCookie: false },\n ): Promise<IsolatedLoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options?: { setCookie?: boolean },\n ): Promise<LoginResponse | IsolatedLoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options?: { setCookie?: boolean },\n ): Promise<LoginResponse | IsolatedLoginResponse> {\n let requestConfig: RequestConfig | undefined;\n if (credentials.id_wl) {\n const wlToken = await whitelabelService.getTokenByWhitelabelId(\n credentials.id_wl,\n );\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\n }\n\n const response = await api.apps.post<LoginApiResponse>(\n \"/auth/login\",\n {\n email: credentials.email,\n password: credentials.password,\n source: credentials?.source,\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n },\n requestConfig,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"E-mail ou senha incorretos\",\n response.code || \"LOGIN_FAILED\",\n 401,\n );\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (response.two_factor_required) {\n return { result: \"two_factor_required\", cookie: response.cookie, twoFactorMode: response.two_factor_required };\n }\n\n // Modo isolado: caller só quer o token, sem afetar a sessão do navegador\n // nem pagar pelas chamadas de user/account (ex.: fluxo de SSO).\n if (options?.setCookie === false) {\n return { result: \"success\", accessToken: response.cookie };\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(\n requestConfig ? { authToken: requestConfig.authToken } : undefined,\n ),\n accountService.findCurrentAccount(requestConfig),\n ]);\n\n return {\n result: \"success\",\n user,\n account,\n accessToken: response.cookie,\n refreshToken: \"\",\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async verifyTwoFactor(\n cookie: string,\n code: string,\n clientInfo: ClientInfo,\n options?: { window?: number; setCookie?: boolean },\n ): Promise<TwoFactorResponse> {\n const payload: TwoFactorRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n code,\n };\n\n const endpoint = options?.window !== undefined ? `/auth/code?window=${options.window}` : '/auth/code';\n const response = await api.apps.post<TwoFactorApiResponse>(\n endpoint,\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\"Código 2FA inválido\", \"TWO_FACTOR_FAILED\", 401);\n }\n\n if (!response?.data?.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida após 2FA\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n // Modo isolado: devolve o token sem gravar o cookie — o caller redireciona\n // pra outro lugar (ex.: SSO callback) e não quer mexer na sessão atual.\n if (options?.setCookie === false) {\n return { status: 1, accessToken: response.data.cookie };\n }\n\n await this.setAuthCookie(response.data.cookie);\n\n return { status: 1 };\n }\n\n async socialLoginGoogle(\n code: string,\n clientInfo: ClientInfo,\n ): Promise<SocialGoogleResponse> {\n const response = await api.apps.post<SocialGoogleApiResponse>(\n \"/auth/social/google\",\n {\n code,\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n verification: true,\n },\n );\n\n if (response.status === 0) {\n if (response.code === \"link_requires_password\") {\n return {\n result: \"link_requires_password\",\n message:\n response.message ||\n \"Uma conta com esse e-mail já existe. Faça login com e-mail e senha para vincular sua conta Google.\",\n };\n }\n throw new ApiError(\n response.message || \"Falha no login com Google\",\n response.code || \"GOOGLE_LOGIN_FAILED\",\n 401,\n );\n }\n\n if (response.needs_onboarding) {\n if (!response.onboarding_token || !response.partial?.email) {\n throw new ApiError(\n \"Resposta de onboarding inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n return {\n result: \"needs_onboarding\",\n onboardingToken: response.onboarding_token,\n partial: response.partial,\n };\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (response.two_factor_required) {\n return {\n result: \"two_factor_required\",\n cookie: response.cookie,\n twoFactorMode: response.two_factor_required,\n };\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n result: \"success\",\n user,\n account,\n accessToken: response.cookie,\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async completeGoogleOnboarding(\n data: SocialOnboardingRequest,\n clientInfo: ClientInfo,\n ): Promise<SocialOnboardingResponse> {\n const today = new Date();\n const trialEndDate = new Date(today);\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\n trialEndDate.setDate(today.getDate() + trialDays);\n\n const idPlan = await this.resolvePlanId(data.idPlan);\n\n const payload = {\n onboarding_token: data.onboardingToken,\n name: data.user.name,\n bussiness_type: data.businessType ?? 0,\n language: \"pt-br\",\n timezone: \"America/Sao_Paulo\",\n currency: \"BRL\",\n location: clientInfo.location,\n ip: clientInfo.ip,\n agent: clientInfo.agent,\n id_affiliate: data.affiliateId || 0,\n origin: data.origin,\n user: {\n id_api: \"\",\n name: data.user.name || \"\",\n last_name: data.user.last_name || \"\",\n rg: data.user.rg || \"\",\n cpf: data.user.cpf || \"\",\n gender: data.user.gender ?? 1,\n ddi: data.user.ddi || \"55\",\n phone: data.user.phone || \"\",\n profile: \"owner\",\n language: \"pt-br\",\n },\n subscription:\n isFreePlan(idPlan)\n ? {\n type: \"free\",\n id_coupon: data.couponId || 0,\n id_plan: FREE_PLAN_ID,\n id_product: 1,\n }\n : {\n type: \"trial\",\n id_coupon: data.couponId || 0,\n id_plan: idPlan,\n date_due: trialEndDate.toISOString().split(\"T\")[0],\n trial_days: trialDays,\n id_product: 1,\n },\n };\n\n const response = await api.apps.post<SocialOnboardingApiResponse>(\n \"/auth/social/onboarding\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao finalizar cadastro com Google\",\n \"ONBOARDING_FAILED\",\n 400,\n );\n }\n\n if (!response.data?.length || !response.cookie) {\n throw new ApiError(\n \"Resposta de cadastro inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n user,\n account,\n accessToken: response.cookie,\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async unlinkGoogle(): Promise<UnlinkGoogleResponse> {\n const { id_account, id_user } = await import(\n \"../utils/get-user-context\"\n ).then((m) => m.getUserContext());\n\n const response = await api.apps.delete<UnlinkGoogleApiResponse>(\n `/accounts/${id_account}/users/${id_user}/social/google`,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao desvincular conta Google\",\n \"UNLINK_FAILED\",\n 400,\n );\n }\n\n return {\n success: true,\n message: response.message,\n };\n }\n\n async register(\n data: RegisterRequest,\n clientInfo: ClientInfo,\n ): Promise<RegisterResponse> {\n const today = new Date();\n const trialEndDate = new Date(today);\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\n trialEndDate.setDate(today.getDate() + trialDays);\n\n const idPlan = await this.resolvePlanId(data.idPlan);\n\n const payload: RegisterApiRequest = {\n name: data.accountName,\n bussiness_type: data.businessType ?? 0,\n language: \"pt-br\",\n timezone: \"America/Sao_Paulo\",\n currency: \"BRL\",\n location: clientInfo.location,\n ip: clientInfo.ip,\n agent: clientInfo.agent,\n id_affiliate: data.affiliateId || 0,\n origin: data.origin,\n user: {\n id_api: \"\",\n name: data.name,\n last_name: data.lastName || \"\",\n rg: data.rg || \"\",\n cpf: data.cpf || \"\",\n gender: data.gender,\n email: data.email,\n phone: data.phone,\n password: data.password,\n profile: \"owner\",\n language: \"pt-br\",\n },\n subscription:\n isFreePlan(idPlan)\n ? {\n type: \"free\",\n id_coupon: data.couponId || 0,\n id_plan: FREE_PLAN_ID,\n id_product: 1,\n }\n : {\n type: \"trial\",\n id_coupon: data.couponId || 0,\n id_plan: idPlan,\n // Fluxo não-Stripe lê `date_due`; fluxo Stripe lê `trial_days`.\n // Mandamos os dois pra cobrir ambos os caminhos da API.\n date_due: trialEndDate.toISOString().split(\"T\")[0],\n trial_days: trialDays,\n id_product: 1,\n },\n };\n\n const response = await api.apps.post<RegisterApiResponse>(\n \"/accounts\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao criar conta\",\n \"REGISTER_FAILED\",\n 400,\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError(\n \"Resposta de registro inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n const accountData = response.data[0];\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n user,\n account,\n accessToken: response.cookie,\n refreshToken: \"\",\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n requiresEmailVerification: !accountData.verified,\n };\n }\n\n async logout(clientInfo: ClientInfo): Promise<LogoutResponse> {\n const cookie = await this.getToken();\n\n if (!cookie) {\n throw new ApiError(\n \"Usuário não autenticado\",\n \"NOT_AUTHENTICATED_LOGOUT\",\n 401\n );\n }\n\n const payload: LogoutRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n };\n\n try {\n const response = await api.apps.post<LogoutApiResponse>(\n \"/auth/logout\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao realizar logout\",\n response.code || \"LOGOUT_FAILED\",\n 400,\n );\n }\n } finally {\n await this.removeAuthCookie();\n }\n\n return {\n success: true,\n };\n }\n\n async forgotPassword(\n _data: ForgotPasswordRequest,\n ): Promise<ForgotPasswordResponse> {\n throw new ApiError(\n \"Recuperação de senha não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async resetPassword(\n _data: ResetPasswordRequest,\n ): Promise<ResetPasswordResponse> {\n throw new ApiError(\n \"Redefinição de senha não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async verifyEmail(_data: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n throw new ApiError(\n \"Verificação de email não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async resendVerification(\n _data: ResendVerificationRequest,\n ): Promise<ResendVerificationResponse> {\n throw new ApiError(\n \"Reenvio de verificação não implementado\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async validateSession(clientInfo: ClientInfo): Promise<boolean> {\n const cookie = await this.getToken();\n\n if (!cookie) {\n return false;\n }\n\n try {\n const requestConfig = await buildWlOverrideFromJwt(cookie);\n\n const payload: SessionKeepRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n };\n\n const response = await api.apps.post<SessionKeepResponse>(\n \"/auth/keep\",\n payload,\n requestConfig,\n );\n\n return response.status === 1;\n } catch (error) {\n console.error(\"[AuthService] validateSession error\", error);\n return false;\n }\n }\n\n async isAuthenticated(): Promise<boolean> {\n const token = await this.getToken();\n return !!token;\n }\n\n async getToken(): Promise<string | undefined> {\n if (process.env.DUMMY_AUTH_TOKEN) return process.env.DUMMY_AUTH_TOKEN;\n const cookieStore = await cookies();\n return cookieStore.get(AUTH_COOKIE_NAME)?.value;\n }\n\n private async resolvePlanId(idPlan?: number | string | null): Promise<number> {\n if (idPlan == null || idPlan === \"\") return -1;\n if (typeof idPlan === \"number\" || Number(idPlan)) return Number(idPlan);\n\n if (typeof idPlan === \"string\") {\n const response = await api.apps.get<SearchPlansApiResponse>(\n `/plans?search=${encodeURIComponent(idPlan)}`,\n );\n\n if (response.status === 1 && response.data?.length) {\n return response.data[0].id;\n }\n\n throw new ApiError(\n `Plano \"${idPlan}\" não encontrado`,\n \"PLAN_NOT_FOUND\",\n 404,\n );\n }\n return -1;\n }\n\n private async setAuthCookie(token: string): Promise<void> {\n const cookieStore = await cookies();\n const whitelabel = await findWhitelabel().catch(() => null);\n const cookieDomain =\n this.normalizeCookieDomain(whitelabel?.domain);\n\n cookieStore.set(AUTH_COOKIE_NAME, token, {\n ...COOKIE_OPTIONS,\n ...(cookieDomain ? { domain: cookieDomain } : {}),\n maxAge: COOKIE_MAX_AGE,\n });\n }\n\n async removeAuthCookie(): Promise<void> {\n const cookieStore = await cookies();\n const whitelabel = await findWhitelabel().catch(() => null);\n const cookieDomain =\n this.normalizeCookieDomain(whitelabel?.domain);\n\n cookieStore.delete({\n name: AUTH_COOKIE_NAME,\n ...COOKIE_OPTIONS,\n ...(cookieDomain ? { domain: cookieDomain } : {}),\n });\n }\n\n private normalizeCookieDomain(domain?: string | null): string | undefined {\n if (!domain) return undefined;\n\n const normalized = domain.trim();\n if (!normalized) return undefined;\n\n const rawHost = (() => {\n try {\n return new URL(normalized).hostname;\n } catch {\n return normalized\n .replace(/^https?:\\/\\//i, \"\")\n .replace(/^www\\./i, \"\")\n .split(\"/\")[0]\n .split(\":\")[0];\n }\n })();\n\n if (!rawHost || rawHost === \"localhost\") {\n return undefined;\n }\n\n return rawHost.startsWith(\".\") ? rawHost : `.${rawHost}`;\n }\n}\n\nexport const authService = new AuthService();\n\nexport type { ClientInfo, GeoLocation };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/auth/services/auth.service.ts"],"sourcesContent":["import { cookies } from \"next/headers\";\n\nimport { api, type RequestConfig } from \"../../../infra/api/client\";\nimport { ApiError } from \"../../../infra/api/types\";\nimport { whitelabelService } from \"../../whitelabel/services/whitelabel.service\";\nimport { buildWlOverrideFromJwt } from \"../utils/build-wl-override\";\nimport {\n ClientInfo,\n ForgotPasswordRequest,\n ForgotPasswordResponse,\n GeoLocation,\n LoginApiResponse,\n LoginRequest,\n LoginResponse,\n LogoutApiResponse,\n LogoutRequest,\n LogoutResponse,\n RegisterApiRequest,\n RegisterApiResponse,\n RegisterRequest,\n RegisterResponse,\n ResendVerificationRequest,\n ResendVerificationResponse,\n ResetPasswordRequest,\n ResetPasswordResponse,\n SearchPlansApiResponse,\n SessionKeepRequest,\n SessionKeepResponse,\n SocialGoogleApiResponse,\n SocialGoogleResponse,\n SocialOnboardingApiResponse,\n SocialOnboardingRequest,\n SocialOnboardingResponse,\n IsolatedLoginResponse,\n TwoFactorApiResponse,\n TwoFactorRequest,\n TwoFactorResponse,\n UnlinkGoogleApiResponse,\n UnlinkGoogleResponse,\n VerifyEmailRequest,\n VerifyEmailResponse,\n} from \"../schema\";\nimport { findWhitelabel } from \"../../../server\";\nimport { resolveLocale } from \"../../../i18n/resolve-locale\";\nimport { localeToApiLanguage } from \"../../../utils/intl/locales\";\n\nconst AUTH_COOKIE_NAME = \"greatapps\";\nconst COOKIE_MAX_AGE = 60 * 60 * 24 * 30;\n\n/** Plano Free (ID fixo). */\nconst FREE_PLAN_ID = 5;\n\n/**\n * O cadastro pede o Free de duas formas, e as duas valem: ausência de plano (que o\n * `resolvePlanId` traduz para o sentinela -1) e o id do próprio Free.\n *\n * Olhar só o sentinela fazia `?id_plan=5` cair no ramo `trial` e criar um trial de 7 dias\n * do plano gratuito, com `date_due` e `trial_days` — estado que não existe no produto.\n */\nfunction isFreePlan(idPlan: number): boolean {\n return idPlan === -1 || idPlan === FREE_PLAN_ID;\n}\n\nconst COOKIE_OPTIONS = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\" as const,\n path: \"/\",\n};\n\nclass AuthService {\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n ): Promise<LoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options: { setCookie: false },\n ): Promise<IsolatedLoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options?: { setCookie?: boolean },\n ): Promise<LoginResponse | IsolatedLoginResponse>;\n async login(\n credentials: LoginRequest,\n clientInfo: ClientInfo,\n options?: { setCookie?: boolean },\n ): Promise<LoginResponse | IsolatedLoginResponse> {\n let requestConfig: RequestConfig | undefined;\n if (credentials.id_wl) {\n const wlToken = await whitelabelService.getTokenByWhitelabelId(\n credentials.id_wl,\n );\n requestConfig = { whiteLabelId: credentials.id_wl, authToken: wlToken };\n }\n\n const response = await api.apps.post<LoginApiResponse>(\n \"/auth/login\",\n {\n email: credentials.email,\n password: credentials.password,\n source: credentials?.source,\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n },\n requestConfig,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"E-mail ou senha incorretos\",\n response.code || \"LOGIN_FAILED\",\n 401,\n );\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (response.two_factor_required) {\n return { result: \"two_factor_required\", cookie: response.cookie, twoFactorMode: response.two_factor_required };\n }\n\n // Modo isolado: caller só quer o token, sem afetar a sessão do navegador\n // nem pagar pelas chamadas de user/account (ex.: fluxo de SSO).\n if (options?.setCookie === false) {\n return { result: \"success\", accessToken: response.cookie };\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(\n requestConfig ? { authToken: requestConfig.authToken } : undefined,\n ),\n accountService.findCurrentAccount(requestConfig),\n ]);\n\n return {\n result: \"success\",\n user,\n account,\n accessToken: response.cookie,\n refreshToken: \"\",\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async verifyTwoFactor(\n cookie: string,\n code: string,\n clientInfo: ClientInfo,\n options?: { window?: number; setCookie?: boolean },\n ): Promise<TwoFactorResponse> {\n const payload: TwoFactorRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n code,\n };\n\n const endpoint = options?.window !== undefined ? `/auth/code?window=${options.window}` : '/auth/code';\n const response = await api.apps.post<TwoFactorApiResponse>(\n endpoint,\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\"Código 2FA inválido\", \"TWO_FACTOR_FAILED\", 401);\n }\n\n if (!response?.data?.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida após 2FA\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n // Modo isolado: devolve o token sem gravar o cookie — o caller redireciona\n // pra outro lugar (ex.: SSO callback) e não quer mexer na sessão atual.\n if (options?.setCookie === false) {\n return { status: 1, accessToken: response.data.cookie };\n }\n\n await this.setAuthCookie(response.data.cookie);\n\n return { status: 1 };\n }\n\n async socialLoginGoogle(\n code: string,\n clientInfo: ClientInfo,\n ): Promise<SocialGoogleResponse> {\n const response = await api.apps.post<SocialGoogleApiResponse>(\n \"/auth/social/google\",\n {\n code,\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n verification: true,\n },\n );\n\n if (response.status === 0) {\n if (response.code === \"link_requires_password\") {\n return {\n result: \"link_requires_password\",\n message:\n response.message ||\n \"Uma conta com esse e-mail já existe. Faça login com e-mail e senha para vincular sua conta Google.\",\n };\n }\n throw new ApiError(\n response.message || \"Falha no login com Google\",\n response.code || \"GOOGLE_LOGIN_FAILED\",\n 401,\n );\n }\n\n if (response.needs_onboarding) {\n if (!response.onboarding_token || !response.partial?.email) {\n throw new ApiError(\n \"Resposta de onboarding inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n return {\n result: \"needs_onboarding\",\n onboardingToken: response.onboarding_token,\n partial: response.partial,\n };\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (response.two_factor_required) {\n return {\n result: \"two_factor_required\",\n cookie: response.cookie,\n twoFactorMode: response.two_factor_required,\n };\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n result: \"success\",\n user,\n account,\n accessToken: response.cookie,\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async completeGoogleOnboarding(\n data: SocialOnboardingRequest,\n clientInfo: ClientInfo,\n ): Promise<SocialOnboardingResponse> {\n const today = new Date();\n const trialEndDate = new Date(today);\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\n trialEndDate.setDate(today.getDate() + trialDays);\n\n const idPlan = await this.resolvePlanId(data.idPlan);\n\n const whitelabel = await findWhitelabel().catch(() => null);\n const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));\n\n const payload = {\n onboarding_token: data.onboardingToken,\n name: data.user.name,\n bussiness_type: data.businessType ?? 0,\n language,\n timezone: clientInfo.timezone,\n currency: \"BRL\",\n location: clientInfo.location,\n ip: clientInfo.ip,\n agent: clientInfo.agent,\n id_affiliate: data.affiliateId || 0,\n origin: data.origin,\n user: {\n id_api: \"\",\n name: data.user.name || \"\",\n last_name: data.user.last_name || \"\",\n rg: data.user.rg || \"\",\n cpf: data.user.cpf || \"\",\n gender: data.user.gender ?? 1,\n ddi: data.user.ddi || \"55\",\n phone: data.user.phone || \"\",\n profile: \"owner\",\n language,\n },\n subscription:\n isFreePlan(idPlan)\n ? {\n type: \"free\",\n id_coupon: data.couponId || 0,\n id_plan: FREE_PLAN_ID,\n id_product: 1,\n }\n : {\n type: \"trial\",\n id_coupon: data.couponId || 0,\n id_plan: idPlan,\n date_due: trialEndDate.toISOString().split(\"T\")[0],\n trial_days: trialDays,\n id_product: 1,\n },\n };\n\n const response = await api.apps.post<SocialOnboardingApiResponse>(\n \"/auth/social/onboarding\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao finalizar cadastro com Google\",\n \"ONBOARDING_FAILED\",\n 400,\n );\n }\n\n if (!response.data?.length || !response.cookie) {\n throw new ApiError(\n \"Resposta de cadastro inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n user,\n account,\n accessToken: response.cookie,\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n };\n }\n\n async unlinkGoogle(): Promise<UnlinkGoogleResponse> {\n const { id_account, id_user } = await import(\n \"../utils/get-user-context\"\n ).then((m) => m.getUserContext());\n\n const response = await api.apps.delete<UnlinkGoogleApiResponse>(\n `/accounts/${id_account}/users/${id_user}/social/google`,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao desvincular conta Google\",\n \"UNLINK_FAILED\",\n 400,\n );\n }\n\n return {\n success: true,\n message: response.message,\n };\n }\n\n async register(\n data: RegisterRequest,\n clientInfo: ClientInfo,\n ): Promise<RegisterResponse> {\n const today = new Date();\n const trialEndDate = new Date(today);\n const trialDays = Math.min(Math.max(data.trialDays ?? 7, 1), 90);\n trialEndDate.setDate(today.getDate() + trialDays);\n\n const idPlan = await this.resolvePlanId(data.idPlan);\n\n const whitelabel = await findWhitelabel().catch(() => null);\n const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));\n\n const payload: RegisterApiRequest = {\n name: data.accountName,\n bussiness_type: data.businessType ?? 0,\n language,\n timezone: clientInfo.timezone,\n currency: \"BRL\",\n location: clientInfo.location,\n ip: clientInfo.ip,\n agent: clientInfo.agent,\n id_affiliate: data.affiliateId || 0,\n origin: data.origin,\n user: {\n id_api: \"\",\n name: data.name,\n last_name: data.lastName || \"\",\n rg: data.rg || \"\",\n cpf: data.cpf || \"\",\n gender: data.gender,\n email: data.email,\n phone: data.phone,\n password: data.password,\n profile: \"owner\",\n language,\n },\n subscription:\n isFreePlan(idPlan)\n ? {\n type: \"free\",\n id_coupon: data.couponId || 0,\n id_plan: FREE_PLAN_ID,\n id_product: 1,\n }\n : {\n type: \"trial\",\n id_coupon: data.couponId || 0,\n id_plan: idPlan,\n // Fluxo não-Stripe lê `date_due`; fluxo Stripe lê `trial_days`.\n // Mandamos os dois pra cobrir ambos os caminhos da API.\n date_due: trialEndDate.toISOString().split(\"T\")[0],\n trial_days: trialDays,\n id_product: 1,\n },\n };\n\n const response = await api.apps.post<RegisterApiResponse>(\n \"/accounts\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao criar conta\",\n \"REGISTER_FAILED\",\n 400,\n );\n }\n\n if (!response.data || response.data.length === 0) {\n throw new ApiError(\n \"Resposta de registro inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n if (!response.cookie) {\n throw new ApiError(\n \"Resposta de autenticação inválida\",\n \"INVALID_RESPONSE\",\n 500,\n );\n }\n\n const accountData = response.data[0];\n\n await this.setAuthCookie(response.cookie);\n\n const [{ userService }, { accountService }] = await Promise.all([\n import(\"../../users/services/user.service\"),\n import(\"../../accounts/services/account.service\"),\n ]);\n const [user, account] = await Promise.all([\n userService.findById(),\n accountService.findCurrentAccount(),\n ]);\n\n return {\n user,\n account,\n accessToken: response.cookie,\n refreshToken: \"\",\n expiresAt: new Date(Date.now() + COOKIE_MAX_AGE * 1000).toISOString(),\n requiresEmailVerification: !accountData.verified,\n };\n }\n\n async logout(clientInfo: ClientInfo): Promise<LogoutResponse> {\n const cookie = await this.getToken();\n\n if (!cookie) {\n throw new ApiError(\n \"Usuário não autenticado\",\n \"NOT_AUTHENTICATED_LOGOUT\",\n 401\n );\n }\n\n const payload: LogoutRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n };\n\n try {\n const response = await api.apps.post<LogoutApiResponse>(\n \"/auth/logout\",\n payload,\n );\n\n if (response.status === 0) {\n throw new ApiError(\n response.message || \"Erro ao realizar logout\",\n response.code || \"LOGOUT_FAILED\",\n 400,\n );\n }\n } finally {\n await this.removeAuthCookie();\n }\n\n return {\n success: true,\n };\n }\n\n async forgotPassword(\n _data: ForgotPasswordRequest,\n ): Promise<ForgotPasswordResponse> {\n throw new ApiError(\n \"Recuperação de senha não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async resetPassword(\n _data: ResetPasswordRequest,\n ): Promise<ResetPasswordResponse> {\n throw new ApiError(\n \"Redefinição de senha não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async verifyEmail(_data: VerifyEmailRequest): Promise<VerifyEmailResponse> {\n throw new ApiError(\n \"Verificação de email não implementada\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async resendVerification(\n _data: ResendVerificationRequest,\n ): Promise<ResendVerificationResponse> {\n throw new ApiError(\n \"Reenvio de verificação não implementado\",\n \"NOT_IMPLEMENTED\",\n 501,\n );\n }\n\n async validateSession(clientInfo: ClientInfo): Promise<boolean> {\n const cookie = await this.getToken();\n\n if (!cookie) {\n return false;\n }\n\n try {\n const requestConfig = await buildWlOverrideFromJwt(cookie);\n\n const payload: SessionKeepRequest = {\n location: clientInfo.location,\n ip: clientInfo.ip,\n timezone: clientInfo.timezone,\n agent: clientInfo.agent,\n cookie,\n };\n\n const response = await api.apps.post<SessionKeepResponse>(\n \"/auth/keep\",\n payload,\n requestConfig,\n );\n\n return response.status === 1;\n } catch (error) {\n console.error(\"[AuthService] validateSession error\", error);\n return false;\n }\n }\n\n async isAuthenticated(): Promise<boolean> {\n const token = await this.getToken();\n return !!token;\n }\n\n async getToken(): Promise<string | undefined> {\n if (process.env.DUMMY_AUTH_TOKEN) return process.env.DUMMY_AUTH_TOKEN;\n const cookieStore = await cookies();\n return cookieStore.get(AUTH_COOKIE_NAME)?.value;\n }\n\n private async resolvePlanId(idPlan?: number | string | null): Promise<number> {\n if (idPlan == null || idPlan === \"\") return -1;\n if (typeof idPlan === \"number\" || Number(idPlan)) return Number(idPlan);\n\n if (typeof idPlan === \"string\") {\n const response = await api.apps.get<SearchPlansApiResponse>(\n `/plans?search=${encodeURIComponent(idPlan)}`,\n );\n\n if (response.status === 1 && response.data?.length) {\n return response.data[0].id;\n }\n\n throw new ApiError(\n `Plano \"${idPlan}\" não encontrado`,\n \"PLAN_NOT_FOUND\",\n 404,\n );\n }\n return -1;\n }\n\n private async setAuthCookie(token: string): Promise<void> {\n const cookieStore = await cookies();\n const whitelabel = await findWhitelabel().catch(() => null);\n const cookieDomain =\n this.normalizeCookieDomain(whitelabel?.domain);\n\n cookieStore.set(AUTH_COOKIE_NAME, token, {\n ...COOKIE_OPTIONS,\n ...(cookieDomain ? { domain: cookieDomain } : {}),\n maxAge: COOKIE_MAX_AGE,\n });\n }\n\n async removeAuthCookie(): Promise<void> {\n const cookieStore = await cookies();\n const whitelabel = await findWhitelabel().catch(() => null);\n const cookieDomain =\n this.normalizeCookieDomain(whitelabel?.domain);\n\n cookieStore.delete({\n name: AUTH_COOKIE_NAME,\n ...COOKIE_OPTIONS,\n ...(cookieDomain ? { domain: cookieDomain } : {}),\n });\n }\n\n private normalizeCookieDomain(domain?: string | null): string | undefined {\n if (!domain) return undefined;\n\n const normalized = domain.trim();\n if (!normalized) return undefined;\n\n const rawHost = (() => {\n try {\n return new URL(normalized).hostname;\n } catch {\n return normalized\n .replace(/^https?:\\/\\//i, \"\")\n .replace(/^www\\./i, \"\")\n .split(\"/\")[0]\n .split(\":\")[0];\n }\n })();\n\n if (!rawHost || rawHost === \"localhost\") {\n return undefined;\n }\n\n return rawHost.startsWith(\".\") ? rawHost : `.${rawHost}`;\n }\n}\n\nexport const authService = new AuthService();\n\nexport type { ClientInfo, GeoLocation };\n"],"mappings":"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","names":[]}
@@ -0,0 +1,20 @@
1
+ const DOM_MUTATION_GUARD_SCRIPT = `(function(){
2
+ if(typeof Node==="undefined"||!Node.prototype)return;
3
+ if(window.__gpDomGuard)return;
4
+ var s={removeChild:0,insertBefore:0};
5
+ window.__gpDomGuard=s;
6
+ window.__gpDomGuardOnHit=window.__gpDomGuardOnHit||null;
7
+ function hit(k){s[k]++;try{if(window.__gpDomGuardOnHit)window.__gpDomGuardOnHit(k)}catch(e){}}
8
+ var removeChild=Node.prototype.removeChild;
9
+ Node.prototype.removeChild=function(child){
10
+ if(child&&child.parentNode!==this){hit("removeChild");return child}
11
+ return removeChild.apply(this,arguments)};
12
+ var insertBefore=Node.prototype.insertBefore;
13
+ Node.prototype.insertBefore=function(newNode,referenceNode){
14
+ if(referenceNode&&referenceNode.parentNode!==this){hit("insertBefore");return newNode}
15
+ return insertBefore.apply(this,arguments)};
16
+ })();`;
17
+ export {
18
+ DOM_MUTATION_GUARD_SCRIPT
19
+ };
20
+ //# sourceMappingURL=dom-mutation-guard.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/utils/dom/dom-mutation-guard.ts"],"sourcesContent":["/**\n * Guarda contra mutação externa do DOM (tradutor do navegador, extensões).\n *\n * PROBLEMA: o Google Tradutor do Chrome substitui cada text node por `<font><font>…</font></font>`.\n * O React continua guardando a referência do text node ORIGINAL no fiber. No commit seguinte ele\n * chama `parent.insertBefore(novo, textNodeAntigo)` ou `parent.removeChild(textNodeAntigo)` — e o nó\n * já não é mais filho daquele pai. O DOM levanta `NotFoundError`, o erro sobe até o root e o app\n * inteiro cai no `global-error.tsx` (evento `render.root_crashed` no Sentry).\n *\n * Isso derrubou clientes reais em CO/PE/MX/AR/FR (zero casos no BR, onde a página já está no idioma\n * do usuário e o Chrome não oferece tradução), inclusive em cima da tela de trocar cartão — o cliente\n * ficava sem conseguir pagar.\n *\n * SOLUÇÃO: transformar essas duas operações em no-op quando o nó de referência já não pertence mais\n * ao pai. O React segue adiante, a página não morre, e o trecho traduzido apenas deixa de receber\n * aquela atualização pontual (o próximo re-render completo normaliza).\n *\n * Precisa rodar ANTES da hidratação, por isso é injetado como `<script>` inline no `<head>` do root\n * layout em vez de virar um `useEffect`.\n */\n\ndeclare global {\n interface Window {\n /** Contadores de quantas vezes a guarda entrou em ação nesta sessão. */\n __gpDomGuard?: { removeChild: number; insertBefore: number };\n /** Hook opcional preenchido pelo reporter para avisar o Sentry no primeiro disparo. */\n __gpDomGuardOnHit?: ((kind: 'removeChild' | 'insertBefore') => void) | null;\n }\n}\n\nexport const DOM_MUTATION_GUARD_SCRIPT = `(function(){\nif(typeof Node===\"undefined\"||!Node.prototype)return;\nif(window.__gpDomGuard)return;\nvar s={removeChild:0,insertBefore:0};\nwindow.__gpDomGuard=s;\nwindow.__gpDomGuardOnHit=window.__gpDomGuardOnHit||null;\nfunction hit(k){s[k]++;try{if(window.__gpDomGuardOnHit)window.__gpDomGuardOnHit(k)}catch(e){}}\nvar removeChild=Node.prototype.removeChild;\nNode.prototype.removeChild=function(child){\nif(child&&child.parentNode!==this){hit(\"removeChild\");return child}\nreturn removeChild.apply(this,arguments)};\nvar insertBefore=Node.prototype.insertBefore;\nNode.prototype.insertBefore=function(newNode,referenceNode){\nif(referenceNode&&referenceNode.parentNode!==this){hit(\"insertBefore\");return newNode}\nreturn insertBefore.apply(this,arguments)};\n})();`;\n"],"mappings":"AA8BO,MAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
@@ -6,8 +6,13 @@ const LANGUAGE_OPTIONS = [
6
6
  function buildLocaleOptions() {
7
7
  return LANGUAGE_OPTIONS;
8
8
  }
9
+ function localeToApiLanguage(locale) {
10
+ const option = LANGUAGE_OPTIONS.find((o) => o.value === locale);
11
+ return option?.apiValue ?? locale;
12
+ }
9
13
  export {
10
14
  LANGUAGE_OPTIONS,
11
- buildLocaleOptions
15
+ buildLocaleOptions,
16
+ localeToApiLanguage
12
17
  };
13
18
  //# sourceMappingURL=locales.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/intl/locales.ts"],"sourcesContent":["export type LocaleOption = {\r\n value: string;\r\n label: string;\r\n displayValue: string;\r\n apiValue: string;\r\n};\r\n\r\nexport const LANGUAGE_OPTIONS: LocaleOption[] = [\r\n { value: 'pt-br', label: 'Português (Brasil)', displayValue: 'Português (Brasil)', apiValue: 'pt-br' },\r\n { value: 'en-us', label: 'Inglês (EUA)', displayValue: 'Inglês (EUA)', apiValue: 'en' },\r\n { value: 'es-es', label: 'Espanhol', displayValue: 'Espanhol', apiValue: 'es' },\r\n];\r\n\r\nexport function buildLocaleOptions(): LocaleOption[] {\r\n return LANGUAGE_OPTIONS;\r\n}\r\n"],"mappings":"AAOO,MAAM,mBAAmC;AAAA,EAC9C,EAAE,OAAO,SAAS,OAAO,yBAAsB,cAAc,yBAAsB,UAAU,QAAQ;AAAA,EACrG,EAAE,OAAO,SAAS,OAAO,mBAAgB,cAAc,mBAAgB,UAAU,KAAK;AAAA,EACtF,EAAE,OAAO,SAAS,OAAO,YAAY,cAAc,YAAY,UAAU,KAAK;AAChF;AAEO,SAAS,qBAAqC;AACnD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/intl/locales.ts"],"sourcesContent":["import { Locale } from '../../i18n/config';\r\n\r\nexport type LocaleOption = {\r\n value: string;\r\n label: string;\r\n displayValue: string;\r\n apiValue: string;\r\n};\r\n\r\nexport const LANGUAGE_OPTIONS: LocaleOption[] = [\r\n { value: 'pt-br', label: 'Português (Brasil)', displayValue: 'Português (Brasil)', apiValue: 'pt-br' },\r\n { value: 'en-us', label: 'Inglês (EUA)', displayValue: 'Inglês (EUA)', apiValue: 'en' },\r\n { value: 'es-es', label: 'Espanhol', displayValue: 'Espanhol', apiValue: 'es' },\r\n];\r\n\r\nexport function buildLocaleOptions(): LocaleOption[] {\r\n return LANGUAGE_OPTIONS;\r\n}\r\n\r\nexport function localeToApiLanguage(locale: Locale): string {\r\n const option = LANGUAGE_OPTIONS.find((o) => o.value === locale);\r\n return option?.apiValue ?? locale;\r\n}\r\n"],"mappings":"AASO,MAAM,mBAAmC;AAAA,EAC9C,EAAE,OAAO,SAAS,OAAO,yBAAsB,cAAc,yBAAsB,UAAU,QAAQ;AAAA,EACrG,EAAE,OAAO,SAAS,OAAO,mBAAgB,cAAc,mBAAgB,UAAU,KAAK;AAAA,EACtF,EAAE,OAAO,SAAS,OAAO,YAAY,cAAc,YAAY,UAAU,KAAK;AAChF;AAEO,SAAS,qBAAqC;AACnD,SAAO;AACT;AAEO,SAAS,oBAAoB,QAAwB;AAC1D,QAAM,SAAS,iBAAiB,KAAK,CAAC,MAAM,EAAE,UAAU,MAAM;AAC9D,SAAO,QAAQ,YAAY;AAC7B;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@greatapps/common",
3
- "version": "1.1.779",
3
+ "version": "1.1.780",
4
4
  "description": "Shared library for GreatApps frontend applications",
5
5
  "main": "./dist/index.mjs",
6
6
  "types": "./src/index.ts",
@@ -7,8 +7,9 @@ import { useRouter } from 'next/navigation';
7
7
  import { toast } from 'sonner';
8
8
  import { IconLock } from '@tabler/icons-react';
9
9
  import { cn } from '../../../infra/utils/clsx';
10
- import type { Locale } from '../../../i18n/config';
10
+ import { isLocale, type Locale } from '../../../i18n/config';
11
11
  import { setLocaleCookie } from '../../../utils/intl/locale-cookie';
12
+ import { localeToApiLanguage } from '../../../utils/intl/locales';
12
13
  import { Button } from '../../ui/buttons/Button';
13
14
  import { Separator } from '../../ui/data-display/Separator';
14
15
  import { Toast } from '../../ui/feedback/Toast';
@@ -112,7 +113,7 @@ export function PreferencesSection({ onClose }: PreferencesSectionProps) {
112
113
  const doSave = async (data: PreferencesFormValues, accountFields: UpdateAccountRequest) => {
113
114
  setIsSaving(true);
114
115
  try {
115
- const apiLanguage = LANGUAGE_OPTIONS.find((o) => o.value === data.language)?.apiValue ?? data.language.toLowerCase();
116
+ const apiLanguage = isLocale(data.language) ? localeToApiLanguage(data.language) : data.language.toLowerCase();
116
117
  await updateAccountUser.mutateAsync({
117
118
  language: apiLanguage,
118
119
  receive_sms: data.receive_sms,
@@ -0,0 +1,55 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useRef } from 'react';
4
+
5
+ export type DomMutationGuardHit = {
6
+ kind: 'removeChild' | 'insertBefore';
7
+ language: string;
8
+ languages: string;
9
+ documentLang: string;
10
+ translatedNodes: number;
11
+ path: string;
12
+ }
13
+
14
+ /**
15
+ * Reporta quando a guarda de mutação de DOM (`DOM_MUTATION_GUARD_SCRIPT`) entra em ação.
16
+ *
17
+ * Sem isso a correção fica cega: o app para de cair, mas ninguém descobre quantos clientes estão
18
+ * navegando com o tradutor do navegador ligado. Reporta UMA vez por sessão — o objetivo é medir
19
+ * quantas sessões são afetadas, não quantas operações de DOM foram salvas.
20
+ */
21
+ export function useDomMutationGuardHit(onHit: (hit: DomMutationGuardHit) => void): void {
22
+ const onHitRef = useRef(onHit);
23
+ onHitRef.current = onHit;
24
+
25
+ useEffect(() => {
26
+ let reported = false;
27
+
28
+ const report = (kind: 'removeChild' | 'insertBefore') => {
29
+ if (reported) return;
30
+ reported = true;
31
+ window.__gpDomGuardOnHit = null;
32
+ onHitRef.current({
33
+ kind,
34
+ language: navigator.language,
35
+ languages: navigator.languages?.join(',') ?? '',
36
+ documentLang: document.documentElement.lang,
37
+ // <font> sem classe é a assinatura do Google Tradutor
38
+ translatedNodes: document.querySelectorAll('font[style]').length,
39
+ path: window.location.pathname,
40
+ });
41
+ };
42
+
43
+ // Disparos que aconteceram antes deste componente montar.
44
+ const already = window.__gpDomGuard;
45
+ if (already && (already.removeChild > 0 || already.insertBefore > 0)) {
46
+ report(already.insertBefore > 0 ? 'insertBefore' : 'removeChild');
47
+ return;
48
+ }
49
+
50
+ window.__gpDomGuardOnHit = report;
51
+ return () => {
52
+ window.__gpDomGuardOnHit = null;
53
+ };
54
+ }, []);
55
+ }
@@ -39,14 +39,24 @@ export interface ResolveLocaleOptions {
39
39
  userLanguage?: string | null;
40
40
  }
41
41
 
42
+ function localeFromAcceptLanguage(header: string | null): Locale | null {
43
+ if (!header) return null;
44
+ for (const entry of header.split(',')) {
45
+ const locale = normalizeLocale(entry.split(';')[0].trim());
46
+ if (locale) return locale;
47
+ }
48
+ return null;
49
+ }
50
+
42
51
  /**
43
52
  * Resolve o locale da requisição (server-side). Ordem de prioridade:
44
53
  *
45
54
  * 1. **Whitelabel não-padrão** (`id_wl != 1`) → `pt` (por enquanto, whitelabels não são localizadas).
46
55
  * 2. **Preferência da conta** (`userLanguage`), quando fornecida.
47
56
  * 3. **Cookie `NEXT_LOCALE`** — cache da preferência ou escolha manual do visitante.
48
- * 4. **Inferência por país** — JWT (`session.location.country`) ou header `CF-IPCountry`.
49
- * 5. **Fallback** → {@link DEFAULT_LOCALE}.
57
+ * 4. **Header `Accept-Language`** do navegador.
58
+ * 5. **Inferência por país** — JWT (`session.location.country`) ou header `CF-IPCountry`.
59
+ * 6. **Fallback** → {@link DEFAULT_LOCALE}.
50
60
  */
51
61
  export async function resolveLocale(options: ResolveLocaleOptions = {}): Promise<Locale> {
52
62
  const cookieStore = await cookies();
@@ -67,12 +77,17 @@ export async function resolveLocale(options: ResolveLocaleOptions = {}): Promise
67
77
  const fromCookie = normalizeLocale(cookieStore.get(LOCALE_COOKIE)?.value);
68
78
  if (fromCookie) return fromCookie;
69
79
 
70
- // 4. Inferência por país (geo)
71
80
  const headersList = await headers();
81
+
82
+ // 4. Header Accept-Language do navegador
83
+ const fromAcceptLanguage = localeFromAcceptLanguage(headersList.get('accept-language'));
84
+ if (fromAcceptLanguage) return fromAcceptLanguage;
85
+
86
+ // 5. Inferência por país (geo)
72
87
  const country = jwt?.country ?? headersList.get(GEO_HEADER);
73
88
  const fromGeo = localeFromCountry(country);
74
89
  if (fromGeo) return fromGeo;
75
90
 
76
- // 5. Fallback
91
+ // 6. Fallback
77
92
  return DEFAULT_LOCALE;
78
93
  }
package/src/index.ts CHANGED
@@ -515,6 +515,9 @@ export { default as usePasswordVisibility } from "./hooks/usePasswordVisibility"
515
515
  export { default as useCountdownTimer } from "./hooks/useCountdownTimer";
516
516
  export { default as useIsMobile } from "./hooks/useIsMobile";
517
517
  export { useDebounce } from "./hooks/useDebounce";
518
+ export { useDomMutationGuardHit } from "./hooks/useDomMutationGuardHit";
519
+ export type { DomMutationGuardHit } from "./hooks/useDomMutationGuardHit";
520
+ export { DOM_MUTATION_GUARD_SCRIPT } from "./utils/dom/dom-mutation-guard";
518
521
  export { useDebouncedEffect } from "./hooks/useDebouncedEffect";
519
522
  export { useDebounceState } from "./hooks/useDebounceState";
520
523
 
@@ -41,6 +41,8 @@ import {
41
41
  VerifyEmailResponse,
42
42
  } from "../schema";
43
43
  import { findWhitelabel } from "../../../server";
44
+ import { resolveLocale } from "../../../i18n/resolve-locale";
45
+ import { localeToApiLanguage } from "../../../utils/intl/locales";
44
46
 
45
47
  const AUTH_COOKIE_NAME = "greatapps";
46
48
  const COOKIE_MAX_AGE = 60 * 60 * 24 * 30;
@@ -295,12 +297,15 @@ class AuthService {
295
297
 
296
298
  const idPlan = await this.resolvePlanId(data.idPlan);
297
299
 
300
+ const whitelabel = await findWhitelabel().catch(() => null);
301
+ const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));
302
+
298
303
  const payload = {
299
304
  onboarding_token: data.onboardingToken,
300
305
  name: data.user.name,
301
306
  bussiness_type: data.businessType ?? 0,
302
- language: "pt-br",
303
- timezone: "America/Sao_Paulo",
307
+ language,
308
+ timezone: clientInfo.timezone,
304
309
  currency: "BRL",
305
310
  location: clientInfo.location,
306
311
  ip: clientInfo.ip,
@@ -317,7 +322,7 @@ class AuthService {
317
322
  ddi: data.user.ddi || "55",
318
323
  phone: data.user.phone || "",
319
324
  profile: "owner",
320
- language: "pt-br",
325
+ language,
321
326
  },
322
327
  subscription:
323
328
  isFreePlan(idPlan)
@@ -411,11 +416,14 @@ class AuthService {
411
416
 
412
417
  const idPlan = await this.resolvePlanId(data.idPlan);
413
418
 
419
+ const whitelabel = await findWhitelabel().catch(() => null);
420
+ const language = localeToApiLanguage(await resolveLocale({ whitelabelId: whitelabel?.id ?? null }));
421
+
414
422
  const payload: RegisterApiRequest = {
415
423
  name: data.accountName,
416
424
  bussiness_type: data.businessType ?? 0,
417
- language: "pt-br",
418
- timezone: "America/Sao_Paulo",
425
+ language,
426
+ timezone: clientInfo.timezone,
419
427
  currency: "BRL",
420
428
  location: clientInfo.location,
421
429
  ip: clientInfo.ip,
@@ -433,7 +441,7 @@ class AuthService {
433
441
  phone: data.phone,
434
442
  password: data.password,
435
443
  profile: "owner",
436
- language: "pt-br",
444
+ language,
437
445
  },
438
446
  subscription:
439
447
  isFreePlan(idPlan)
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Guarda contra mutação externa do DOM (tradutor do navegador, extensões).
3
+ *
4
+ * PROBLEMA: o Google Tradutor do Chrome substitui cada text node por `<font><font>…</font></font>`.
5
+ * O React continua guardando a referência do text node ORIGINAL no fiber. No commit seguinte ele
6
+ * chama `parent.insertBefore(novo, textNodeAntigo)` ou `parent.removeChild(textNodeAntigo)` — e o nó
7
+ * já não é mais filho daquele pai. O DOM levanta `NotFoundError`, o erro sobe até o root e o app
8
+ * inteiro cai no `global-error.tsx` (evento `render.root_crashed` no Sentry).
9
+ *
10
+ * Isso derrubou clientes reais em CO/PE/MX/AR/FR (zero casos no BR, onde a página já está no idioma
11
+ * do usuário e o Chrome não oferece tradução), inclusive em cima da tela de trocar cartão — o cliente
12
+ * ficava sem conseguir pagar.
13
+ *
14
+ * SOLUÇÃO: transformar essas duas operações em no-op quando o nó de referência já não pertence mais
15
+ * ao pai. O React segue adiante, a página não morre, e o trecho traduzido apenas deixa de receber
16
+ * aquela atualização pontual (o próximo re-render completo normaliza).
17
+ *
18
+ * Precisa rodar ANTES da hidratação, por isso é injetado como `<script>` inline no `<head>` do root
19
+ * layout em vez de virar um `useEffect`.
20
+ */
21
+
22
+ declare global {
23
+ interface Window {
24
+ /** Contadores de quantas vezes a guarda entrou em ação nesta sessão. */
25
+ __gpDomGuard?: { removeChild: number; insertBefore: number };
26
+ /** Hook opcional preenchido pelo reporter para avisar o Sentry no primeiro disparo. */
27
+ __gpDomGuardOnHit?: ((kind: 'removeChild' | 'insertBefore') => void) | null;
28
+ }
29
+ }
30
+
31
+ export const DOM_MUTATION_GUARD_SCRIPT = `(function(){
32
+ if(typeof Node==="undefined"||!Node.prototype)return;
33
+ if(window.__gpDomGuard)return;
34
+ var s={removeChild:0,insertBefore:0};
35
+ window.__gpDomGuard=s;
36
+ window.__gpDomGuardOnHit=window.__gpDomGuardOnHit||null;
37
+ function hit(k){s[k]++;try{if(window.__gpDomGuardOnHit)window.__gpDomGuardOnHit(k)}catch(e){}}
38
+ var removeChild=Node.prototype.removeChild;
39
+ Node.prototype.removeChild=function(child){
40
+ if(child&&child.parentNode!==this){hit("removeChild");return child}
41
+ return removeChild.apply(this,arguments)};
42
+ var insertBefore=Node.prototype.insertBefore;
43
+ Node.prototype.insertBefore=function(newNode,referenceNode){
44
+ if(referenceNode&&referenceNode.parentNode!==this){hit("insertBefore");return newNode}
45
+ return insertBefore.apply(this,arguments)};
46
+ })();`;
@@ -1,3 +1,5 @@
1
+ import { Locale } from '../../i18n/config';
2
+
1
3
  export type LocaleOption = {
2
4
  value: string;
3
5
  label: string;
@@ -14,3 +16,8 @@ export const LANGUAGE_OPTIONS: LocaleOption[] = [
14
16
  export function buildLocaleOptions(): LocaleOption[] {
15
17
  return LANGUAGE_OPTIONS;
16
18
  }
19
+
20
+ export function localeToApiLanguage(locale: Locale): string {
21
+ const option = LANGUAGE_OPTIONS.find((o) => o.value === locale);
22
+ return option?.apiValue ?? locale;
23
+ }