@lukoweb/apitogo-plugin-dev-portal-billing 0.1.42 → 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 +51 -25
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -4,12 +4,14 @@ 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";
10
11
  import { Alert, AlertAction, AlertDescription } from "@lukoweb/apitogo/ui/Alert";
11
12
  import { Button as Button$1 } from "@lukoweb/apitogo/ui/Button";
12
13
  import { Secret } from "@lukoweb/apitogo/ui/Secret.js";
14
+ import { Value } from "@lukoweb/apitogo/ui/Value.js";
13
15
 
14
16
  //#region src/utils/dev-portal-api.ts
15
17
  const DEV_PORTAL_PLACEHOLDER_API_URL = "https://dp-example.azurecontainerapps.io";
@@ -23,22 +25,23 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
23
25
  if (!apiBaseUrl) return true;
24
26
  return apiBaseUrl === DEV_PORTAL_PLACEHOLDER_API_URL || apiBaseUrl.includes("dp-example.azurecontainerapps.io");
25
27
  }
26
- function parseMockPlans() {
27
- const raw = typeof VITE_APITOGO_DEV_PORTAL_MOCK_PLANS === "string" ? VITE_APITOGO_DEV_PORTAL_MOCK_PLANS.trim() : "";
28
- if (!raw) return { plans: [] };
29
- try {
30
- return { plans: JSON.parse(raw).map((plan) => ({
31
- sku: plan.sku,
32
- displayName: plan.displayName,
33
- isFree: plan.isFree ?? false,
34
- priceAmount: plan.priceAmount ?? 0,
35
- priceCurrency: plan.priceCurrency ?? "usd",
36
- billingPeriod: plan.billingPeriod ?? "monthly",
37
- limitsJson: plan.limitsJson ?? null
38
- })) };
39
- } catch {
40
- return { plans: [] };
41
- }
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)}`;
42
45
  }
43
46
  function formatPlanPrice(plan) {
44
47
  if (plan.isFree || plan.priceAmount <= 0) return "Free";
@@ -114,6 +117,23 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
114
117
  className: "mt-4 text-sm text-muted-foreground",
115
118
  children: limitsSummary
116
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,
117
137
  /* @__PURE__ */ jsx("div", {
118
138
  className: "mt-6 space-y-2",
119
139
  children: mode === "account" ? isActive ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -251,7 +271,7 @@ function usePlans() {
251
271
  isPreview
252
272
  ],
253
273
  queryFn: async () => {
254
- if (isPreview) return parseMockPlans();
274
+ if (isPreview) return parseManifestPlans();
255
275
  if (!apiBaseUrl) return { plans: [] };
256
276
  const response = await fetch(`${apiBaseUrl}/api/v1/plans`, { headers: { Accept: "application/json" } });
257
277
  if (!response.ok) throw new Error("Failed to load plans.");
@@ -297,9 +317,17 @@ const AccountPlansPage = () => {
297
317
  })]
298
318
  })]
299
319
  }),
300
- isPreview ? /* @__PURE__ */ jsx("div", {
320
+ isPreview ? /* @__PURE__ */ jsxs("div", {
301
321
  className: "mb-8 rounded-xl border border-dashed bg-muted/20 p-6 text-center text-sm text-muted-foreground",
302
- 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
+ ]
303
331
  }) : null,
304
332
  cancelMutation.isError ? /* @__PURE__ */ jsx("div", {
305
333
  className: "mb-6 rounded-xl border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive",
@@ -645,11 +673,9 @@ const CredentialsPage = () => {
645
673
  className: "text-sm text-muted-foreground",
646
674
  children: "Base URL for API requests through the gateway."
647
675
  })]
648
- }), credentials.gatewayBaseUrl ? /* @__PURE__ */ jsx(Secret, {
676
+ }), credentials.gatewayBaseUrl ? /* @__PURE__ */ jsx(Value, {
649
677
  className: "max-w-full w-full",
650
- secret: credentials.gatewayBaseUrl,
651
- status: "none",
652
- noReveal: true
678
+ value: credentials.gatewayBaseUrl
653
679
  }) : /* @__PURE__ */ jsx("p", {
654
680
  className: "text-sm text-muted-foreground",
655
681
  children: "Available after your API is deployed to the gateway."
@@ -716,11 +742,11 @@ const PricingPage = () => {
716
742
  isPreview && !auth.isAuthenticated ? /* @__PURE__ */ jsxs("div", {
717
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",
718
744
  children: [
719
- "Local preview uses mock plans from",
745
+ "Local preview uses plans from",
720
746
  " ",
721
747
  /* @__PURE__ */ jsx("code", {
722
748
  className: "rounded bg-muted px-1.5 py-0.5",
723
- children: "VITE_APITOGO_DEV_PORTAL_MOCK_PLANS"
749
+ children: "apitogo.local.json"
724
750
  }),
725
751
  ". Checkout activates after the portal is published."
726
752
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo-plugin-dev-portal-billing",
3
- "version": "0.1.42",
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.42"
49
+ "@lukoweb/apitogo": "0.1.44"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": ">=19.2.0",