@lukoweb/apitogo-plugin-dev-portal-billing 0.1.49 → 0.1.51

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 +82 -89
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -12,8 +12,7 @@ import { Alert, AlertAction, AlertDescription } from "@lukoweb/apitogo/ui/Alert"
12
12
  import { Button as Button$1 } from "@lukoweb/apitogo/ui/Button";
13
13
  import { Secret } from "@lukoweb/apitogo/ui/Secret.js";
14
14
  import { Value } from "@lukoweb/apitogo/ui/Value.js";
15
- import { access, readFile } from "node:fs/promises";
16
- import path from "node:path";
15
+ import { isAuthenticationEnabled, readEffectiveManifest, resolveManifestEnv } from "@lukoweb/apitogo/local-manifest";
17
16
 
18
17
  //#region src/utils/dev-portal-api.ts
19
18
  const DEV_PORTAL_PLACEHOLDER_API_URL = "https://dp-example.azurecontainerapps.io";
@@ -326,17 +325,16 @@ const AccountPlansPage = () => {
326
325
  " ",
327
326
  /* @__PURE__ */ jsx("code", {
328
327
  className: "rounded bg-muted px-1.5 py-0.5",
329
- children: "apitogo.json"
328
+ children: "apitogo.config.json"
330
329
  }),
331
330
  ` `,
332
- "(with optional",
331
+ "(overridable via",
333
332
  " ",
334
333
  /* @__PURE__ */ jsx("code", {
335
334
  className: "rounded bg-muted px-1.5 py-0.5",
336
- children: "apitogo.local.json"
335
+ children: ".env"
337
336
  }),
338
- " ",
339
- "overrides). Subscribe and unsubscribe activate after the portal is published."
337
+ "). Subscribe and unsubscribe activate after the portal is published."
340
338
  ]
341
339
  }) : null,
342
340
  cancelMutation.isError ? /* @__PURE__ */ jsx("div", {
@@ -767,17 +765,22 @@ const PricingPage = () => {
767
765
  " ",
768
766
  /* @__PURE__ */ jsx("code", {
769
767
  className: "rounded bg-muted px-1.5 py-0.5",
770
- children: "apitogo.json"
768
+ children: "apitogo.config.json"
771
769
  }),
772
770
  ` `,
773
- "(with optional",
771
+ "(overridable via",
774
772
  " ",
775
773
  /* @__PURE__ */ jsx("code", {
776
774
  className: "rounded bg-muted px-1.5 py-0.5",
777
- children: "apitogo.local.json"
775
+ children: ".env"
778
776
  }),
779
777
  " ",
780
- "overrides). Checkout activates after the portal is published."
778
+ "with ",
779
+ /* @__PURE__ */ jsx("code", {
780
+ className: "rounded bg-muted px-1.5 py-0.5",
781
+ children: "APITOGO_CONFIG_*"
782
+ }),
783
+ "). Checkout activates after the portal is published."
781
784
  ]
782
785
  }) : null,
783
786
  isLoading ? /* @__PURE__ */ jsx("p", {
@@ -802,7 +805,7 @@ const PricingPage = () => {
802
805
  " ",
803
806
  /* @__PURE__ */ jsx("code", {
804
807
  className: "rounded bg-muted px-1.5 py-0.5",
805
- children: "apitogo.json"
808
+ children: "apitogo.config.json"
806
809
  }),
807
810
  " ",
808
811
  "and set",
@@ -942,59 +945,30 @@ const SubscriptionsPage = () => {
942
945
  };
943
946
 
944
947
  //#endregion
945
- //#region src/utils/manifest-pricing.ts
946
- const APITOGO_MANIFEST_BASE_FILENAME = "apitogo.json";
947
- const APITOGO_MANIFEST_ENV_FILES = {
948
- development: "apitogo.local.json",
949
- production: "apitogo.prod.json"
950
- };
951
- async function fileExists(filePath) {
952
- try {
953
- await access(filePath);
954
- return true;
955
- } catch {
956
- return false;
957
- }
958
- }
959
- async function readManifestFile(filePath) {
960
- try {
961
- const raw = await readFile(filePath, "utf8");
962
- return JSON.parse(raw);
963
- } catch {
964
- return null;
965
- }
948
+ //#region src/utils/auth-config.ts
949
+ const LOGIN_NAV_PATH = "/signin";
950
+ async function resolveAuthenticationNavEnabled(config) {
951
+ if (config.__meta?.authenticationEnabled !== void 0) return config.__meta.authenticationEnabled;
952
+ if (manifestCatalog?.authenticationEnabled === true) return true;
953
+ return isAuthenticationEnabled(await readEffectiveManifest(config.__meta?.rootDir ?? process.cwd(), resolveManifestEnv(process.env.NODE_ENV === "production" ? "production" : "development")));
966
954
  }
967
- function mergeManifest(base, override) {
968
- if (!base) return override;
969
- if (!override) return base;
970
- return {
971
- ...base,
972
- ...override,
973
- pricing: {
974
- ...base.pricing,
975
- ...override.pricing
955
+
956
+ //#endregion
957
+ //#region src/utils/navigation-auth.ts
958
+ function withoutLoginNavigation(items) {
959
+ if (!items?.length) return [];
960
+ return items.map((item) => {
961
+ if (typeof item === "string") return item;
962
+ if ("to" in item && item.to === LOGIN_NAV_PATH) return null;
963
+ if (item.items?.length) {
964
+ const filteredItems = withoutLoginNavigation(item.items);
965
+ return {
966
+ ...item,
967
+ items: filteredItems
968
+ };
976
969
  }
977
- };
978
- }
979
- async function readEffectiveManifest(rootDir, mode) {
980
- const resolvedRoot = path.resolve(rootDir);
981
- const env = mode === "production" ? "production" : "development";
982
- const basePath = path.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
983
- const overridePath = path.join(resolvedRoot, APITOGO_MANIFEST_ENV_FILES[env]);
984
- const hasBase = await fileExists(basePath);
985
- const hasOverride = await fileExists(overridePath);
986
- if (!hasBase) {
987
- const legacy = await readManifestFile(path.join(resolvedRoot, APITOGO_MANIFEST_ENV_FILES.development));
988
- if (legacy) return legacy;
989
- if (hasOverride) return readManifestFile(overridePath);
990
- return null;
991
- }
992
- const base = await readManifestFile(basePath);
993
- if (!hasOverride) return base;
994
- return mergeManifest(base, await readManifestFile(overridePath));
995
- }
996
- async function manifestPricingEnabled(rootDir, mode = "development") {
997
- return (await readEffectiveManifest(rootDir, mode))?.pricing?.enabled === true;
970
+ return item;
971
+ }).filter((item) => item !== null);
998
972
  }
999
973
 
1000
974
  //#endregion
@@ -1015,28 +989,50 @@ function withoutPricingNavigation(items) {
1015
989
  }).filter((item) => item !== null);
1016
990
  }
1017
991
 
992
+ //#endregion
993
+ //#region src/utils/header-navigation.ts
994
+ function hasHeaderLink(navigation, path) {
995
+ return navigation.some((item) => "to" in item && item.to === path);
996
+ }
997
+ function buildDevPortalHeaderNavigation({ navigation, pricingEnabled, authNavEnabled }) {
998
+ let items = [...navigation ?? []];
999
+ if (!pricingEnabled) items = withoutPricingNavigation(items);
1000
+ else if (!hasHeaderLink(items, PRICING_PATH)) items = [...items, {
1001
+ label: "Pricing",
1002
+ to: PRICING_PATH,
1003
+ display: "anon"
1004
+ }];
1005
+ if (!authNavEnabled) items = withoutLoginNavigation(items);
1006
+ else if (!hasHeaderLink(items, LOGIN_NAV_PATH)) items = [...items, {
1007
+ label: "Login",
1008
+ to: LOGIN_NAV_PATH,
1009
+ display: "anon"
1010
+ }];
1011
+ return items;
1012
+ }
1013
+
1018
1014
  //#endregion
1019
1015
  //#region src/DevPortalBillingPlugin.tsx
1020
- async function resolvePricingEnabled(config) {
1021
- const meta = config;
1022
- const rootDir = meta.__meta?.rootDir;
1023
- if (rootDir) return manifestPricingEnabled(rootDir, meta.__meta?.mode);
1016
+ function resolvePricingEnabled(config) {
1017
+ if (config.__meta?.pricingEnabled !== void 0) return config.__meta.pricingEnabled;
1024
1018
  return isPreviewPricingEnabled();
1025
1019
  }
1026
1020
  const devPortalBillingPlugin = createPlugin((options = {}) => ({
1027
1021
  transformConfig: async ({ config, merge }) => {
1028
- if (!await resolvePricingEnabled(config)) return merge({
1029
- navigation: withoutPricingNavigation(config.navigation),
1022
+ const pricingEnabled = resolvePricingEnabled(config);
1023
+ const authNavEnabled = !!config.authentication && await resolveAuthenticationNavEnabled(config);
1024
+ const headerNavigation = buildDevPortalHeaderNavigation({
1025
+ navigation: config.header?.navigation,
1026
+ pricingEnabled,
1027
+ authNavEnabled
1028
+ });
1029
+ return merge({
1030
+ navigation: pricingEnabled ? config.navigation : withoutPricingNavigation(config.navigation),
1030
1031
  header: {
1031
1032
  ...config.header,
1032
- navigation: withoutPricingNavigation(config.header?.navigation)
1033
+ navigation: headerNavigation
1033
1034
  }
1034
1035
  });
1035
- return merge({ header: { navigation: [...config.header?.navigation ?? [], {
1036
- label: "Pricing",
1037
- to: PRICING_PATH,
1038
- display: "anon"
1039
- }] } });
1040
1036
  },
1041
1037
  getProfileMenuItems: () => [{
1042
1038
  label: "My Subscriptions",
@@ -1051,8 +1047,15 @@ const devPortalBillingPlugin = createPlugin((options = {}) => ({
1051
1047
  category: "middle",
1052
1048
  weight: 26
1053
1049
  }],
1054
- getRoutes: () => {
1055
- const children = [
1050
+ getRoutes: () => [{
1051
+ element: /* @__PURE__ */ jsx(DevPortalBillingWrapper, { options }),
1052
+ handle: { layout: "none" },
1053
+ children: [
1054
+ {
1055
+ path: PRICING_PATH,
1056
+ handle: { layout: "default" },
1057
+ element: /* @__PURE__ */ jsx(PricingPage, {})
1058
+ },
1056
1059
  {
1057
1060
  path: CHECKOUT_PATH,
1058
1061
  handle: { layout: "default" },
@@ -1068,18 +1071,8 @@ const devPortalBillingPlugin = createPlugin((options = {}) => ({
1068
1071
  handle: { layout: "default" },
1069
1072
  element: /* @__PURE__ */ jsx(CredentialsPage, {})
1070
1073
  }
1071
- ];
1072
- if (isPreviewPricingEnabled()) children.unshift({
1073
- path: PRICING_PATH,
1074
- handle: { layout: "default" },
1075
- element: /* @__PURE__ */ jsx(PricingPage, {})
1076
- });
1077
- return [{
1078
- element: /* @__PURE__ */ jsx(DevPortalBillingWrapper, { options }),
1079
- handle: { layout: "none" },
1080
- children
1081
- }];
1082
- },
1074
+ ]
1075
+ }],
1083
1076
  getProtectedRoutes: () => [
1084
1077
  CHECKOUT_PATH,
1085
1078
  SUBSCRIPTIONS_PATH,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo-plugin-dev-portal-billing",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
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.49"
49
+ "@lukoweb/apitogo": "0.1.51"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "react": ">=19.2.0",