@hook-sdk/template 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -55,6 +55,22 @@ type DeepLinks = {
55
55
  passwordReset?: string;
56
56
  emailVerify?: string;
57
57
  };
58
+ type I18nConfig = {
59
+ defaultLocale: string;
60
+ supportedLocales: string[];
61
+ resources: Record<string, Record<string, string>>;
62
+ };
63
+ type InstallPromptConfig = {
64
+ /**
65
+ * Position of the InstallGate splash in the AppRoot render tree.
66
+ * - 'pre-auth': renders before AuthGate (legacy behavior up to template 0.18.x).
67
+ * - 'post-paywall': renders inside SubscriptionGate's children path,
68
+ * only after the user is past the paywall (trialing/active/past_due).
69
+ *
70
+ * Default: 'post-paywall' (changed in template 0.19.0 — see ADR-017 amendment).
71
+ */
72
+ position?: 'pre-auth' | 'post-paywall';
73
+ };
58
74
  type AppConfig = {
59
75
  slug: string;
60
76
  name: string;
@@ -75,8 +91,23 @@ type AppConfig = {
75
91
  persistedKeys: PersistedKey[];
76
92
  onboarding?: OnboardingConfig;
77
93
  deepLinks?: DeepLinks;
94
+ i18n?: I18nConfig;
78
95
  features_enabled?: string[];
96
+ install_prompt?: InstallPromptConfig;
79
97
  theme?: Record<string, unknown>;
98
+ /**
99
+ * G133 — Allowlist de keys em /app-data/* liberadas pré-paywall (read+write).
100
+ * Provisionado via `admin-register-app.ts` para `apps.public_app_data_keys`
101
+ * (column adicionada na migration 0044). Apps que não declarar usam canonical
102
+ * 6 (`onboarding_data`/`notifications`/`pending_unlocks`/`physical_baseline`/
103
+ * `preferences`/`user_progress`) pelo backfill da migration.
104
+ *
105
+ * Apps com keys próprias (ex: keniafitnesss usa `profile`,
106
+ * `<slug>_onboarding_buffer`, `workout_music_on`) precisam declarar aqui
107
+ * — sem isso, post-signup o SubscriptionGate 402's nesses keys e o user
108
+ * fica em loop visual no Paywall slot.
109
+ */
110
+ publicKeys?: string[];
80
111
  };
81
112
 
82
113
  interface AuthScreenProps {
@@ -149,8 +180,14 @@ declare function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequeste
149
180
 
150
181
  interface InstallGateProps {
151
182
  children: ReactNode;
183
+ /**
184
+ * Position of the gate in the AppRoot render tree.
185
+ * Forwarded to `pwa_install_splash_shown` analytics for funnel analysis.
186
+ * AppRoot reads `config.install_prompt?.position` and passes it here.
187
+ */
188
+ position?: 'pre-auth' | 'post-paywall';
152
189
  }
153
- declare function InstallGate({ children }: InstallGateProps): react_jsx_runtime.JSX.Element;
190
+ declare function InstallGate({ children, position }: InstallGateProps): react_jsx_runtime.JSX.Element;
154
191
 
155
192
  interface InstallSplashProps {
156
193
  children: ReactNode;
@@ -159,6 +196,24 @@ interface InstallSplashProps {
159
196
  }
160
197
  declare function InstallSplash({ children, title, subtitle }: InstallSplashProps): react_jsx_runtime.JSX.Element;
161
198
 
199
+ type LanguageSwitcherProps = {
200
+ /** Optional id for label association. */
201
+ id?: string;
202
+ /** Optional CSS class for app styling. */
203
+ className?: string;
204
+ /** Optional label text; defaults to 'Language'. */
205
+ label?: string;
206
+ };
207
+ declare function LanguageSwitcher({ id, className, label }: LanguageSwitcherProps): react_jsx_runtime.JSX.Element | null;
208
+
209
+ interface I18nProviderProps {
210
+ defaultLocale: string;
211
+ supportedLocales: string[];
212
+ resources: Record<string, Record<string, string>>;
213
+ children: ReactNode;
214
+ }
215
+ declare function I18nProvider({ defaultLocale, supportedLocales, resources, children, }: I18nProviderProps): react_jsx_runtime.JSX.Element;
216
+
162
217
  declare function LoadingState({ message }: {
163
218
  message?: string;
164
219
  }): react_jsx_runtime.JSX.Element;
@@ -448,7 +503,7 @@ declare function usePlan(): PlanState;
448
503
  * Lovable→Hook: (a) strings hardcoded "R$ 19,90" no JSX, (b) divisões ad-hoc
449
504
  * por 100 + `toFixed(2)` que ignoram locale.
450
505
  *
451
- * Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.
506
+ * Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.
452
507
  */
453
508
  /**
454
509
  * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência
@@ -723,7 +778,21 @@ declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
723
778
  */
724
779
  declare function shouldShowPermanentOption(state: InstallState): boolean;
725
780
 
726
- declare function asaasErrorMessage(code: string): string;
781
+ /**
782
+ * Map Asaas error → PT-BR user-facing message.
783
+ *
784
+ * Two inputs because backend folds Asaas's specific error code into a
785
+ * compound code (`payments.capture_card.tokenize_failed:invalid_holderInfo`)
786
+ * and only the *description* string ("O CEP informado é inválido.")
787
+ * distinguishes between sub-cases of `invalid_holderInfo` (CEP, phone, name).
788
+ *
789
+ * Asaas keeps a snapshot of Correios CEPs that lags real registrations by
790
+ * months — CEPs of recently-cadastrated streets (ex: bairros novos) get
791
+ * rejected even though they're valid in ViaCEP/BrasilAPI. We don't suggest
792
+ * a fictitious CEP (would mess up nota fiscal/comms); we explain the issue
793
+ * is on the processor's side and ask user to try a nearby street's CEP.
794
+ */
795
+ declare function asaasErrorMessage(code: string, description?: string): string;
727
796
 
728
797
  type RouteBoundaryProps = {
729
798
  children: ReactNode;
@@ -864,9 +933,21 @@ declare const AppConfigSchema: z.ZodObject<{
864
933
  passwordReset: z.ZodOptional<z.ZodString>;
865
934
  emailVerify: z.ZodOptional<z.ZodString>;
866
935
  }, z.core.$strict>>;
936
+ i18n: z.ZodOptional<z.ZodObject<{
937
+ defaultLocale: z.ZodString;
938
+ supportedLocales: z.ZodArray<z.ZodString>;
939
+ resources: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>;
940
+ }, z.core.$strict>>;
867
941
  features_enabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
942
+ install_prompt: z.ZodOptional<z.ZodObject<{
943
+ position: z.ZodOptional<z.ZodEnum<{
944
+ "pre-auth": "pre-auth";
945
+ "post-paywall": "post-paywall";
946
+ }>>;
947
+ }, z.core.$strict>>;
868
948
  theme: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
949
+ publicKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
869
950
  }, z.core.$strict>;
870
951
  declare function parseAppConfig(input: unknown): AppConfig;
871
952
 
872
- export { type AndroidBrowser, type AppConfig, AppConfigProvider, AppConfigSchema, AppRoot, type AppRootProps, type AppRootSlots, type AuthFlowConfig, type AuthFormError, type AuthFormErrorCode, type AuthScreenProps, type CheckoutMethod, type Cycle, DeepLinkHandler, type DeepLinks, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type OnboardingConfig, OnboardingFlow, type OnboardingFlowProps, type OnboardingStep, type OnboardingStepCtx, type OnboardingStepDef, type PaymentMethod, PaymentReturnHandler, type PaywallConfig, type PersistedKey, PersistenceRegistry, type PersistenceRegistryProps, type PixPending, type Platform, PreAuthShell, type PreAuthShellProps, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, RouteBoundary, type RouteBoundaryProps, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, asaasErrorMessage, computeAnchorCents, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, discountPercent, formatBRL, monthlyFromYearly, parseAppConfig, shouldBlockInstall, shouldShowPermanentOption, useAppConfig, useAuth, useAuthPrimitives, useFeature, useForgotForm, useInstallPrompt, useLoginForm, useOnboardingStep, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
953
+ export { type AndroidBrowser, type AppConfig, AppConfigProvider, AppConfigSchema, AppRoot, type AppRootProps, type AppRootSlots, type AuthFlowConfig, type AuthFormError, type AuthFormErrorCode, type AuthScreenProps, type CheckoutMethod, type Cycle, DeepLinkHandler, type DeepLinks, EmptyState, ErrorBoundary, type I18nConfig, I18nProvider, type I18nProviderProps, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LanguageSwitcher, type LanguageSwitcherProps, LoadingState, type OnboardingConfig, OnboardingFlow, type OnboardingFlowProps, type OnboardingStep, type OnboardingStepCtx, type OnboardingStepDef, type PaymentMethod, PaymentReturnHandler, type PaywallConfig, type PersistedKey, PersistenceRegistry, type PersistenceRegistryProps, type PixPending, type Platform, PreAuthShell, type PreAuthShellProps, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, RouteBoundary, type RouteBoundaryProps, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, asaasErrorMessage, computeAnchorCents, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, discountPercent, formatBRL, monthlyFromYearly, parseAppConfig, shouldBlockInstall, shouldShowPermanentOption, useAppConfig, useAuth, useAuthPrimitives, useFeature, useForgotForm, useInstallPrompt, useLoginForm, useOnboardingStep, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
package/dist/index.d.ts CHANGED
@@ -55,6 +55,22 @@ type DeepLinks = {
55
55
  passwordReset?: string;
56
56
  emailVerify?: string;
57
57
  };
58
+ type I18nConfig = {
59
+ defaultLocale: string;
60
+ supportedLocales: string[];
61
+ resources: Record<string, Record<string, string>>;
62
+ };
63
+ type InstallPromptConfig = {
64
+ /**
65
+ * Position of the InstallGate splash in the AppRoot render tree.
66
+ * - 'pre-auth': renders before AuthGate (legacy behavior up to template 0.18.x).
67
+ * - 'post-paywall': renders inside SubscriptionGate's children path,
68
+ * only after the user is past the paywall (trialing/active/past_due).
69
+ *
70
+ * Default: 'post-paywall' (changed in template 0.19.0 — see ADR-017 amendment).
71
+ */
72
+ position?: 'pre-auth' | 'post-paywall';
73
+ };
58
74
  type AppConfig = {
59
75
  slug: string;
60
76
  name: string;
@@ -75,8 +91,23 @@ type AppConfig = {
75
91
  persistedKeys: PersistedKey[];
76
92
  onboarding?: OnboardingConfig;
77
93
  deepLinks?: DeepLinks;
94
+ i18n?: I18nConfig;
78
95
  features_enabled?: string[];
96
+ install_prompt?: InstallPromptConfig;
79
97
  theme?: Record<string, unknown>;
98
+ /**
99
+ * G133 — Allowlist de keys em /app-data/* liberadas pré-paywall (read+write).
100
+ * Provisionado via `admin-register-app.ts` para `apps.public_app_data_keys`
101
+ * (column adicionada na migration 0044). Apps que não declarar usam canonical
102
+ * 6 (`onboarding_data`/`notifications`/`pending_unlocks`/`physical_baseline`/
103
+ * `preferences`/`user_progress`) pelo backfill da migration.
104
+ *
105
+ * Apps com keys próprias (ex: keniafitnesss usa `profile`,
106
+ * `<slug>_onboarding_buffer`, `workout_music_on`) precisam declarar aqui
107
+ * — sem isso, post-signup o SubscriptionGate 402's nesses keys e o user
108
+ * fica em loop visual no Paywall slot.
109
+ */
110
+ publicKeys?: string[];
80
111
  };
81
112
 
82
113
  interface AuthScreenProps {
@@ -149,8 +180,14 @@ declare function PushPrompt({ texts, onSubscribed, onDeclined, onInstallRequeste
149
180
 
150
181
  interface InstallGateProps {
151
182
  children: ReactNode;
183
+ /**
184
+ * Position of the gate in the AppRoot render tree.
185
+ * Forwarded to `pwa_install_splash_shown` analytics for funnel analysis.
186
+ * AppRoot reads `config.install_prompt?.position` and passes it here.
187
+ */
188
+ position?: 'pre-auth' | 'post-paywall';
152
189
  }
153
- declare function InstallGate({ children }: InstallGateProps): react_jsx_runtime.JSX.Element;
190
+ declare function InstallGate({ children, position }: InstallGateProps): react_jsx_runtime.JSX.Element;
154
191
 
155
192
  interface InstallSplashProps {
156
193
  children: ReactNode;
@@ -159,6 +196,24 @@ interface InstallSplashProps {
159
196
  }
160
197
  declare function InstallSplash({ children, title, subtitle }: InstallSplashProps): react_jsx_runtime.JSX.Element;
161
198
 
199
+ type LanguageSwitcherProps = {
200
+ /** Optional id for label association. */
201
+ id?: string;
202
+ /** Optional CSS class for app styling. */
203
+ className?: string;
204
+ /** Optional label text; defaults to 'Language'. */
205
+ label?: string;
206
+ };
207
+ declare function LanguageSwitcher({ id, className, label }: LanguageSwitcherProps): react_jsx_runtime.JSX.Element | null;
208
+
209
+ interface I18nProviderProps {
210
+ defaultLocale: string;
211
+ supportedLocales: string[];
212
+ resources: Record<string, Record<string, string>>;
213
+ children: ReactNode;
214
+ }
215
+ declare function I18nProvider({ defaultLocale, supportedLocales, resources, children, }: I18nProviderProps): react_jsx_runtime.JSX.Element;
216
+
162
217
  declare function LoadingState({ message }: {
163
218
  message?: string;
164
219
  }): react_jsx_runtime.JSX.Element;
@@ -448,7 +503,7 @@ declare function usePlan(): PlanState;
448
503
  * Lovable→Hook: (a) strings hardcoded "R$ 19,90" no JSX, (b) divisões ad-hoc
449
504
  * por 100 + `toFixed(2)` que ignoram locale.
450
505
  *
451
- * Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.
506
+ * Ver G72 em .claude/skills/hook-conversion-shared/catalog/known-gotchas.md.
452
507
  */
453
508
  /**
454
509
  * Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência
@@ -723,7 +778,21 @@ declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
723
778
  */
724
779
  declare function shouldShowPermanentOption(state: InstallState): boolean;
725
780
 
726
- declare function asaasErrorMessage(code: string): string;
781
+ /**
782
+ * Map Asaas error → PT-BR user-facing message.
783
+ *
784
+ * Two inputs because backend folds Asaas's specific error code into a
785
+ * compound code (`payments.capture_card.tokenize_failed:invalid_holderInfo`)
786
+ * and only the *description* string ("O CEP informado é inválido.")
787
+ * distinguishes between sub-cases of `invalid_holderInfo` (CEP, phone, name).
788
+ *
789
+ * Asaas keeps a snapshot of Correios CEPs that lags real registrations by
790
+ * months — CEPs of recently-cadastrated streets (ex: bairros novos) get
791
+ * rejected even though they're valid in ViaCEP/BrasilAPI. We don't suggest
792
+ * a fictitious CEP (would mess up nota fiscal/comms); we explain the issue
793
+ * is on the processor's side and ask user to try a nearby street's CEP.
794
+ */
795
+ declare function asaasErrorMessage(code: string, description?: string): string;
727
796
 
728
797
  type RouteBoundaryProps = {
729
798
  children: ReactNode;
@@ -864,9 +933,21 @@ declare const AppConfigSchema: z.ZodObject<{
864
933
  passwordReset: z.ZodOptional<z.ZodString>;
865
934
  emailVerify: z.ZodOptional<z.ZodString>;
866
935
  }, z.core.$strict>>;
936
+ i18n: z.ZodOptional<z.ZodObject<{
937
+ defaultLocale: z.ZodString;
938
+ supportedLocales: z.ZodArray<z.ZodString>;
939
+ resources: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>;
940
+ }, z.core.$strict>>;
867
941
  features_enabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
942
+ install_prompt: z.ZodOptional<z.ZodObject<{
943
+ position: z.ZodOptional<z.ZodEnum<{
944
+ "pre-auth": "pre-auth";
945
+ "post-paywall": "post-paywall";
946
+ }>>;
947
+ }, z.core.$strict>>;
868
948
  theme: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
949
+ publicKeys: z.ZodOptional<z.ZodArray<z.ZodString>>;
869
950
  }, z.core.$strict>;
870
951
  declare function parseAppConfig(input: unknown): AppConfig;
871
952
 
872
- export { type AndroidBrowser, type AppConfig, AppConfigProvider, AppConfigSchema, AppRoot, type AppRootProps, type AppRootSlots, type AuthFlowConfig, type AuthFormError, type AuthFormErrorCode, type AuthScreenProps, type CheckoutMethod, type Cycle, DeepLinkHandler, type DeepLinks, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type OnboardingConfig, OnboardingFlow, type OnboardingFlowProps, type OnboardingStep, type OnboardingStepCtx, type OnboardingStepDef, type PaymentMethod, PaymentReturnHandler, type PaywallConfig, type PersistedKey, PersistenceRegistry, type PersistenceRegistryProps, type PixPending, type Platform, PreAuthShell, type PreAuthShellProps, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, RouteBoundary, type RouteBoundaryProps, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, asaasErrorMessage, computeAnchorCents, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, discountPercent, formatBRL, monthlyFromYearly, parseAppConfig, shouldBlockInstall, shouldShowPermanentOption, useAppConfig, useAuth, useAuthPrimitives, useFeature, useForgotForm, useInstallPrompt, useLoginForm, useOnboardingStep, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
953
+ export { type AndroidBrowser, type AppConfig, AppConfigProvider, AppConfigSchema, AppRoot, type AppRootProps, type AppRootSlots, type AuthFlowConfig, type AuthFormError, type AuthFormErrorCode, type AuthScreenProps, type CheckoutMethod, type Cycle, DeepLinkHandler, type DeepLinks, EmptyState, ErrorBoundary, type I18nConfig, I18nProvider, type I18nProviderProps, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LanguageSwitcher, type LanguageSwitcherProps, LoadingState, type OnboardingConfig, OnboardingFlow, type OnboardingFlowProps, type OnboardingStep, type OnboardingStepCtx, type OnboardingStepDef, type PaymentMethod, PaymentReturnHandler, type PaywallConfig, type PersistedKey, PersistenceRegistry, type PersistenceRegistryProps, type PixPending, type Platform, PreAuthShell, type PreAuthShellProps, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, RouteBoundary, type RouteBoundaryProps, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, asaasErrorMessage, computeAnchorCents, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, discountPercent, formatBRL, monthlyFromYearly, parseAppConfig, shouldBlockInstall, shouldShowPermanentOption, useAppConfig, useAuth, useAuthPrimitives, useFeature, useForgotForm, useInstallPrompt, useLoginForm, useOnboardingStep, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };