@lukoweb/apitogo-plugin-dev-portal-billing 0.1.48 → 0.1.49
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.mjs +139 -18
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -12,6 +12,8 @@ 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
17
|
|
|
16
18
|
//#region src/utils/dev-portal-api.ts
|
|
17
19
|
const DEV_PORTAL_PLACEHOLDER_API_URL = "https://dp-example.azurecontainerapps.io";
|
|
@@ -713,14 +715,25 @@ const CredentialsPage = () => {
|
|
|
713
715
|
});
|
|
714
716
|
};
|
|
715
717
|
|
|
718
|
+
//#endregion
|
|
719
|
+
//#region src/utils/pricing-config.ts
|
|
720
|
+
function isPreviewPricingEnabled() {
|
|
721
|
+
return manifestCatalog?.pricingEnabled === true;
|
|
722
|
+
}
|
|
723
|
+
|
|
716
724
|
//#endregion
|
|
717
725
|
//#region src/pages/PricingPage.tsx
|
|
718
726
|
const PricingPage = () => {
|
|
719
727
|
const { pricing } = useDevPortalBillingConfig();
|
|
720
728
|
const auth = useAuth();
|
|
721
729
|
const isPreview = useDevPortalPreviewMode();
|
|
730
|
+
const pricingEnabled = isPreviewPricingEnabled();
|
|
722
731
|
const { data: catalog, isLoading, isError } = usePlans();
|
|
723
732
|
const { data: me } = useMySubscriptions();
|
|
733
|
+
if (!pricingEnabled) return /* @__PURE__ */ jsx(Navigate, {
|
|
734
|
+
to: "/",
|
|
735
|
+
replace: true
|
|
736
|
+
});
|
|
724
737
|
if (auth.isAuthenticated) return /* @__PURE__ */ jsx(Navigate, {
|
|
725
738
|
to: "/account/plans",
|
|
726
739
|
replace: true
|
|
@@ -782,9 +795,25 @@ const PricingPage = () => {
|
|
|
782
795
|
mode: "public",
|
|
783
796
|
isSubscribed: activeSkus.has(plan.sku)
|
|
784
797
|
}, plan.sku))
|
|
785
|
-
}) : !isLoading && !isError ? /* @__PURE__ */
|
|
798
|
+
}) : !isLoading && !isError ? /* @__PURE__ */ jsxs("div", {
|
|
786
799
|
className: "mx-auto max-w-lg rounded-xl border border-dashed p-8 text-center text-sm text-muted-foreground",
|
|
787
|
-
children:
|
|
800
|
+
children: [
|
|
801
|
+
"No plans are configured yet. Add plans in",
|
|
802
|
+
" ",
|
|
803
|
+
/* @__PURE__ */ jsx("code", {
|
|
804
|
+
className: "rounded bg-muted px-1.5 py-0.5",
|
|
805
|
+
children: "apitogo.json"
|
|
806
|
+
}),
|
|
807
|
+
" ",
|
|
808
|
+
"and set",
|
|
809
|
+
" ",
|
|
810
|
+
/* @__PURE__ */ jsx("code", {
|
|
811
|
+
className: "rounded bg-muted px-1.5 py-0.5",
|
|
812
|
+
children: "pricing.enabled"
|
|
813
|
+
}),
|
|
814
|
+
" ",
|
|
815
|
+
"to true."
|
|
816
|
+
]
|
|
788
817
|
}) : null
|
|
789
818
|
]
|
|
790
819
|
});
|
|
@@ -912,14 +941,103 @@ const SubscriptionsPage = () => {
|
|
|
912
941
|
});
|
|
913
942
|
};
|
|
914
943
|
|
|
944
|
+
//#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
|
+
}
|
|
966
|
+
}
|
|
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
|
|
976
|
+
}
|
|
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;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
//#endregion
|
|
1001
|
+
//#region src/utils/navigation-plans.ts
|
|
1002
|
+
function withoutPricingNavigation(items) {
|
|
1003
|
+
if (!items?.length) return [];
|
|
1004
|
+
return items.map((item) => {
|
|
1005
|
+
if (typeof item === "string") return item;
|
|
1006
|
+
if (item.type === "link" && item.to === PRICING_PATH) return null;
|
|
1007
|
+
if (item.items?.length) {
|
|
1008
|
+
const filteredItems = withoutPricingNavigation(item.items);
|
|
1009
|
+
return {
|
|
1010
|
+
...item,
|
|
1011
|
+
items: filteredItems
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
return item;
|
|
1015
|
+
}).filter((item) => item !== null);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
915
1018
|
//#endregion
|
|
916
1019
|
//#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);
|
|
1024
|
+
return isPreviewPricingEnabled();
|
|
1025
|
+
}
|
|
917
1026
|
const devPortalBillingPlugin = createPlugin((options = {}) => ({
|
|
918
|
-
transformConfig: ({ config, merge }) =>
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1027
|
+
transformConfig: async ({ config, merge }) => {
|
|
1028
|
+
if (!await resolvePricingEnabled(config)) return merge({
|
|
1029
|
+
navigation: withoutPricingNavigation(config.navigation),
|
|
1030
|
+
header: {
|
|
1031
|
+
...config.header,
|
|
1032
|
+
navigation: withoutPricingNavigation(config.header?.navigation)
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
return merge({ header: { navigation: [...config.header?.navigation ?? [], {
|
|
1036
|
+
label: "Pricing",
|
|
1037
|
+
to: PRICING_PATH,
|
|
1038
|
+
display: "anon"
|
|
1039
|
+
}] } });
|
|
1040
|
+
},
|
|
923
1041
|
getProfileMenuItems: () => [{
|
|
924
1042
|
label: "My Subscriptions",
|
|
925
1043
|
path: SUBSCRIPTIONS_PATH,
|
|
@@ -933,15 +1051,8 @@ const devPortalBillingPlugin = createPlugin((options = {}) => ({
|
|
|
933
1051
|
category: "middle",
|
|
934
1052
|
weight: 26
|
|
935
1053
|
}],
|
|
936
|
-
getRoutes: () =>
|
|
937
|
-
|
|
938
|
-
handle: { layout: "none" },
|
|
939
|
-
children: [
|
|
940
|
-
{
|
|
941
|
-
path: PRICING_PATH,
|
|
942
|
-
handle: { layout: "default" },
|
|
943
|
-
element: /* @__PURE__ */ jsx(PricingPage, {})
|
|
944
|
-
},
|
|
1054
|
+
getRoutes: () => {
|
|
1055
|
+
const children = [
|
|
945
1056
|
{
|
|
946
1057
|
path: CHECKOUT_PATH,
|
|
947
1058
|
handle: { layout: "default" },
|
|
@@ -957,8 +1068,18 @@ const devPortalBillingPlugin = createPlugin((options = {}) => ({
|
|
|
957
1068
|
handle: { layout: "default" },
|
|
958
1069
|
element: /* @__PURE__ */ jsx(CredentialsPage, {})
|
|
959
1070
|
}
|
|
960
|
-
]
|
|
961
|
-
|
|
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
|
+
},
|
|
962
1083
|
getProtectedRoutes: () => [
|
|
963
1084
|
CHECKOUT_PATH,
|
|
964
1085
|
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.
|
|
3
|
+
"version": "0.1.49",
|
|
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
|
+
"@lukoweb/apitogo": "0.1.49"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"react": ">=19.2.0",
|