@lukoweb/apitogo-plugin-dev-portal-billing 0.1.43 → 0.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +48 -21
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import { createContext, useContext, useEffect, useState } from "react";
4
4
  import { cn, createPlugin } from "@lukoweb/apitogo";
5
5
  import { Link, Navigate, Outlet, useNavigate, useSearchParams } from "@lukoweb/apitogo/router";
6
6
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@lukoweb/apitogo/ui/AlertDialog.js";
7
+ import manifestCatalog from "virtual:apitogo-local-manifest";
7
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
9
  import { useMutation, useQuery, useQueryClient } from "@lukoweb/apitogo/react-query";
9
10
  import { useAuth } from "@lukoweb/apitogo/hooks";
@@ -24,22 +25,23 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
24
25
  if (!apiBaseUrl) return true;
25
26
  return apiBaseUrl === DEV_PORTAL_PLACEHOLDER_API_URL || apiBaseUrl.includes("dp-example.azurecontainerapps.io");
26
27
  }
27
- function parseMockPlans() {
28
- const raw = typeof VITE_APITOGO_DEV_PORTAL_MOCK_PLANS === "string" ? VITE_APITOGO_DEV_PORTAL_MOCK_PLANS.trim() : "";
29
- if (!raw) return { plans: [] };
30
- try {
31
- return { plans: JSON.parse(raw).map((plan) => ({
32
- sku: plan.sku,
33
- displayName: plan.displayName,
34
- isFree: plan.isFree ?? false,
35
- priceAmount: plan.priceAmount ?? 0,
36
- priceCurrency: plan.priceCurrency ?? "usd",
37
- billingPeriod: plan.billingPeriod ?? "monthly",
38
- limitsJson: plan.limitsJson ?? null
39
- })) };
40
- } catch {
41
- return { plans: [] };
42
- }
28
+ function parseManifestPlans() {
29
+ if (!manifestCatalog?.plans?.length) return { plans: [] };
30
+ return { plans: manifestCatalog.plans.map((plan) => ({
31
+ sku: plan.sku,
32
+ displayName: plan.displayName,
33
+ isFree: plan.isFree,
34
+ priceAmount: plan.priceAmount,
35
+ priceCurrency: plan.priceCurrency,
36
+ billingPeriod: plan.billingPeriod,
37
+ limitsJson: plan.limitsJson,
38
+ includedActionKeys: plan.includedActionKeys
39
+ })) };
40
+ }
41
+ function formatActionKey(actionKey) {
42
+ const separatorIndex = actionKey.indexOf(":");
43
+ if (separatorIndex <= 0) return actionKey;
44
+ return `${actionKey.slice(0, separatorIndex).toUpperCase()} ${actionKey.slice(separatorIndex + 1)}`;
43
45
  }
44
46
  function formatPlanPrice(plan) {
45
47
  if (plan.isFree || plan.priceAmount <= 0) return "Free";
@@ -115,6 +117,23 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
115
117
  className: "mt-4 text-sm text-muted-foreground",
116
118
  children: limitsSummary
117
119
  }) : null,
120
+ plan.includedActionKeys && plan.includedActionKeys.length > 0 ? /* @__PURE__ */ jsxs("div", {
121
+ className: "mt-4",
122
+ "data-testid": `included-endpoints-${plan.sku}`,
123
+ children: [/* @__PURE__ */ jsx("p", {
124
+ className: "text-xs font-medium uppercase tracking-wide text-muted-foreground",
125
+ children: "Included endpoints"
126
+ }), /* @__PURE__ */ jsx("ul", {
127
+ className: "mt-2 space-y-1 text-sm text-muted-foreground",
128
+ children: plan.includedActionKeys.map((actionKey) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("code", {
129
+ className: "rounded bg-muted px-1.5 py-0.5 text-xs",
130
+ children: formatActionKey(actionKey)
131
+ }) }, actionKey))
132
+ })]
133
+ }) : plan.isFree ? /* @__PURE__ */ jsx("p", {
134
+ className: "mt-4 text-sm text-muted-foreground",
135
+ children: "API access not included"
136
+ }) : null,
118
137
  /* @__PURE__ */ jsx("div", {
119
138
  className: "mt-6 space-y-2",
120
139
  children: mode === "account" ? isActive ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -252,7 +271,7 @@ function usePlans() {
252
271
  isPreview
253
272
  ],
254
273
  queryFn: async () => {
255
- if (isPreview) return parseMockPlans();
274
+ if (isPreview) return parseManifestPlans();
256
275
  if (!apiBaseUrl) return { plans: [] };
257
276
  const response = await fetch(`${apiBaseUrl}/api/v1/plans`, { headers: { Accept: "application/json" } });
258
277
  if (!response.ok) throw new Error("Failed to load plans.");
@@ -298,9 +317,17 @@ const AccountPlansPage = () => {
298
317
  })]
299
318
  })]
300
319
  }),
301
- isPreview ? /* @__PURE__ */ jsx("div", {
320
+ isPreview ? /* @__PURE__ */ jsxs("div", {
302
321
  className: "mb-8 rounded-xl border border-dashed bg-muted/20 p-6 text-center text-sm text-muted-foreground",
303
- children: "Local preview uses mock plans. Subscribe and unsubscribe activate after the portal is published."
322
+ children: [
323
+ "Local preview uses plans from",
324
+ " ",
325
+ /* @__PURE__ */ jsx("code", {
326
+ className: "rounded bg-muted px-1.5 py-0.5",
327
+ children: "apitogo.local.json"
328
+ }),
329
+ ". Subscribe and unsubscribe activate after the portal is published."
330
+ ]
304
331
  }) : null,
305
332
  cancelMutation.isError ? /* @__PURE__ */ jsx("div", {
306
333
  className: "mb-6 rounded-xl border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive",
@@ -715,11 +742,11 @@ const PricingPage = () => {
715
742
  isPreview && !auth.isAuthenticated ? /* @__PURE__ */ jsxs("div", {
716
743
  className: "mx-auto mb-8 max-w-2xl rounded-xl border border-dashed bg-muted/20 p-6 text-center text-sm text-muted-foreground",
717
744
  children: [
718
- "Local preview uses mock plans from",
745
+ "Local preview uses plans from",
719
746
  " ",
720
747
  /* @__PURE__ */ jsx("code", {
721
748
  className: "rounded bg-muted px-1.5 py-0.5",
722
- children: "VITE_APITOGO_DEV_PORTAL_MOCK_PLANS"
749
+ children: "apitogo.local.json"
723
750
  }),
724
751
  ". Checkout activates after the portal is published."
725
752
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo-plugin-dev-portal-billing",
3
- "version": "0.1.43",
3
+ "version": "0.1.44",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/zuplo/zudoku",
@@ -46,7 +46,7 @@
46
46
  "react": "19.2.4",
47
47
  "react-dom": "19.2.4",
48
48
  "tsdown": "0.20.3",
49
- "@lukoweb/apitogo": "0.1.43"
49
+ "@lukoweb/apitogo": "0.1.44"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": ">=19.2.0",