@hook-sdk/template 0.5.0 → 0.6.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.cjs +39 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -2
- package/dist/index.d.ts +63 -2
- package/dist/index.js +35 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -2,7 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode, ComponentType, Component } from 'react';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import * as _hook_sdk_sdk from '@hook-sdk/sdk';
|
|
5
|
-
import { ReminderSlot } from '@hook-sdk/sdk';
|
|
5
|
+
import { PlanState, ReminderSlot } from '@hook-sdk/sdk';
|
|
6
|
+
export { PlanInfo, PlanState } from '@hook-sdk/sdk';
|
|
6
7
|
|
|
7
8
|
declare const AppConfigSchema: z.ZodObject<{
|
|
8
9
|
$schema: z.ZodOptional<z.ZodString>;
|
|
@@ -288,6 +289,66 @@ declare function usePaywallState(): {
|
|
|
288
289
|
error: Error | null;
|
|
289
290
|
};
|
|
290
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Thin wrapper sobre `useHook().plan`. Existe pra apps importarem "tudo
|
|
294
|
+
* que precisam" via `@hook-sdk/template` sem mudar de package pra cada
|
|
295
|
+
* primitive, e pra manter espaço pra evoluir a API (ex: expor campos
|
|
296
|
+
* derivados como `monthlyEquivalent()`) sem mexer no SDK.
|
|
297
|
+
*
|
|
298
|
+
* Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:
|
|
299
|
+
*
|
|
300
|
+
* const { data, initialLoadComplete } = usePlan();
|
|
301
|
+
* if (!initialLoadComplete) return <Skeleton />;
|
|
302
|
+
* if (!data) return null;
|
|
303
|
+
* return <span>{formatBRL(data.priceCents)}</span>;
|
|
304
|
+
*/
|
|
305
|
+
declare function usePlan(): PlanState;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Helpers de formatação de preço pro Hook.
|
|
309
|
+
*
|
|
310
|
+
* Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço
|
|
311
|
+
* leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam
|
|
312
|
+
* inline. Isso evita os dois patterns errados que já vimos em conversões
|
|
313
|
+
* Lovable→Hook: (a) strings hardcoded "R$ 19,90" no JSX, (b) divisões ad-hoc
|
|
314
|
+
* por 100 + `toFixed(2)` que ignoram locale.
|
|
315
|
+
*
|
|
316
|
+
* Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.
|
|
317
|
+
*/
|
|
318
|
+
/**
|
|
319
|
+
* Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência
|
|
320
|
+
* (callers que lidam com `yearlyPriceCents: number | null`).
|
|
321
|
+
*
|
|
322
|
+
* Examples:
|
|
323
|
+
* formatBRL(1990) → "R$ 19,90"
|
|
324
|
+
* formatBRL(4999) → "R$ 49,99"
|
|
325
|
+
* formatBRL(23988) → "R$ 239,88"
|
|
326
|
+
* formatBRL(0) → "R$ 0,00"
|
|
327
|
+
* formatBRL(null) → ""
|
|
328
|
+
*/
|
|
329
|
+
declare function formatBRL(cents: number | null | undefined): string;
|
|
330
|
+
/**
|
|
331
|
+
* Deriva "preço mensal" a partir do preço anual (em centavos). Round half-up
|
|
332
|
+
* pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.
|
|
333
|
+
*
|
|
334
|
+
* Não assume que o creator configurou yearlyPriceCents "redondo": se ele
|
|
335
|
+
* setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880
|
|
336
|
+
* (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).
|
|
337
|
+
*
|
|
338
|
+
* Example (papomaterno):
|
|
339
|
+
* monthlyFromYearly(23988) = 1999 → formatBRL = "R$ 19,99"
|
|
340
|
+
* monthlyFromYearly(23880) = 1990 → formatBRL = "R$ 19,90"
|
|
341
|
+
*/
|
|
342
|
+
declare function monthlyFromYearly(yearlyCents: number | null | undefined): number;
|
|
343
|
+
/**
|
|
344
|
+
* Deriva "preço por dia" (365 dias) a partir do anual, em centavos. Útil
|
|
345
|
+
* pra copy tipo "apenas R$ 0,66 por dia, menos que um café".
|
|
346
|
+
*
|
|
347
|
+
* Example:
|
|
348
|
+
* dailyFromYearly(23988) = 66 → formatBRL = "R$ 0,66"
|
|
349
|
+
*/
|
|
350
|
+
declare function dailyFromYearly(yearlyCents: number | null | undefined): number;
|
|
351
|
+
|
|
291
352
|
/**
|
|
292
353
|
* Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).
|
|
293
354
|
* Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.
|
|
@@ -493,4 +554,4 @@ declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
|
|
|
493
554
|
*/
|
|
494
555
|
declare function shouldShowPermanentOption(state: InstallState): boolean;
|
|
495
556
|
|
|
496
|
-
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|
|
557
|
+
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, formatBRL, monthlyFromYearly, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
2
2
|
import { ReactNode, ComponentType, Component } from 'react';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import * as _hook_sdk_sdk from '@hook-sdk/sdk';
|
|
5
|
-
import { ReminderSlot } from '@hook-sdk/sdk';
|
|
5
|
+
import { PlanState, ReminderSlot } from '@hook-sdk/sdk';
|
|
6
|
+
export { PlanInfo, PlanState } from '@hook-sdk/sdk';
|
|
6
7
|
|
|
7
8
|
declare const AppConfigSchema: z.ZodObject<{
|
|
8
9
|
$schema: z.ZodOptional<z.ZodString>;
|
|
@@ -288,6 +289,66 @@ declare function usePaywallState(): {
|
|
|
288
289
|
error: Error | null;
|
|
289
290
|
};
|
|
290
291
|
|
|
292
|
+
/**
|
|
293
|
+
* Thin wrapper sobre `useHook().plan`. Existe pra apps importarem "tudo
|
|
294
|
+
* que precisam" via `@hook-sdk/template` sem mudar de package pra cada
|
|
295
|
+
* primitive, e pra manter espaço pra evoluir a API (ex: expor campos
|
|
296
|
+
* derivados como `monthlyEquivalent()`) sem mexer no SDK.
|
|
297
|
+
*
|
|
298
|
+
* Retorna o PlanState bruto. Use junto com helpers de `@hook-sdk/template`:
|
|
299
|
+
*
|
|
300
|
+
* const { data, initialLoadComplete } = usePlan();
|
|
301
|
+
* if (!initialLoadComplete) return <Skeleton />;
|
|
302
|
+
* if (!data) return null;
|
|
303
|
+
* return <span>{formatBRL(data.priceCents)}</span>;
|
|
304
|
+
*/
|
|
305
|
+
declare function usePlan(): PlanState;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Helpers de formatação de preço pro Hook.
|
|
309
|
+
*
|
|
310
|
+
* Preço vive no banco em CENTAVOS (int), sempre. Apps que renderizam preço
|
|
311
|
+
* leem do hook `usePlan()` e passam por `formatBRL(cents)` — nunca formatam
|
|
312
|
+
* inline. Isso evita os dois patterns errados que já vimos em conversões
|
|
313
|
+
* Lovable→Hook: (a) strings hardcoded "R$ 19,90" no JSX, (b) divisões ad-hoc
|
|
314
|
+
* por 100 + `toFixed(2)` que ignoram locale.
|
|
315
|
+
*
|
|
316
|
+
* Ver G72 em .claude/skills/lovable-to-hook/catalog/known-gotchas.md.
|
|
317
|
+
*/
|
|
318
|
+
/**
|
|
319
|
+
* Formata centavos como BRL no locale pt-BR. Aceita null pra conveniência
|
|
320
|
+
* (callers que lidam com `yearlyPriceCents: number | null`).
|
|
321
|
+
*
|
|
322
|
+
* Examples:
|
|
323
|
+
* formatBRL(1990) → "R$ 19,90"
|
|
324
|
+
* formatBRL(4999) → "R$ 49,99"
|
|
325
|
+
* formatBRL(23988) → "R$ 239,88"
|
|
326
|
+
* formatBRL(0) → "R$ 0,00"
|
|
327
|
+
* formatBRL(null) → ""
|
|
328
|
+
*/
|
|
329
|
+
declare function formatBRL(cents: number | null | undefined): string;
|
|
330
|
+
/**
|
|
331
|
+
* Deriva "preço mensal" a partir do preço anual (em centavos). Round half-up
|
|
332
|
+
* pra evitar R$ 19,899... → R$ 19,89 quando o usuário esperava R$ 19,90.
|
|
333
|
+
*
|
|
334
|
+
* Não assume que o creator configurou yearlyPriceCents "redondo": se ele
|
|
335
|
+
* setou 23988 (= R$ 239,88), 23988/12 = 1999 (= R$ 19,99). Se setou 23880
|
|
336
|
+
* (= R$ 238,80), 23880/12 = 1990 (= R$ 19,90).
|
|
337
|
+
*
|
|
338
|
+
* Example (papomaterno):
|
|
339
|
+
* monthlyFromYearly(23988) = 1999 → formatBRL = "R$ 19,99"
|
|
340
|
+
* monthlyFromYearly(23880) = 1990 → formatBRL = "R$ 19,90"
|
|
341
|
+
*/
|
|
342
|
+
declare function monthlyFromYearly(yearlyCents: number | null | undefined): number;
|
|
343
|
+
/**
|
|
344
|
+
* Deriva "preço por dia" (365 dias) a partir do anual, em centavos. Útil
|
|
345
|
+
* pra copy tipo "apenas R$ 0,66 por dia, menos que um café".
|
|
346
|
+
*
|
|
347
|
+
* Example:
|
|
348
|
+
* dailyFromYearly(23988) = 66 → formatBRL = "R$ 0,66"
|
|
349
|
+
*/
|
|
350
|
+
declare function dailyFromYearly(yearlyCents: number | null | undefined): number;
|
|
351
|
+
|
|
291
352
|
/**
|
|
292
353
|
* Escape hatch pra screens FORA do fluxo de auth (ex: settings/trocar-senha).
|
|
293
354
|
* Pra LoginScreen/SignupScreen/ForgotScreen custom, use useLoginForm/useSignupForm/useForgotForm.
|
|
@@ -493,4 +554,4 @@ declare function shouldBlockInstall(state: InstallState, now?: number): boolean;
|
|
|
493
554
|
*/
|
|
494
555
|
declare function shouldShowPermanentOption(state: InstallState): boolean;
|
|
495
556
|
|
|
496
|
-
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|
|
557
|
+
export { type AndroidBrowser, AppRoot, type AppRootProps, type AuthFormError, type AuthFormErrorCode, type AuthScreen, type AuthScreenProps, DefaultForgotScreen, DefaultLoginScreen, DefaultPaywall, DefaultResetScreen, DefaultSignupScreen, EmptyState, ErrorBoundary, type IOSBrowser, type InAppApp, type InstallActions, InstallGate, InstallSplash, type InstallState, type InstallVariant, LoadingState, type Platform, PushPrompt, type PushPromptProps, type PushPromptTexts, type PushUiState, type SubscriptionStatus, type ToastItem, type UseLoginFormResult, type UseResetFormResult, dailyFromYearly, detectAndroidBrowser, detectIOSBrowser, detectInAppApp, detectPlatform, detectStandalone, formatBRL, monthlyFromYearly, shouldBlockInstall, shouldShowPermanentOption, useAuth, useAuthPrimitives, useForgotForm, useInstallPrompt, useLoginForm, usePaywallState, usePlan, usePush, useReminders, useResetForm, useSignupForm, useSubscription, useToast };
|
package/dist/index.js
CHANGED
|
@@ -2327,12 +2327,37 @@ function EmptyState({ title, description, action }) {
|
|
|
2327
2327
|
] });
|
|
2328
2328
|
}
|
|
2329
2329
|
|
|
2330
|
+
// src/hooks/usePlan.ts
|
|
2331
|
+
import { useHook as useHook10 } from "@hook-sdk/sdk";
|
|
2332
|
+
function usePlan() {
|
|
2333
|
+
const { plan } = useHook10();
|
|
2334
|
+
return plan;
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
// src/utils/price.ts
|
|
2338
|
+
function formatBRL(cents) {
|
|
2339
|
+
if (cents === null || cents === void 0) return "";
|
|
2340
|
+
const reais = cents / 100;
|
|
2341
|
+
return new Intl.NumberFormat("pt-BR", {
|
|
2342
|
+
style: "currency",
|
|
2343
|
+
currency: "BRL"
|
|
2344
|
+
}).format(reais);
|
|
2345
|
+
}
|
|
2346
|
+
function monthlyFromYearly(yearlyCents) {
|
|
2347
|
+
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2348
|
+
return Math.round(yearlyCents / 12);
|
|
2349
|
+
}
|
|
2350
|
+
function dailyFromYearly(yearlyCents) {
|
|
2351
|
+
if (yearlyCents === null || yearlyCents === void 0) return 0;
|
|
2352
|
+
return Math.round(yearlyCents / 365);
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2330
2355
|
// src/hooks/useAuthPrimitives.ts
|
|
2331
2356
|
import { useEffect as useEffect9 } from "react";
|
|
2332
|
-
import { useHook as
|
|
2357
|
+
import { useHook as useHook11 } from "@hook-sdk/sdk";
|
|
2333
2358
|
var warned = false;
|
|
2334
2359
|
function useAuthPrimitives() {
|
|
2335
|
-
const { auth } =
|
|
2360
|
+
const { auth } = useHook11();
|
|
2336
2361
|
useEffect9(() => {
|
|
2337
2362
|
if (!warned && process.env.NODE_ENV !== "production") {
|
|
2338
2363
|
warned = true;
|
|
@@ -2355,9 +2380,9 @@ function useAuthPrimitives() {
|
|
|
2355
2380
|
}
|
|
2356
2381
|
|
|
2357
2382
|
// src/hooks/useSubscription.ts
|
|
2358
|
-
import { useHook as
|
|
2383
|
+
import { useHook as useHook12 } from "@hook-sdk/sdk";
|
|
2359
2384
|
function useSubscription() {
|
|
2360
|
-
const { subscription } =
|
|
2385
|
+
const { subscription } = useHook12();
|
|
2361
2386
|
return {
|
|
2362
2387
|
status: subscription.status()
|
|
2363
2388
|
};
|
|
@@ -2365,9 +2390,9 @@ function useSubscription() {
|
|
|
2365
2390
|
|
|
2366
2391
|
// src/hooks/useReminders.ts
|
|
2367
2392
|
import { useCallback as useCallback9, useEffect as useEffect10, useState as useState13 } from "react";
|
|
2368
|
-
import { useHook as
|
|
2393
|
+
import { useHook as useHook13 } from "@hook-sdk/sdk";
|
|
2369
2394
|
function useReminders() {
|
|
2370
|
-
const { push } =
|
|
2395
|
+
const { push } = useHook13();
|
|
2371
2396
|
const r = push.reminders;
|
|
2372
2397
|
const [reminders, setReminders] = useState13([]);
|
|
2373
2398
|
const [loading, setLoading] = useState13(true);
|
|
@@ -2429,11 +2454,14 @@ export {
|
|
|
2429
2454
|
InstallSplash,
|
|
2430
2455
|
LoadingState,
|
|
2431
2456
|
PushPrompt2 as PushPrompt,
|
|
2457
|
+
dailyFromYearly,
|
|
2432
2458
|
detectAndroidBrowser,
|
|
2433
2459
|
detectIOSBrowser,
|
|
2434
2460
|
detectInAppApp,
|
|
2435
2461
|
detectPlatform,
|
|
2436
2462
|
detectStandalone,
|
|
2463
|
+
formatBRL,
|
|
2464
|
+
monthlyFromYearly,
|
|
2437
2465
|
shouldBlockInstall,
|
|
2438
2466
|
shouldShowPermanentOption,
|
|
2439
2467
|
useAuth,
|
|
@@ -2442,6 +2470,7 @@ export {
|
|
|
2442
2470
|
useInstallPrompt,
|
|
2443
2471
|
useLoginForm,
|
|
2444
2472
|
usePaywallState,
|
|
2473
|
+
usePlan,
|
|
2445
2474
|
usePush,
|
|
2446
2475
|
useReminders,
|
|
2447
2476
|
useResetForm,
|