@lukoweb/apitogo-plugin-dev-portal-billing 0.1.50 → 0.1.53

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.mts CHANGED
@@ -1,5 +1,5 @@
1
- import * as _lukoweb_apitogo0 from "@lukoweb/apitogo";
2
1
  import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as _lukoweb_apitogo_plugins0 from "@lukoweb/apitogo/plugins";
3
3
 
4
4
  //#region src/pages/AccountPlansPage.d.ts
5
5
  declare const AccountPlansPage: () => react_jsx_runtime0.JSX.Element;
@@ -9,7 +9,16 @@ type DevPortalBillingConfig = {
9
9
  pricing?: {
10
10
  title?: string;
11
11
  subtitle?: string;
12
- };
12
+ }; /** Local preview plan catalog (from `apitogo.config.json` `plans`). */
13
+ previewPlans?: Array<{
14
+ sku: string;
15
+ displayName: string;
16
+ priceAmount?: number;
17
+ priceCurrency?: string;
18
+ billingPeriod?: string;
19
+ limitsJson?: string | null;
20
+ includedActionKeys?: string[];
21
+ }>;
13
22
  };
14
23
  //#endregion
15
24
  //#region src/paths.d.ts
@@ -19,6 +28,6 @@ declare const SUBSCRIPTIONS_PATH = "/account/subscriptions";
19
28
  declare const CREDENTIALS_PATH = "/account/credentials";
20
29
  //#endregion
21
30
  //#region src/DevPortalBillingPlugin.d.ts
22
- declare const devPortalBillingPlugin: (options?: DevPortalBillingConfig | undefined) => _lukoweb_apitogo0.ApitogoPlugin;
31
+ declare const devPortalBillingPlugin: (options?: DevPortalBillingConfig | undefined) => _lukoweb_apitogo_plugins0.ApitogoPlugin;
23
32
  //#endregion
24
33
  export { AccountPlansPage, CHECKOUT_PATH, CREDENTIALS_PATH, PRICING_PATH, SUBSCRIPTIONS_PATH, devPortalBillingPlugin };
package/dist/index.mjs CHANGED
@@ -1,13 +1,15 @@
1
- import { Button, ClientOnly, Head, Heading } from "@lukoweb/apitogo/components";
1
+ import { Button, Head, Heading } from "@lukoweb/apitogo/components";
2
2
  import { CreditCardIcon, KeyRoundIcon, ShieldIcon, StarsIcon } from "@lukoweb/apitogo/icons";
3
3
  import { createContext, useContext, useEffect, useState } from "react";
4
- import { cn, createPlugin } from "@lukoweb/apitogo";
5
4
  import { Link, Navigate, Outlet, useNavigate, useSearchParams } from "@lukoweb/apitogo/router";
6
5
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@lukoweb/apitogo/ui/AlertDialog.js";
6
+ import { cn } from "@lukoweb/apitogo/ui/util.js";
7
7
  import manifestCatalog from "virtual:apitogo-local-manifest";
8
+ import zudokuConfig from "virtual:zudoku-config";
8
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
10
  import { useMutation, useQuery, useQueryClient } from "@lukoweb/apitogo/react-query";
10
11
  import { useAuth } from "@lukoweb/apitogo/hooks";
12
+ import { createPlugin } from "@lukoweb/apitogo/plugins";
11
13
  import { Alert, AlertAction, AlertDescription } from "@lukoweb/apitogo/ui/Alert";
12
14
  import { Button as Button$1 } from "@lukoweb/apitogo/ui/Button";
13
15
  import { Secret } from "@lukoweb/apitogo/ui/Secret.js";
@@ -18,25 +20,52 @@ const DEV_PORTAL_PLACEHOLDER_API_URL = "https://dp-example.azurecontainerapps.io
18
20
  function resolveDevPortalApiBaseUrl(configuredUrl) {
19
21
  const fromConfig = configuredUrl?.trim();
20
22
  if (fromConfig) return fromConfig.replace(/\/+$/, "");
21
- const envUrl = typeof VITE_APITOGO_DEV_PORTAL_API_URL === "string" ? VITE_APITOGO_DEV_PORTAL_API_URL.trim() : "";
23
+ const envUrl = (typeof VITE_APITOGO_AUTHENTICATION_API_BASE_URL === "string" ? VITE_APITOGO_AUTHENTICATION_API_BASE_URL.trim() : "") || (typeof VITE_APITOGO_DEV_PORTAL_API_URL === "string" ? VITE_APITOGO_DEV_PORTAL_API_URL.trim() : "");
22
24
  return envUrl ? envUrl.replace(/\/+$/, "") : void 0;
23
25
  }
24
26
  function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
25
27
  if (!apiBaseUrl) return true;
26
28
  return apiBaseUrl === DEV_PORTAL_PLACEHOLDER_API_URL || apiBaseUrl.includes("dp-example.azurecontainerapps.io");
27
29
  }
28
- function parseManifestPlans() {
29
- if (!manifestCatalog?.plans?.length) return { plans: [] };
30
- return { plans: manifestCatalog.plans.map((plan) => ({
30
+ function mapPreviewPlans(plans) {
31
+ return plans.map((plan) => ({
31
32
  sku: plan.sku,
32
33
  displayName: plan.displayName,
33
- isFree: plan.isFree,
34
34
  priceAmount: plan.priceAmount,
35
35
  priceCurrency: plan.priceCurrency,
36
36
  billingPeriod: plan.billingPeriod,
37
37
  limitsJson: plan.limitsJson,
38
38
  includedActionKeys: plan.includedActionKeys
39
- })) };
39
+ }));
40
+ }
41
+ function readModulePlanItems() {
42
+ const items = (zudokuConfig?.modules)?.userPanel?.plans?.items;
43
+ return Array.isArray(items) && items.length > 0 ? items : void 0;
44
+ }
45
+ function parseManifestPlans(configPlans) {
46
+ if (configPlans?.length) return { plans: mapPreviewPlans(configPlans.map((plan) => ({
47
+ sku: plan.sku,
48
+ displayName: plan.displayName,
49
+ priceAmount: plan.priceAmount ?? 0,
50
+ priceCurrency: plan.priceCurrency ?? "usd",
51
+ billingPeriod: plan.billingPeriod ?? "monthly",
52
+ limitsJson: plan.limitsJson ?? null,
53
+ includedActionKeys: plan.includedActionKeys ?? []
54
+ }))) };
55
+ if (manifestCatalog?.plans?.length) return { plans: mapPreviewPlans(manifestCatalog.plans) };
56
+ const metaPlans = zudokuConfig?.__meta?.previewPlans;
57
+ if (metaPlans?.length) return { plans: mapPreviewPlans(metaPlans) };
58
+ const moduleItems = readModulePlanItems();
59
+ if (moduleItems?.length) return { plans: mapPreviewPlans(moduleItems.map((plan) => ({
60
+ sku: plan.sku,
61
+ displayName: plan.displayName,
62
+ priceAmount: plan.priceAmount ?? 0,
63
+ priceCurrency: plan.priceCurrency ?? "usd",
64
+ billingPeriod: plan.billingPeriod ?? "monthly",
65
+ limitsJson: plan.limitsJson ?? null,
66
+ includedActionKeys: plan.includedActionKeys ?? []
67
+ }))) };
68
+ return { plans: [] };
40
69
  }
41
70
  function formatActionKey(actionKey) {
42
71
  const separatorIndex = actionKey.indexOf(":");
@@ -44,7 +73,7 @@ function formatActionKey(actionKey) {
44
73
  return `${actionKey.slice(0, separatorIndex).toUpperCase()} ${actionKey.slice(separatorIndex + 1)}`;
45
74
  }
46
75
  function formatPlanPrice(plan) {
47
- if (plan.isFree || plan.priceAmount <= 0) return "Free";
76
+ if (plan.priceAmount <= 0) return "Free";
48
77
  const amount = new Intl.NumberFormat(void 0, {
49
78
  style: "currency",
50
79
  currency: plan.priceCurrency.toUpperCase(),
@@ -55,6 +84,9 @@ function formatPlanPrice(plan) {
55
84
  if (period === "annual" || period === "year") return `${amount}/yr`;
56
85
  return amount;
57
86
  }
87
+ function isPlanFree(plan) {
88
+ return plan.priceAmount <= 0;
89
+ }
58
90
  function formatBillingPeriod(period) {
59
91
  const normalized = period.toLowerCase();
60
92
  if (normalized === "month" || normalized === "monthly") return "Monthly";
@@ -130,7 +162,7 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
130
162
  children: formatActionKey(actionKey)
131
163
  }) }, actionKey))
132
164
  })]
133
- }) : plan.isFree ? /* @__PURE__ */ jsx("p", {
165
+ }) : isPlanFree(plan) ? /* @__PURE__ */ jsx("p", {
134
166
  className: "mt-4 text-sm text-muted-foreground",
135
167
  children: "API access not included"
136
168
  }) : null,
@@ -171,7 +203,7 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
171
203
  asChild: true,
172
204
  children: /* @__PURE__ */ jsx(Link, {
173
205
  to: `/checkout?planSku=${encodeURIComponent(plan.sku)}`,
174
- children: plan.isFree ? "Get started" : "Subscribe"
206
+ children: isPlanFree(plan) ? "Get started" : "Subscribe"
175
207
  })
176
208
  }) : isActive ? /* @__PURE__ */ jsx(Button, {
177
209
  variant: "secondary",
@@ -187,7 +219,7 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
187
219
  asChild: true,
188
220
  children: /* @__PURE__ */ jsx(Link, {
189
221
  to: `/checkout?planSku=${encodeURIComponent(plan.sku)}`,
190
- children: plan.isFree ? "Get started" : "Subscribe"
222
+ children: isPlanFree(plan) ? "Get started" : "Subscribe"
191
223
  })
192
224
  })
193
225
  })
@@ -195,6 +227,15 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
195
227
  });
196
228
  };
197
229
 
230
+ //#endregion
231
+ //#region src/DevPortalBillingContext.tsx
232
+ const DevPortalBillingContext = createContext({});
233
+ const DevPortalBillingProvider = ({ options, children }) => /* @__PURE__ */ jsx(DevPortalBillingContext.Provider, {
234
+ value: options,
235
+ children
236
+ });
237
+ const useDevPortalBillingConfig = () => useContext(DevPortalBillingContext);
238
+
198
239
  //#endregion
199
240
  //#region src/hooks/useDevPortalApiBaseUrl.ts
200
241
  function useDevPortalApiBaseUrl() {
@@ -264,27 +305,45 @@ function useMySubscriptions() {
264
305
  function usePlans() {
265
306
  const apiBaseUrl = useDevPortalApiBaseUrl();
266
307
  const isPreview = useDevPortalPreviewMode();
267
- return useQuery({
268
- queryKey: [
269
- "dev-portal-plans",
270
- apiBaseUrl,
271
- isPreview
272
- ],
308
+ const { previewPlans } = useDevPortalBillingConfig();
309
+ const liveQuery = useQuery({
310
+ queryKey: ["dev-portal-plans", apiBaseUrl],
311
+ enabled: !isPreview && Boolean(apiBaseUrl),
273
312
  queryFn: async () => {
274
- if (isPreview) return parseManifestPlans();
275
313
  if (!apiBaseUrl) return { plans: [] };
276
314
  const response = await fetch(`${apiBaseUrl}/api/v1/plans`, { headers: { Accept: "application/json" } });
277
315
  if (!response.ok) throw new Error("Failed to load plans.");
278
316
  return await response.json();
279
317
  }
280
318
  });
319
+ if (isPreview) {
320
+ const data = parseManifestPlans(previewPlans);
321
+ return {
322
+ ...liveQuery,
323
+ data,
324
+ dataUpdatedAt: Date.now(),
325
+ error: null,
326
+ fetchStatus: "idle",
327
+ isError: false,
328
+ isFetching: false,
329
+ isLoading: false,
330
+ isPending: false,
331
+ isSuccess: true,
332
+ status: "success"
333
+ };
334
+ }
335
+ return liveQuery;
281
336
  }
282
337
 
283
338
  //#endregion
284
339
  //#region src/pages/AccountPlansPage.tsx
285
340
  const AccountPlansPage = () => {
341
+ const { previewPlans } = useDevPortalBillingConfig();
286
342
  const isPreview = useDevPortalPreviewMode();
287
- const { data: catalog, isLoading, isError } = usePlans();
343
+ const livePlans = usePlans();
344
+ const catalog = isPreview ? parseManifestPlans(previewPlans) : livePlans.data;
345
+ const isLoading = isPreview ? false : livePlans.isLoading;
346
+ const isError = isPreview ? false : livePlans.isError;
288
347
  const { data: me } = useMySubscriptions();
289
348
  const cancelMutation = useCancelSubscription();
290
349
  const [cancelingSku, setCancelingSku] = useState(null);
@@ -324,17 +383,16 @@ const AccountPlansPage = () => {
324
383
  " ",
325
384
  /* @__PURE__ */ jsx("code", {
326
385
  className: "rounded bg-muted px-1.5 py-0.5",
327
- children: "apitogo.json"
386
+ children: "apitogo.config.json"
328
387
  }),
329
388
  ` `,
330
- "(with optional",
389
+ "(overridable via",
331
390
  " ",
332
391
  /* @__PURE__ */ jsx("code", {
333
392
  className: "rounded bg-muted px-1.5 py-0.5",
334
- children: "apitogo.local.json"
393
+ children: ".env"
335
394
  }),
336
- " ",
337
- "overrides). Subscribe and unsubscribe activate after the portal is published."
395
+ "). Subscribe and unsubscribe activate after the portal is published."
338
396
  ]
339
397
  }) : null,
340
398
  cancelMutation.isError ? /* @__PURE__ */ jsx("div", {
@@ -372,20 +430,11 @@ const AccountPlansPage = () => {
372
430
  });
373
431
  };
374
432
 
375
- //#endregion
376
- //#region src/DevPortalBillingContext.tsx
377
- const DevPortalBillingContext = createContext({});
378
- const DevPortalBillingProvider = ({ options, children }) => /* @__PURE__ */ jsx(DevPortalBillingContext.Provider, {
379
- value: options,
380
- children
381
- });
382
- const useDevPortalBillingConfig = () => useContext(DevPortalBillingContext);
383
-
384
433
  //#endregion
385
434
  //#region src/DevPortalBillingWrapper.tsx
386
435
  const DevPortalBillingWrapper = ({ options = {} }) => /* @__PURE__ */ jsx(DevPortalBillingProvider, {
387
436
  options,
388
- children: /* @__PURE__ */ jsx(ClientOnly, { children: /* @__PURE__ */ jsx(Outlet, {}) })
437
+ children: /* @__PURE__ */ jsx(Outlet, {})
389
438
  });
390
439
 
391
440
  //#endregion
@@ -436,6 +485,7 @@ const PRICING_PATH = "/pricing";
436
485
  const CHECKOUT_PATH = "/checkout";
437
486
  const SUBSCRIPTIONS_PATH = "/account/subscriptions";
438
487
  const CREDENTIALS_PATH = "/account/credentials";
488
+ const LOGIN_NAV_PATH = "/signin";
439
489
 
440
490
  //#endregion
441
491
  //#region src/pages/CheckoutPage.tsx
@@ -474,7 +524,7 @@ const CheckoutPage = () => {
474
524
  return await response.json();
475
525
  }
476
526
  });
477
- const freeProvisioned = checkoutQuery.data?.isFree === true && checkoutQuery.data.entitlementProvisioned === true;
527
+ const freeProvisioned = checkoutQuery.data?.checkoutUrl == null && checkoutQuery.data?.entitlementProvisioned === true;
478
528
  useEffect(() => {
479
529
  if (freeProvisioned) navigate("/account/subscriptions?checkout=success", { replace: true });
480
530
  }, [freeProvisioned, navigate]);
@@ -716,23 +766,27 @@ const CredentialsPage = () => {
716
766
  //#endregion
717
767
  //#region src/utils/pricing-config.ts
718
768
  function isPreviewPricingEnabled() {
719
- return manifestCatalog?.pricingEnabled === true;
769
+ if (manifestCatalog?.pricingEnabled === true) return true;
770
+ return zudokuConfig?.__meta?.pricingEnabled === true;
720
771
  }
721
772
 
722
773
  //#endregion
723
774
  //#region src/pages/PricingPage.tsx
724
775
  const PricingPage = () => {
725
- const { pricing } = useDevPortalBillingConfig();
776
+ const { pricing, previewPlans } = useDevPortalBillingConfig();
726
777
  const auth = useAuth();
727
778
  const isPreview = useDevPortalPreviewMode();
728
- const pricingEnabled = isPreviewPricingEnabled();
729
- const { data: catalog, isLoading, isError } = usePlans();
779
+ const pricingEnabled = isPreviewPricingEnabled() || isPreview;
780
+ const livePlans = usePlans();
781
+ const catalog = isPreview ? parseManifestPlans(previewPlans) : livePlans.data;
782
+ const isLoading = isPreview ? false : livePlans.isLoading;
783
+ const isError = isPreview ? false : livePlans.isError;
730
784
  const { data: me } = useMySubscriptions();
731
785
  if (!pricingEnabled) return /* @__PURE__ */ jsx(Navigate, {
732
786
  to: "/",
733
787
  replace: true
734
788
  });
735
- if (auth.isAuthenticated) return /* @__PURE__ */ jsx(Navigate, {
789
+ if (auth.sessionChecked && auth.isAuthenticated && !isPreview) return /* @__PURE__ */ jsx(Navigate, {
736
790
  to: "/account/plans",
737
791
  replace: true
738
792
  });
@@ -765,17 +819,22 @@ const PricingPage = () => {
765
819
  " ",
766
820
  /* @__PURE__ */ jsx("code", {
767
821
  className: "rounded bg-muted px-1.5 py-0.5",
768
- children: "apitogo.json"
822
+ children: "apitogo.config.json"
769
823
  }),
770
824
  ` `,
771
- "(with optional",
825
+ "(overridable via",
772
826
  " ",
773
827
  /* @__PURE__ */ jsx("code", {
774
828
  className: "rounded bg-muted px-1.5 py-0.5",
775
- children: "apitogo.local.json"
829
+ children: ".env"
776
830
  }),
831
+ " with",
777
832
  " ",
778
- "overrides). Checkout activates after the portal is published."
833
+ /* @__PURE__ */ jsx("code", {
834
+ className: "rounded bg-muted px-1.5 py-0.5",
835
+ children: "APITOGO_CONFIG_*"
836
+ }),
837
+ "). Checkout activates after the portal is published."
779
838
  ]
780
839
  }) : null,
781
840
  isLoading ? /* @__PURE__ */ jsx("p", {
@@ -800,14 +859,14 @@ const PricingPage = () => {
800
859
  " ",
801
860
  /* @__PURE__ */ jsx("code", {
802
861
  className: "rounded bg-muted px-1.5 py-0.5",
803
- children: "apitogo.json"
862
+ children: "apitogo.config.json"
804
863
  }),
805
864
  " ",
806
865
  "and set",
807
866
  " ",
808
867
  /* @__PURE__ */ jsx("code", {
809
868
  className: "rounded bg-muted px-1.5 py-0.5",
810
- children: "pricing.enabled"
869
+ children: "modules.userPanel.plans.enabled"
811
870
  }),
812
871
  " ",
813
872
  "to true."
@@ -939,8 +998,45 @@ const SubscriptionsPage = () => {
939
998
  });
940
999
  };
941
1000
 
1001
+ //#endregion
1002
+ //#region src/utils/auth-config.ts
1003
+ async function resolveAuthenticationNavEnabled(config) {
1004
+ if (config.__meta?.authenticationEnabled !== void 0) return config.__meta.authenticationEnabled;
1005
+ return manifestCatalog?.authenticationEnabled === true;
1006
+ }
1007
+
1008
+ //#endregion
1009
+ //#region src/utils/navigation-auth.ts
1010
+ function withoutLoginNavigation(items) {
1011
+ if (!items?.length) return [];
1012
+ return items.map((item) => {
1013
+ if (typeof item === "string") return item;
1014
+ if ("to" in item && item.to === LOGIN_NAV_PATH) return null;
1015
+ if (item.items?.length) {
1016
+ const filteredItems = withoutLoginNavigation(item.items);
1017
+ return {
1018
+ ...item,
1019
+ items: filteredItems
1020
+ };
1021
+ }
1022
+ return item;
1023
+ }).filter((item) => item !== null);
1024
+ }
1025
+
942
1026
  //#endregion
943
1027
  //#region src/utils/navigation-plans.ts
1028
+ function hasPricingLink(items) {
1029
+ return items.some((item) => typeof item !== "string" && item.type === "link" && item.to === PRICING_PATH);
1030
+ }
1031
+ function withPricingNavigation(items) {
1032
+ const current = items ?? [];
1033
+ if (hasPricingLink(current)) return current;
1034
+ return [...current, {
1035
+ type: "link",
1036
+ to: PRICING_PATH,
1037
+ label: "Pricing"
1038
+ }];
1039
+ }
944
1040
  function withoutPricingNavigation(items) {
945
1041
  if (!items?.length) return [];
946
1042
  return items.map((item) => {
@@ -958,32 +1054,49 @@ function withoutPricingNavigation(items) {
958
1054
  }
959
1055
 
960
1056
  //#endregion
961
- //#region src/DevPortalBillingPlugin.tsx
962
- function isNodeRuntime() {
963
- return typeof process !== "undefined" && typeof process.versions?.node === "string";
1057
+ //#region src/utils/header-navigation.ts
1058
+ function hasHeaderLink(navigation, path) {
1059
+ return navigation.some((item) => "to" in item && item.to === path);
964
1060
  }
965
- async function resolvePricingEnabled(config) {
966
- const rootDir = config.__meta?.rootDir;
967
- if (rootDir && isNodeRuntime()) {
968
- const { isPricingEnabled, readEffectiveManifest, resolveManifestEnv } = await import("@lukoweb/apitogo/local-manifest");
969
- return isPricingEnabled(await readEffectiveManifest(rootDir, resolveManifestEnv(config.__meta?.mode ?? "development")));
970
- }
1061
+ function buildDevPortalHeaderNavigation({ navigation, pricingEnabled, authNavEnabled }) {
1062
+ let items = [...navigation ?? []];
1063
+ if (!pricingEnabled) items = withoutPricingNavigation(items);
1064
+ else if (!hasHeaderLink(items, PRICING_PATH)) items = [...items, {
1065
+ label: "Pricing",
1066
+ to: PRICING_PATH,
1067
+ display: "anon"
1068
+ }];
1069
+ if (!authNavEnabled) items = withoutLoginNavigation(items);
1070
+ else if (!hasHeaderLink(items, LOGIN_NAV_PATH)) items = [...items, {
1071
+ label: "Login",
1072
+ to: LOGIN_NAV_PATH,
1073
+ display: "anon"
1074
+ }];
1075
+ return items;
1076
+ }
1077
+
1078
+ //#endregion
1079
+ //#region src/DevPortalBillingPlugin.tsx
1080
+ function resolvePricingEnabled(config) {
1081
+ if (config.__meta?.pricingEnabled !== void 0) return config.__meta.pricingEnabled;
971
1082
  return isPreviewPricingEnabled();
972
1083
  }
973
1084
  const devPortalBillingPlugin = createPlugin((options = {}) => ({
974
1085
  transformConfig: async ({ config, merge }) => {
975
- if (!await resolvePricingEnabled(config)) return merge({
976
- navigation: withoutPricingNavigation(config.navigation),
1086
+ const pricingEnabled = resolvePricingEnabled(config);
1087
+ const authNavEnabled = !!config.authentication && await resolveAuthenticationNavEnabled(config);
1088
+ const headerNavigation = buildDevPortalHeaderNavigation({
1089
+ navigation: config.header?.navigation,
1090
+ pricingEnabled,
1091
+ authNavEnabled
1092
+ });
1093
+ return merge({
1094
+ navigation: pricingEnabled ? withPricingNavigation(config.navigation) : withoutPricingNavigation(config.navigation),
977
1095
  header: {
978
1096
  ...config.header,
979
- navigation: withoutPricingNavigation(config.header?.navigation)
1097
+ navigation: headerNavigation
980
1098
  }
981
1099
  });
982
- return merge({ header: { navigation: [...config.header?.navigation ?? [], {
983
- label: "Pricing",
984
- to: PRICING_PATH,
985
- display: "anon"
986
- }] } });
987
1100
  },
988
1101
  getProfileMenuItems: () => [{
989
1102
  label: "My Subscriptions",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo-plugin-dev-portal-billing",
3
- "version": "0.1.50",
3
+ "version": "0.1.53",
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.50"
49
+ "@lukoweb/apitogo": "0.1.53"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": ">=19.2.0",