@zuplo/zudoku-plugin-monetization 0.0.45 → 0.0.47
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.
|
@@ -148,6 +148,13 @@ const formatTieredPriceBreakdown = (opts) => {
|
|
|
148
148
|
const tierHasPositivePrice = (tier) => parseFloat(tier.flatPrice?.amount ?? "0") > 0 || parseFloat(tier.unitPrice?.amount ?? "0") > 0;
|
|
149
149
|
//#endregion
|
|
150
150
|
//#region src/utils/categorizeRateCards.ts
|
|
151
|
+
const formatInlinePrice = (opts) => {
|
|
152
|
+
const unit = parseFloat(opts.unitAmount ?? "0");
|
|
153
|
+
const flat = parseFloat(opts.flatAmount ?? "0");
|
|
154
|
+
const flatPart = flat > 0 ? formatPrice(flat, opts.currency) : "";
|
|
155
|
+
const unitPart = unit > 0 ? `${formatPrice(unit, opts.currency)}/${opts.unitLabel}` : "";
|
|
156
|
+
return (flatPart && unitPart ? `${flatPart} + ${unitPart}` : flatPart || unitPart) || void 0;
|
|
157
|
+
};
|
|
151
158
|
const categorizeRateCards = (rateCards, options) => {
|
|
152
159
|
const { currency, units, planBillingCadence } = options ?? {};
|
|
153
160
|
const quotas = [];
|
|
@@ -163,8 +170,10 @@ const categorizeRateCards = (rateCards, options) => {
|
|
|
163
170
|
return "month";
|
|
164
171
|
};
|
|
165
172
|
const firstTier = rc.price?.type === "tiered" && rc.price.tiers.length > 0 ? rc.price.tiers[0] : void 0;
|
|
166
|
-
const
|
|
167
|
-
|
|
173
|
+
const billsFromFirstUnit = !!firstTier && tierHasPositivePrice(firstTier) || rc.price?.type === "unit" && parseFloat(rc.price.amount) > 0;
|
|
174
|
+
const includedQuota = et.type === "metered" ? et.issueAfterReset ?? 0 : 0;
|
|
175
|
+
const isHardCap = et.type === "metered" && et.isSoftLimit === false;
|
|
176
|
+
if (et.type === "metered" && (isHardCap || includedQuota > 0 && !billsFromFirstUnit)) {
|
|
168
177
|
let tierPrices;
|
|
169
178
|
if (rc.price?.type === "tiered" && rc.price.tiers) tierPrices = formatTieredPriceBreakdown({
|
|
170
179
|
tiers: rc.price.tiers.map((t) => ({
|
|
@@ -176,12 +185,24 @@ const categorizeRateCards = (rateCards, options) => {
|
|
|
176
185
|
unitLabel: unitLabelFor(rc),
|
|
177
186
|
includedLabel: "Included"
|
|
178
187
|
});
|
|
188
|
+
const inlinePrice = rc.price?.type === "unit" ? formatInlinePrice({
|
|
189
|
+
unitAmount: rc.price.amount,
|
|
190
|
+
currency,
|
|
191
|
+
unitLabel: unitLabelFor(rc)
|
|
192
|
+
}) : rc.price?.type === "tiered" && rc.price.tiers.length === 1 ? formatInlinePrice({
|
|
193
|
+
flatAmount: rc.price.tiers[0].flatPrice?.amount,
|
|
194
|
+
unitAmount: rc.price.tiers[0].unitPrice?.amount,
|
|
195
|
+
currency,
|
|
196
|
+
unitLabel: unitLabelFor(rc)
|
|
197
|
+
}) : void 0;
|
|
179
198
|
quotas.push({
|
|
180
199
|
key: rc.featureKey ?? rc.key,
|
|
181
200
|
name: rc.name,
|
|
182
|
-
limit:
|
|
201
|
+
limit: includedQuota,
|
|
183
202
|
period: periodFor(rc),
|
|
184
|
-
tierPrices
|
|
203
|
+
tierPrices,
|
|
204
|
+
...inlinePrice ? { unitPrice: inlinePrice } : {},
|
|
205
|
+
...isHardCap ? { isHardCap: true } : {}
|
|
185
206
|
});
|
|
186
207
|
} else if (et.type === "metered" && rc.type === "usage_based" && rc.price) {
|
|
187
208
|
const unitLabel = unitLabelFor(rc);
|
|
@@ -195,11 +216,12 @@ const categorizeRateCards = (rateCards, options) => {
|
|
|
195
216
|
continue;
|
|
196
217
|
}
|
|
197
218
|
if (tiers.length === 1) {
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
219
|
+
const pricePart = formatInlinePrice({
|
|
220
|
+
flatAmount: tiers[0].flatPrice?.amount,
|
|
221
|
+
unitAmount: tiers[0].unitPrice?.amount,
|
|
222
|
+
currency,
|
|
223
|
+
unitLabel
|
|
224
|
+
});
|
|
203
225
|
if (pricePart) {
|
|
204
226
|
quotas.push({
|
|
205
227
|
key: rc.featureKey ?? rc.key,
|
|
@@ -249,7 +271,11 @@ const categorizeRateCards = (rateCards, options) => {
|
|
|
249
271
|
key: rc.featureKey ?? rc.key,
|
|
250
272
|
name: rc.name
|
|
251
273
|
});
|
|
252
|
-
} else if (et.type === "
|
|
274
|
+
} else if (et.type === "metered") features.push({
|
|
275
|
+
key: rc.featureKey ?? rc.key,
|
|
276
|
+
name: rc.name
|
|
277
|
+
});
|
|
278
|
+
else if (et.type === "boolean") features.push({
|
|
253
279
|
key: rc.featureKey ?? rc.key,
|
|
254
280
|
name: rc.name
|
|
255
281
|
});
|
|
@@ -520,7 +546,7 @@ const FeatureItem = ({ feature, className }) => {
|
|
|
520
546
|
//#region src/pricing-ui/QuotaItem.tsx
|
|
521
547
|
const QuotaItem = ({ quota, className }) => {
|
|
522
548
|
const hasTierBreakdown = !!quota.tierPrices && quota.tierPrices.length > 0;
|
|
523
|
-
const showQuotaLine = !quota.isPayg && !hasTierBreakdown;
|
|
549
|
+
const showQuotaLine = !quota.isPayg && (quota.isHardCap || !hasTierBreakdown);
|
|
524
550
|
return /* @__PURE__ */ jsxs("div", {
|
|
525
551
|
className: cn("flex items-start gap-2", className),
|
|
526
552
|
children: [/* @__PURE__ */ jsx(CheckIcon, { className: "w-4 h-4 text-primary shrink-0 mt-0.5" }), /* @__PURE__ */ jsxs("div", {
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { D as formatDurationAdjective, E as formatDuration, O as formatDurationInterval, T as formatPrice, _ as formatPlanPrice, a as planHasDefaultTaxBehavior, b as sameEntitlementSet, c as getPlanPriceSchedule, d as PlanEntitlements, f as PlanPhaseHeader, l as PlanPriceTag, o as subscriptionTaxLegendSentence, p as EntitlementList, r as isCustomPlan, t as PricingTable, u as PlanPriceSchedule, w as formatMinorCurrencyAmount, x as categorizeRateCards, y as comparePlanEntitlements } from "./PricingTable-
|
|
1
|
+
import { D as formatDurationAdjective, E as formatDuration, O as formatDurationInterval, T as formatPrice, _ as formatPlanPrice, a as planHasDefaultTaxBehavior, b as sameEntitlementSet, c as getPlanPriceSchedule, d as PlanEntitlements, f as PlanPhaseHeader, l as PlanPriceTag, o as subscriptionTaxLegendSentence, p as EntitlementList, r as isCustomPlan, t as PricingTable, u as PlanPriceSchedule, w as formatMinorCurrencyAmount, x as categorizeRateCards, y as comparePlanEntitlements } from "./PricingTable-Ec-BAGAS.mjs";
|
|
2
2
|
import { cn, createPlugin, joinUrl, throwIfProblemJson } from "zudoku";
|
|
3
3
|
import { AlertTriangleIcon, ArrowDownIcon, ArrowLeftRightIcon, ArrowUpIcon, BadgePercentIcon, CalendarIcon, CheckCheckIcon, CheckIcon, ChevronDownIcon, CircleSlashIcon, ClockIcon, CreditCardIcon, Grid2x2XIcon, HistoryIcon, InfoIcon, Loader2Icon, LockIcon, MoreVerticalIcon, RefreshCcw, RefreshCwIcon, Settings, ShieldIcon, StarsIcon, Trash2Icon, XIcon } from "zudoku/icons";
|
|
4
|
-
import { Link, Outlet, useLocation, useNavigate, useSearchParams } from "zudoku/router";
|
|
4
|
+
import { Link, Navigate, Outlet, useLocation, useNavigate, useSearchParams } from "zudoku/router";
|
|
5
5
|
import { useAuth, useZudoku } from "zudoku/hooks";
|
|
6
6
|
import { QueryClient, QueryClientProvider, queryOptions, useMutation, useQuery, useQueryClient, useSuspenseQuery } from "zudoku/react-query";
|
|
7
|
-
import { Button, ClientOnly, Head, Heading, Link as Link$1, Slot } from "zudoku/components";
|
|
7
|
+
import { Button, ClientOnly, Head, Heading, Link as Link$1, Slot, ZudokuError } from "zudoku/components";
|
|
8
8
|
import { createContext, use, useEffect, useMemo, useState } from "react";
|
|
9
9
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { Alert, AlertAction, AlertDescription, AlertTitle } from "zudoku/ui/Alert";
|
|
@@ -40,11 +40,27 @@ const isTaxInclusiveFromPurchaseDetails = (response) => {
|
|
|
40
40
|
return response.tax?.taxInclusive === true;
|
|
41
41
|
};
|
|
42
42
|
//#endregion
|
|
43
|
+
//#region src/deploymentName.ts
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the Zuplo deployment name from the environment.
|
|
46
|
+
*
|
|
47
|
+
* `ZUPLO_PUBLIC_DEPLOYMENT_NAME` is populated by `zuplo link`, so a missing
|
|
48
|
+
* value almost always means the project hasn't been linked yet (the common
|
|
49
|
+
* case when running the docs locally). Throw a `ZudokuError` with actionable
|
|
50
|
+
* guidance rather than a bare "not set" so the UI can surface the fix.
|
|
51
|
+
*/
|
|
52
|
+
const resolveDeploymentName = (deploymentName) => {
|
|
53
|
+
const trimmed = deploymentName?.trim();
|
|
54
|
+
if (!trimmed) throw new ZudokuError("This project is not linked to a Zuplo deployment, so the monetization plugin can't load pricing or subscriptions.", {
|
|
55
|
+
title: "Not linked to a Zuplo deployment",
|
|
56
|
+
developerHint: "Run `zuplo link` to connect this project to your Zuplo deployment. This sets the `ZUPLO_PUBLIC_DEPLOYMENT_NAME` environment variable that the monetization plugin needs."
|
|
57
|
+
});
|
|
58
|
+
return trimmed;
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
43
61
|
//#region src/hooks/useDeploymentName.ts
|
|
44
62
|
const useDeploymentName = () => {
|
|
45
|
-
|
|
46
|
-
if (!deploymentName) throw new Error("ZUPLO_PUBLIC_DEPLOYMENT_NAME is not set");
|
|
47
|
-
return deploymentName;
|
|
63
|
+
return resolveDeploymentName(useZudoku().env.ZUPLO_PUBLIC_DEPLOYMENT_NAME);
|
|
48
64
|
};
|
|
49
65
|
//#endregion
|
|
50
66
|
//#region src/hooks/usePurchaseDetails.ts
|
|
@@ -98,7 +114,8 @@ const queryClient = new QueryClient({ defaultOptions: {
|
|
|
98
114
|
...q.meta?.request?.headers
|
|
99
115
|
}
|
|
100
116
|
});
|
|
101
|
-
const
|
|
117
|
+
const queryContext = q.meta?.context;
|
|
118
|
+
const response = await fetch(queryContext?.getAuthState().isAuthenticated ? await queryContext.signRequest(request) : request);
|
|
102
119
|
await throwIfProblemJson(response);
|
|
103
120
|
if (!response.ok) throw new Error("Failed to fetch request");
|
|
104
121
|
return response.json();
|
|
@@ -128,7 +145,8 @@ const queryClient = new QueryClient({ defaultOptions: {
|
|
|
128
145
|
...init.headers
|
|
129
146
|
}
|
|
130
147
|
});
|
|
131
|
-
const
|
|
148
|
+
const mutationContext = m.meta?.context;
|
|
149
|
+
const response = await fetch(mutationContext?.getAuthState().isAuthenticated ? await mutationContext.signRequest(request) : request);
|
|
132
150
|
await throwIfProblemJson(response);
|
|
133
151
|
if (!response.ok) {
|
|
134
152
|
const errorText = await response.text();
|
|
@@ -451,17 +469,13 @@ const useUrlUtils = () => {
|
|
|
451
469
|
};
|
|
452
470
|
//#endregion
|
|
453
471
|
//#region src/pages/CheckoutPage.tsx
|
|
454
|
-
const
|
|
455
|
-
const [searchParams] = useSearchParams();
|
|
456
|
-
const planId = searchParams.get("planId");
|
|
472
|
+
const CheckoutRedirect = ({ planId }) => {
|
|
457
473
|
const zudoku = useZudoku();
|
|
458
474
|
const auth = useAuth();
|
|
459
475
|
const { generateUrl } = useUrlUtils();
|
|
460
|
-
const deploymentName = useDeploymentName();
|
|
461
|
-
if (!planId) throw new Error(`missing planId in URL`);
|
|
462
476
|
const checkoutLink = useQuery({
|
|
463
477
|
queryKey: [
|
|
464
|
-
`/v3/zudoku-metering/${
|
|
478
|
+
`/v3/zudoku-metering/${useDeploymentName()}/stripe/checkout`,
|
|
465
479
|
planId,
|
|
466
480
|
auth.profile?.sub
|
|
467
481
|
],
|
|
@@ -499,6 +513,15 @@ const CheckoutPage = () => {
|
|
|
499
513
|
})
|
|
500
514
|
});
|
|
501
515
|
};
|
|
516
|
+
const CheckoutPage = () => {
|
|
517
|
+
const [searchParams] = useSearchParams();
|
|
518
|
+
const planId = searchParams.get("planId");
|
|
519
|
+
if (!planId) return /* @__PURE__ */ jsx(Navigate, {
|
|
520
|
+
to: "/pricing",
|
|
521
|
+
replace: true
|
|
522
|
+
});
|
|
523
|
+
return /* @__PURE__ */ jsx(CheckoutRedirect, { planId });
|
|
524
|
+
};
|
|
502
525
|
//#endregion
|
|
503
526
|
//#region src/pages/ManagePaymentPage.tsx
|
|
504
527
|
const ManagePaymentPage = () => {
|
|
@@ -543,11 +566,7 @@ const ManagePaymentPage = () => {
|
|
|
543
566
|
};
|
|
544
567
|
//#endregion
|
|
545
568
|
//#region src/queries.ts
|
|
546
|
-
const getDeploymentName = (context) =>
|
|
547
|
-
const deploymentName = context.env.ZUPLO_PUBLIC_DEPLOYMENT_NAME;
|
|
548
|
-
if (!deploymentName) throw new Error("ZUPLO_PUBLIC_DEPLOYMENT_NAME is not set");
|
|
549
|
-
return deploymentName;
|
|
550
|
-
};
|
|
569
|
+
const getDeploymentName = (context) => resolveDeploymentName(context.env.ZUPLO_PUBLIC_DEPLOYMENT_NAME);
|
|
551
570
|
const pricingPageQuery = (context) => queryOptions({
|
|
552
571
|
queryKey: [`/v3/zudoku-metering/${getDeploymentName(context)}/pricing-page`],
|
|
553
572
|
meta: { context: context.getAuthState().isAuthenticated ? context : void 0 }
|
|
@@ -2745,6 +2764,9 @@ const zuploMonetizationPlugin = createPlugin((options = {}) => ({
|
|
|
2745
2764
|
queryClient.prefetchQuery(pricingPageQuery(context));
|
|
2746
2765
|
if (context.getAuthState().isAuthenticated) queryClient.prefetchQuery(subscriptionsQuery(context));
|
|
2747
2766
|
},
|
|
2767
|
+
events: { auth: ({ prev, next }) => {
|
|
2768
|
+
if (prev.isAuthenticated && !next.isAuthenticated) queryClient.removeQueries();
|
|
2769
|
+
} },
|
|
2748
2770
|
getIdentities: async (context) => {
|
|
2749
2771
|
if (!context.getAuthState().isAuthenticated) return [];
|
|
2750
2772
|
return (await queryClient.fetchQuery(subscriptionsQuery(context))).items.flatMap((sub) => sub.status !== "active" ? [] : sub.consumer.apiKeys.flatMap((apiKey) => apiKey.expiresOn && new Date(apiKey.expiresOn) < /* @__PURE__ */ new Date() ? [] : {
|
package/dist/pricing-ui.d.mts
CHANGED
|
@@ -87,6 +87,7 @@ interface Quota {
|
|
|
87
87
|
tierPrices?: string[];
|
|
88
88
|
isPayg?: boolean;
|
|
89
89
|
unitPrice?: string;
|
|
90
|
+
isHardCap?: boolean;
|
|
90
91
|
}
|
|
91
92
|
interface Feature {
|
|
92
93
|
key: string;
|
|
@@ -139,7 +140,7 @@ declare const FeatureItem: ({
|
|
|
139
140
|
}: {
|
|
140
141
|
feature: Feature;
|
|
141
142
|
className?: string;
|
|
142
|
-
}) => import("react
|
|
143
|
+
}) => import("react").JSX.Element;
|
|
143
144
|
//#endregion
|
|
144
145
|
//#region src/pricing-ui/PlanEntitlements.d.ts
|
|
145
146
|
/**
|
|
@@ -161,7 +162,7 @@ declare const PlanEntitlements: ({
|
|
|
161
162
|
billingCadence?: string;
|
|
162
163
|
units?: Record<string, string>;
|
|
163
164
|
itemClassName?: string;
|
|
164
|
-
}) => import("react
|
|
165
|
+
}) => import("react").JSX.Element;
|
|
165
166
|
//#endregion
|
|
166
167
|
//#region src/utils/formatPlanPrice.d.ts
|
|
167
168
|
type PlanPriceLabel = {
|
|
@@ -225,7 +226,7 @@ declare const PlanPriceSchedule: ({
|
|
|
225
226
|
billingCadence?: string;
|
|
226
227
|
size?: "sm" | "lg";
|
|
227
228
|
className?: string;
|
|
228
|
-
}) => import("react
|
|
229
|
+
}) => import("react").JSX.Element;
|
|
229
230
|
//#endregion
|
|
230
231
|
//#region src/pricing-ui/PlanPriceTag.d.ts
|
|
231
232
|
/**
|
|
@@ -253,7 +254,7 @@ declare const PlanPriceTag: ({
|
|
|
253
254
|
billingCadence?: string;
|
|
254
255
|
description?: boolean;
|
|
255
256
|
size?: "inline" | "lg";
|
|
256
|
-
}) => import("react
|
|
257
|
+
}) => import("react").JSX.Element;
|
|
257
258
|
//#endregion
|
|
258
259
|
//#region src/pricing-ui/PricingCard.d.ts
|
|
259
260
|
type PricingCardProps = {
|
|
@@ -269,7 +270,7 @@ declare const PricingCard: ({
|
|
|
269
270
|
units,
|
|
270
271
|
action,
|
|
271
272
|
className
|
|
272
|
-
}: PricingCardProps) => import("react
|
|
273
|
+
}: PricingCardProps) => import("react").JSX.Element | null;
|
|
273
274
|
//#endregion
|
|
274
275
|
//#region src/pricing-ui/PricingTable.d.ts
|
|
275
276
|
type PricingTableProps = {
|
|
@@ -319,7 +320,7 @@ declare const PricingTable: ({
|
|
|
319
320
|
showTaxLegend,
|
|
320
321
|
className,
|
|
321
322
|
cardClassName
|
|
322
|
-
}: PricingTableProps) => import("react
|
|
323
|
+
}: PricingTableProps) => import("react").JSX.Element;
|
|
323
324
|
//#endregion
|
|
324
325
|
//#region src/pricing-ui/QuotaItem.d.ts
|
|
325
326
|
declare const QuotaItem: ({
|
|
@@ -328,7 +329,7 @@ declare const QuotaItem: ({
|
|
|
328
329
|
}: {
|
|
329
330
|
quota: Quota;
|
|
330
331
|
className?: string;
|
|
331
|
-
}) => import("react
|
|
332
|
+
}) => import("react").JSX.Element;
|
|
332
333
|
//#endregion
|
|
333
334
|
//#region src/utils/categorizeRateCards.d.ts
|
|
334
335
|
declare const categorizeRateCards: (rateCards: RateCard[], options?: {
|
package/dist/pricing-ui.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as formatStaticEntitlementConfig, D as formatDurationAdjective, E as formatDuration, O as formatDurationInterval, S as formatTieredPriceBreakdown, T as formatPrice, _ as formatPlanPrice, a as planHasDefaultTaxBehavior, c as getPlanPriceSchedule, d as PlanEntitlements, g as getPhasePriceLabel, h as FeatureItem, i as collectDefaultTaxBehaviors, l as PlanPriceTag, m as QuotaItem, n as PricingCard, o as subscriptionTaxLegendSentence, s as taxBehaviorLegendSentence, t as PricingTable, u as PlanPriceSchedule, v as getPlanPrice, w as formatMinorCurrencyAmount, x as categorizeRateCards } from "./PricingTable-
|
|
1
|
+
import { C as formatStaticEntitlementConfig, D as formatDurationAdjective, E as formatDuration, O as formatDurationInterval, S as formatTieredPriceBreakdown, T as formatPrice, _ as formatPlanPrice, a as planHasDefaultTaxBehavior, c as getPlanPriceSchedule, d as PlanEntitlements, g as getPhasePriceLabel, h as FeatureItem, i as collectDefaultTaxBehaviors, l as PlanPriceTag, m as QuotaItem, n as PricingCard, o as subscriptionTaxLegendSentence, s as taxBehaviorLegendSentence, t as PricingTable, u as PlanPriceSchedule, v as getPlanPrice, w as formatMinorCurrencyAmount, x as categorizeRateCards } from "./PricingTable-Ec-BAGAS.mjs";
|
|
2
2
|
export { FeatureItem, PlanEntitlements, PlanPriceSchedule, PlanPriceTag, PricingCard, PricingTable, QuotaItem, categorizeRateCards, collectDefaultTaxBehaviors, formatDuration, formatDurationAdjective, formatDurationInterval, formatMinorCurrencyAmount, formatPlanPrice, formatPrice, formatStaticEntitlementConfig, formatTieredPriceBreakdown, getPhasePriceLabel, getPlanPrice, getPlanPriceSchedule, planHasDefaultTaxBehavior, subscriptionTaxLegendSentence, taxBehaviorLegendSentence };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuplo/zudoku-plugin-monetization",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.47",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/zuplo/zudoku",
|
|
@@ -31,13 +31,14 @@
|
|
|
31
31
|
"@testing-library/dom": "10.4.1",
|
|
32
32
|
"@testing-library/jest-dom": "6.9.1",
|
|
33
33
|
"@testing-library/react": "16.3.2",
|
|
34
|
-
"@types/react": "19.2.
|
|
34
|
+
"@types/react": "19.2.17",
|
|
35
35
|
"@types/react-dom": "19.2.3",
|
|
36
|
+
"@typescript/native-preview": "7.0.0-dev.20260624.1",
|
|
36
37
|
"happy-dom": "20.10.2",
|
|
37
|
-
"react": "19.2.
|
|
38
|
-
"react-dom": "19.2.
|
|
38
|
+
"react": "19.2.7",
|
|
39
|
+
"react-dom": "19.2.7",
|
|
39
40
|
"tsdown": "0.22.0",
|
|
40
|
-
"zudoku": "0.
|
|
41
|
+
"zudoku": "0.82.3"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"react": ">=19.2.0",
|
|
@@ -52,6 +53,6 @@
|
|
|
52
53
|
"scripts": {
|
|
53
54
|
"build": "tsdown",
|
|
54
55
|
"dev": "tsdown --watch",
|
|
55
|
-
"typecheck": "
|
|
56
|
+
"typecheck": "tsgo --project tsconfig.json"
|
|
56
57
|
}
|
|
57
58
|
}
|