@lukoweb/apitogo-plugin-dev-portal-billing 0.1.73 → 0.1.74
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 +26 -14
- package/dist/index.mjs +103 -91
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -5,17 +5,6 @@ import * as _tanstack_react_query0 from "@tanstack/react-query";
|
|
|
5
5
|
//#region src/pages/AccountPlansPage.d.ts
|
|
6
6
|
declare const AccountPlansPage: () => react_jsx_runtime0.JSX.Element;
|
|
7
7
|
//#endregion
|
|
8
|
-
//#region src/components/ApiKeysPanel.d.ts
|
|
9
|
-
/**
|
|
10
|
-
* Lists the developer's gateway API keys with create and revoke. The plaintext key is returned by the
|
|
11
|
-
* platform exactly once, so it is held in local state until dismissed and never re-fetched.
|
|
12
|
-
*/
|
|
13
|
-
declare const ApiKeysPanel: ({
|
|
14
|
-
readOnly
|
|
15
|
-
}: {
|
|
16
|
-
readOnly?: boolean;
|
|
17
|
-
}) => react_jsx_runtime0.JSX.Element;
|
|
18
|
-
//#endregion
|
|
19
8
|
//#region src/types.d.ts
|
|
20
9
|
type DevPortalApiKey = {
|
|
21
10
|
id: string;
|
|
@@ -26,11 +15,16 @@ type DevPortalApiKey = {
|
|
|
26
15
|
revokedAtUtc: string | null; /** Present only in the response to a successful create; never returned again. */
|
|
27
16
|
key: string | null;
|
|
28
17
|
};
|
|
29
|
-
type
|
|
18
|
+
type DevPortalApiKeyPlan = {
|
|
19
|
+
planSku: string;
|
|
20
|
+
displayName: string;
|
|
30
21
|
keys: DevPortalApiKey[];
|
|
31
22
|
activeCount: number; /** Per-developer cap from the project's platform plan; null means unlimited. */
|
|
32
23
|
maxKeys: number | null;
|
|
33
|
-
canCreate: boolean;
|
|
24
|
+
canCreate: boolean;
|
|
25
|
+
};
|
|
26
|
+
type DevPortalApiKeyListResponse = {
|
|
27
|
+
plans: DevPortalApiKeyPlan[]; /** Header the key must be sent in when calling the gateway. */
|
|
34
28
|
header: string;
|
|
35
29
|
gatewayBaseUrl: string | null;
|
|
36
30
|
};
|
|
@@ -50,6 +44,21 @@ type DevPortalBillingConfig = {
|
|
|
50
44
|
}>;
|
|
51
45
|
};
|
|
52
46
|
//#endregion
|
|
47
|
+
//#region src/components/ApiKeysPanel.d.ts
|
|
48
|
+
/**
|
|
49
|
+
* Lists gateway API keys for one plan with create and revoke. The plaintext key is returned by the
|
|
50
|
+
* platform exactly once, so it is held in local state until dismissed and never re-fetched.
|
|
51
|
+
*/
|
|
52
|
+
declare const ApiKeysPanel: ({
|
|
53
|
+
plan,
|
|
54
|
+
header,
|
|
55
|
+
readOnly
|
|
56
|
+
}: {
|
|
57
|
+
plan: DevPortalApiKeyPlan;
|
|
58
|
+
header: string;
|
|
59
|
+
readOnly?: boolean;
|
|
60
|
+
}) => react_jsx_runtime0.JSX.Element;
|
|
61
|
+
//#endregion
|
|
53
62
|
//#region src/paths.d.ts
|
|
54
63
|
declare const PRICING_PATH = "/pricing";
|
|
55
64
|
declare const CHECKOUT_PATH = "/checkout";
|
|
@@ -171,7 +180,10 @@ declare function useApiKeys(): _tanstack_react_query0.QueryObserverRefetchErrorR
|
|
|
171
180
|
fetchStatus: _tanstack_react_query0.FetchStatus;
|
|
172
181
|
promise: Promise<DevPortalApiKeyListResponse>;
|
|
173
182
|
};
|
|
174
|
-
declare function useCreateApiKey(): _tanstack_react_query0.UseMutationResult<DevPortalApiKey, Error,
|
|
183
|
+
declare function useCreateApiKey(): _tanstack_react_query0.UseMutationResult<DevPortalApiKey, Error, {
|
|
184
|
+
name: string;
|
|
185
|
+
planSku: string;
|
|
186
|
+
}, unknown>;
|
|
175
187
|
declare function useRevokeApiKey(): _tanstack_react_query0.UseMutationResult<void, Error, string, unknown>;
|
|
176
188
|
//#endregion
|
|
177
189
|
export { API_KEY_CAP_REACHED, AccountPlansPage, ApiKeysPanel, CHECKOUT_PATH, CREDENTIALS_PATH, PRICING_PATH, SUBSCRIPTIONS_PATH, devPortalBillingPlugin, useApiKeys, useCreateApiKey, useRevokeApiKey };
|
package/dist/index.mjs
CHANGED
|
@@ -177,7 +177,7 @@ const PricingCard = ({ plan, mode = "public", subscriptionStatus, isSubscribed =
|
|
|
177
177
|
variant: "secondary",
|
|
178
178
|
className: "w-full",
|
|
179
179
|
disabled: true,
|
|
180
|
-
children: "
|
|
180
|
+
children: "Subscribed"
|
|
181
181
|
}),
|
|
182
182
|
onUnsubscribe ? /* @__PURE__ */ jsxs(AlertDialog, { children: [/* @__PURE__ */ jsx(AlertDialogTrigger, {
|
|
183
183
|
asChild: true,
|
|
@@ -292,22 +292,28 @@ function useCancelSubscription() {
|
|
|
292
292
|
const DEMO_SUBSCRIPTION_KEY = "demo-subscription-key";
|
|
293
293
|
const DEMO_GATEWAY_KEY_HEADER = "Ocp-Apim-Subscription-Key";
|
|
294
294
|
const DEMO_MAX_KEYS = 5;
|
|
295
|
-
function
|
|
296
|
-
|
|
295
|
+
function resolveDemoPlans(plans) {
|
|
296
|
+
if (plans && plans.length > 0) return plans.map((plan) => ({
|
|
297
|
+
sku: plan.sku,
|
|
298
|
+
displayName: plan.displayName
|
|
299
|
+
}));
|
|
300
|
+
return [{
|
|
301
|
+
sku: "free",
|
|
302
|
+
displayName: "Free"
|
|
303
|
+
}];
|
|
297
304
|
}
|
|
298
305
|
function createDemoMeResponse(plans) {
|
|
299
|
-
const planSku = resolveDemoPlanSku(plans);
|
|
300
306
|
const periodEnd = /* @__PURE__ */ new Date();
|
|
301
307
|
periodEnd.setMonth(periodEnd.getMonth() + 1);
|
|
302
308
|
return {
|
|
303
309
|
userId: "00000000-0000-0000-0000-000000000001",
|
|
304
310
|
displayName: "Demo User",
|
|
305
|
-
subscriptions:
|
|
306
|
-
planSku,
|
|
311
|
+
subscriptions: resolveDemoPlans(plans).map((plan) => ({
|
|
312
|
+
planSku: plan.sku,
|
|
307
313
|
status: "Active",
|
|
308
314
|
entitlementState: "active",
|
|
309
315
|
currentPeriodEnd: periodEnd.toISOString()
|
|
310
|
-
}
|
|
316
|
+
}))
|
|
311
317
|
};
|
|
312
318
|
}
|
|
313
319
|
function createDemoCredentials(plans) {
|
|
@@ -315,24 +321,28 @@ function createDemoCredentials(plans) {
|
|
|
315
321
|
idToken: "demo-id-token",
|
|
316
322
|
accessToken: null,
|
|
317
323
|
gatewayBaseUrl: null,
|
|
318
|
-
|
|
324
|
+
planSkus: resolveDemoPlans(plans).map((plan) => plan.sku),
|
|
319
325
|
expiresAt: null
|
|
320
326
|
};
|
|
321
327
|
}
|
|
322
|
-
function createDemoApiKeys() {
|
|
328
|
+
function createDemoApiKeys(plans) {
|
|
323
329
|
return {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
330
|
+
plans: resolveDemoPlans(plans).map((plan, index) => ({
|
|
331
|
+
planSku: plan.sku,
|
|
332
|
+
displayName: plan.displayName,
|
|
333
|
+
keys: index === 0 ? [{
|
|
334
|
+
id: "00000000-0000-0000-0000-0000000000a1",
|
|
335
|
+
name: "default",
|
|
336
|
+
keyPrefix: DEMO_SUBSCRIPTION_KEY.slice(0, 8),
|
|
337
|
+
status: "active",
|
|
338
|
+
createdAtUtc: (/* @__PURE__ */ new Date()).toISOString(),
|
|
339
|
+
revokedAtUtc: null,
|
|
340
|
+
key: null
|
|
341
|
+
}] : [],
|
|
342
|
+
activeCount: index === 0 ? 1 : 0,
|
|
343
|
+
maxKeys: DEMO_MAX_KEYS,
|
|
344
|
+
canCreate: true
|
|
345
|
+
})),
|
|
336
346
|
header: DEMO_GATEWAY_KEY_HEADER,
|
|
337
347
|
gatewayBaseUrl: null
|
|
338
348
|
};
|
|
@@ -502,6 +512,7 @@ function useApiKeys() {
|
|
|
502
512
|
const apiBaseUrl = useDevPortalApiBaseUrl();
|
|
503
513
|
const isPreview = useDevPortalPreviewMode();
|
|
504
514
|
const isDemoSession = useIsDemoSession();
|
|
515
|
+
const { previewPlans } = useDevPortalBillingConfig();
|
|
505
516
|
const liveQuery = useQuery({
|
|
506
517
|
queryKey: apiKeysQueryKey(apiBaseUrl),
|
|
507
518
|
enabled: auth.isAuthenticated && !isPreview && !isDemoSession && Boolean(apiBaseUrl),
|
|
@@ -519,7 +530,7 @@ function useApiKeys() {
|
|
|
519
530
|
});
|
|
520
531
|
if (isDemoSession && auth.isAuthenticated) return {
|
|
521
532
|
...liveQuery,
|
|
522
|
-
data: createDemoApiKeys(),
|
|
533
|
+
data: createDemoApiKeys(previewPlans),
|
|
523
534
|
error: null,
|
|
524
535
|
isError: false,
|
|
525
536
|
isFetching: false,
|
|
@@ -534,7 +545,7 @@ function useCreateApiKey() {
|
|
|
534
545
|
const apiBaseUrl = useDevPortalApiBaseUrl();
|
|
535
546
|
const queryClient = useQueryClient();
|
|
536
547
|
return useMutation({
|
|
537
|
-
mutationFn: async (name) => {
|
|
548
|
+
mutationFn: async ({ name, planSku }) => {
|
|
538
549
|
if (!apiBaseUrl) throw new Error("Dev portal API is not configured.");
|
|
539
550
|
const response = await fetch(`${apiBaseUrl}/api/v1/api-keys`, {
|
|
540
551
|
method: "POST",
|
|
@@ -543,7 +554,10 @@ function useCreateApiKey() {
|
|
|
543
554
|
"Content-Type": "application/json"
|
|
544
555
|
},
|
|
545
556
|
credentials: "include",
|
|
546
|
-
body: JSON.stringify({
|
|
557
|
+
body: JSON.stringify({
|
|
558
|
+
name,
|
|
559
|
+
planSku
|
|
560
|
+
})
|
|
547
561
|
});
|
|
548
562
|
if (response.status === 409) throw new Error(API_KEY_CAP_REACHED);
|
|
549
563
|
if (!response.ok) throw new Error(await readProblemDetail(response) ?? "Failed to create API key.");
|
|
@@ -583,24 +597,27 @@ async function readProblemDetail(response) {
|
|
|
583
597
|
//#endregion
|
|
584
598
|
//#region src/components/ApiKeysPanel.tsx
|
|
585
599
|
/**
|
|
586
|
-
* Lists
|
|
600
|
+
* Lists gateway API keys for one plan with create and revoke. The plaintext key is returned by the
|
|
587
601
|
* platform exactly once, so it is held in local state until dismissed and never re-fetched.
|
|
588
602
|
*/
|
|
589
|
-
const ApiKeysPanel = ({ readOnly = false }) => {
|
|
590
|
-
const { data, isLoading, error } = useApiKeys();
|
|
603
|
+
const ApiKeysPanel = ({ plan, header, readOnly = false }) => {
|
|
591
604
|
const createKey = useCreateApiKey();
|
|
592
605
|
const revokeKey = useRevokeApiKey();
|
|
593
606
|
const [name, setName] = useState("");
|
|
594
607
|
const [newKey, setNewKey] = useState(null);
|
|
595
608
|
const [openRevokeId, setOpenRevokeId] = useState(null);
|
|
596
609
|
const [pendingRevokeId, setPendingRevokeId] = useState(null);
|
|
597
|
-
const activeKeys =
|
|
598
|
-
const
|
|
599
|
-
const
|
|
610
|
+
const activeKeys = plan.keys.filter((key) => key.status === "active");
|
|
611
|
+
const planActiveCount = activeKeys.length;
|
|
612
|
+
const capLabel = plan.maxKeys == null ? `${plan.activeCount} active (all plans)` : `${plan.activeCount} of ${plan.maxKeys} used (all plans)`;
|
|
613
|
+
const canCreate = !readOnly && plan.canCreate;
|
|
600
614
|
const handleCreate = () => {
|
|
601
615
|
const trimmed = name.trim();
|
|
602
616
|
if (!trimmed) return;
|
|
603
|
-
createKey.mutate(
|
|
617
|
+
createKey.mutate({
|
|
618
|
+
name: trimmed,
|
|
619
|
+
planSku: plan.planSku
|
|
620
|
+
}, { onSuccess: (key) => {
|
|
604
621
|
setNewKey(key);
|
|
605
622
|
setName("");
|
|
606
623
|
} });
|
|
@@ -619,9 +636,9 @@ const ApiKeysPanel = ({ readOnly = false }) => {
|
|
|
619
636
|
className: "flex flex-wrap items-start justify-between gap-3",
|
|
620
637
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
621
638
|
className: "space-y-1",
|
|
622
|
-
children: [/* @__PURE__ */
|
|
639
|
+
children: [/* @__PURE__ */ jsxs("h2", {
|
|
623
640
|
className: "text-lg font-medium",
|
|
624
|
-
children: "API keys"
|
|
641
|
+
children: [plan.displayName, " API keys"]
|
|
625
642
|
}), /* @__PURE__ */ jsxs("p", {
|
|
626
643
|
className: "text-sm text-muted-foreground",
|
|
627
644
|
children: [
|
|
@@ -629,16 +646,16 @@ const ApiKeysPanel = ({ readOnly = false }) => {
|
|
|
629
646
|
" ",
|
|
630
647
|
/* @__PURE__ */ jsx("code", {
|
|
631
648
|
className: "rounded bg-muted px-1 py-0.5 text-xs",
|
|
632
|
-
children:
|
|
649
|
+
children: header
|
|
633
650
|
}),
|
|
634
651
|
" ",
|
|
635
|
-
"header when calling
|
|
652
|
+
"header when calling this plan's endpoints. Keys share your developer key cap across all plans."
|
|
636
653
|
]
|
|
637
654
|
})]
|
|
638
|
-
}),
|
|
655
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
639
656
|
className: "shrink-0 rounded-full border px-3 py-1 text-xs text-muted-foreground",
|
|
640
657
|
children: capLabel
|
|
641
|
-
})
|
|
658
|
+
})]
|
|
642
659
|
}),
|
|
643
660
|
newKey?.key ? /* @__PURE__ */ jsxs(Alert, { children: [
|
|
644
661
|
/* @__PURE__ */ jsx(KeyRoundIcon, { size: 16 }),
|
|
@@ -658,23 +675,15 @@ const ApiKeysPanel = ({ readOnly = false }) => {
|
|
|
658
675
|
] }) : null,
|
|
659
676
|
createKey.isError ? /* @__PURE__ */ jsx(Alert, {
|
|
660
677
|
variant: "destructive",
|
|
661
|
-
children: /* @__PURE__ */ jsx(AlertTitle, { children: createKey.error.message === API_KEY_CAP_REACHED ?
|
|
678
|
+
children: /* @__PURE__ */ jsx(AlertTitle, { children: createKey.error.message === API_KEY_CAP_REACHED ? plan.maxKeys == null ? "You cannot create more API keys right now." : `You already have the maximum of ${plan.maxKeys} active API keys. Revoke one to create another.` : createKey.error.message })
|
|
662
679
|
}) : null,
|
|
663
680
|
revokeKey.isError ? /* @__PURE__ */ jsx(Alert, {
|
|
664
681
|
variant: "destructive",
|
|
665
682
|
children: /* @__PURE__ */ jsx(AlertTitle, { children: revokeKey.error.message })
|
|
666
683
|
}) : null,
|
|
667
|
-
|
|
668
|
-
className: "text-sm text-muted-foreground",
|
|
669
|
-
children: "Loading…"
|
|
670
|
-
}) : null,
|
|
671
|
-
error ? /* @__PURE__ */ jsx("p", {
|
|
672
|
-
className: "text-sm text-muted-foreground",
|
|
673
|
-
children: error instanceof Error && error.message === "NO_ENTITLEMENT" ? "Choose a plan to get your first API key." : "Unable to load your API keys. Try again in a moment."
|
|
674
|
-
}) : null,
|
|
675
|
-
data && activeKeys.length === 0 && !isLoading ? /* @__PURE__ */ jsx("p", {
|
|
684
|
+
planActiveCount === 0 ? /* @__PURE__ */ jsx("p", {
|
|
676
685
|
className: "text-sm text-muted-foreground",
|
|
677
|
-
children: "You have no active API keys yet."
|
|
686
|
+
children: "You have no active API keys for this plan yet."
|
|
678
687
|
}) : null,
|
|
679
688
|
activeKeys.length > 0 ? /* @__PURE__ */ jsx("ul", {
|
|
680
689
|
className: "divide-y rounded-lg border",
|
|
@@ -738,7 +747,7 @@ const ApiKeysPanel = ({ readOnly = false }) => {
|
|
|
738
747
|
className: "max-w-xs",
|
|
739
748
|
maxLength: 64,
|
|
740
749
|
placeholder: "Key name (e.g. production)",
|
|
741
|
-
"aria-label":
|
|
750
|
+
"aria-label": `New API key name for ${plan.displayName}`,
|
|
742
751
|
value: name,
|
|
743
752
|
disabled: !canCreate || createKey.isPending,
|
|
744
753
|
onChange: (event) => setName(event.target.value),
|
|
@@ -752,9 +761,9 @@ const ApiKeysPanel = ({ readOnly = false }) => {
|
|
|
752
761
|
children: createKey.isPending ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Spinner, { size: 14 }), "Creating…"] }) : "Create API key"
|
|
753
762
|
})]
|
|
754
763
|
}),
|
|
755
|
-
|
|
764
|
+
plan && !plan.canCreate && !readOnly ? /* @__PURE__ */ jsx("p", {
|
|
756
765
|
className: "text-sm text-muted-foreground",
|
|
757
|
-
children:
|
|
766
|
+
children: plan.maxKeys == null ? "API key creation is currently disabled for this API." : `You have reached your limit of ${plan.maxKeys} API keys across all plans. Revoke a key to create a new one.`
|
|
758
767
|
}) : null
|
|
759
768
|
]
|
|
760
769
|
});
|
|
@@ -981,8 +990,10 @@ const CredentialsPage = () => {
|
|
|
981
990
|
const isPreview = useDevPortalPreviewMode();
|
|
982
991
|
const isDemoSession = useIsDemoSession();
|
|
983
992
|
const { data: credentials, isLoading, error } = useCredentials();
|
|
984
|
-
const { data:
|
|
985
|
-
const
|
|
993
|
+
const { data: apiKeys, isLoading: keysLoading, error: keysError } = useApiKeys();
|
|
994
|
+
const gatewayBaseUrl = credentials?.gatewayBaseUrl ?? apiKeys?.gatewayBaseUrl ?? null;
|
|
995
|
+
const header = apiKeys?.header ?? "Ocp-Apim-Subscription-Key";
|
|
996
|
+
const plans = apiKeys?.plans ?? [];
|
|
986
997
|
return /* @__PURE__ */ jsxs("div", {
|
|
987
998
|
className: "mx-auto max-w-screen-lg px-4 pb-16 pt-(--padding-content-top) lg:px-8",
|
|
988
999
|
children: [
|
|
@@ -999,7 +1010,7 @@ const CredentialsPage = () => {
|
|
|
999
1010
|
children: "API credentials"
|
|
1000
1011
|
}), /* @__PURE__ */ jsx("p", {
|
|
1001
1012
|
className: "text-muted-foreground",
|
|
1002
|
-
children: "Create API keys and use them to authenticate requests to the API gateway."
|
|
1013
|
+
children: "Create API keys for each subscribed plan and use them to authenticate requests to the API gateway."
|
|
1003
1014
|
})]
|
|
1004
1015
|
})]
|
|
1005
1016
|
}),
|
|
@@ -1018,7 +1029,7 @@ const CredentialsPage = () => {
|
|
|
1018
1029
|
className: "rounded-xl border border-dashed p-8 text-center",
|
|
1019
1030
|
children: [/* @__PURE__ */ jsx("p", {
|
|
1020
1031
|
className: "text-muted-foreground",
|
|
1021
|
-
children: "Sign in to view your subscription
|
|
1032
|
+
children: "Sign in to view your subscription keys."
|
|
1022
1033
|
}), /* @__PURE__ */ jsx(Button$2, {
|
|
1023
1034
|
className: "mt-4",
|
|
1024
1035
|
asChild: true,
|
|
@@ -1028,15 +1039,15 @@ const CredentialsPage = () => {
|
|
|
1028
1039
|
})
|
|
1029
1040
|
})]
|
|
1030
1041
|
}) : null,
|
|
1031
|
-
!isPreview && !isDemoSession && auth.isAuthenticated && isLoading ? /* @__PURE__ */ jsx("p", {
|
|
1042
|
+
!isPreview && !isDemoSession && auth.isAuthenticated && (isLoading || keysLoading) ? /* @__PURE__ */ jsx("p", {
|
|
1032
1043
|
className: "text-muted-foreground",
|
|
1033
1044
|
children: "Loading credentials…"
|
|
1034
1045
|
}) : null,
|
|
1035
|
-
!isPreview && !isDemoSession && auth.isAuthenticated && error ? /* @__PURE__ */ jsxs("div", {
|
|
1046
|
+
!isPreview && !isDemoSession && auth.isAuthenticated && (error || keysError) ? /* @__PURE__ */ jsxs("div", {
|
|
1036
1047
|
className: "rounded-xl border border-dashed p-8 text-center",
|
|
1037
1048
|
children: [/* @__PURE__ */ jsx("p", {
|
|
1038
1049
|
className: "text-muted-foreground",
|
|
1039
|
-
children: error instanceof Error && error.message === "NO_ENTITLEMENT" ? "No active subscription found. Choose a plan to get your API key." : "Unable to load API credentials. Try again in a moment."
|
|
1050
|
+
children: error instanceof Error && error.message === "NO_ENTITLEMENT" || keysError instanceof Error && keysError.message === "NO_ENTITLEMENT" ? "No active subscription found. Choose a plan to get your API key." : "Unable to load API credentials. Try again in a moment."
|
|
1040
1051
|
}), /* @__PURE__ */ jsx(Button$2, {
|
|
1041
1052
|
className: "mt-4",
|
|
1042
1053
|
asChild: true,
|
|
@@ -1046,43 +1057,44 @@ const CredentialsPage = () => {
|
|
|
1046
1057
|
})
|
|
1047
1058
|
})]
|
|
1048
1059
|
}) : null,
|
|
1049
|
-
(isDemoSession || !isPreview) &&
|
|
1060
|
+
(isDemoSession || !isPreview) && auth.isAuthenticated && !error && !keysError && !isLoading && !keysLoading ? /* @__PURE__ */ jsxs("div", {
|
|
1050
1061
|
className: "space-y-6",
|
|
1051
|
-
children: [
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
})]
|
|
1062
|
+
children: [plans.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
1063
|
+
className: "rounded-xl border border-dashed p-8 text-center",
|
|
1064
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1065
|
+
className: "text-muted-foreground",
|
|
1066
|
+
children: "Choose a plan to get your first API key."
|
|
1067
|
+
}), /* @__PURE__ */ jsx(Button$2, {
|
|
1068
|
+
className: "mt-4",
|
|
1069
|
+
asChild: true,
|
|
1070
|
+
children: /* @__PURE__ */ jsx(Link, {
|
|
1071
|
+
to: "/account/plans",
|
|
1072
|
+
children: "View plans"
|
|
1063
1073
|
})
|
|
1064
|
-
})
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
}), credentials.gatewayBaseUrl ? /* @__PURE__ */ jsx(Value, {
|
|
1078
|
-
className: "max-w-full w-full",
|
|
1079
|
-
value: credentials.gatewayBaseUrl
|
|
1080
|
-
}) : /* @__PURE__ */ jsx("p", {
|
|
1074
|
+
})]
|
|
1075
|
+
}) : plans.map((plan) => /* @__PURE__ */ jsx(ApiKeysPanel, {
|
|
1076
|
+
plan,
|
|
1077
|
+
header,
|
|
1078
|
+
readOnly: isDemoSession
|
|
1079
|
+
}, plan.planSku)), /* @__PURE__ */ jsxs("article", {
|
|
1080
|
+
className: "rounded-xl border bg-card/60 p-6 space-y-4",
|
|
1081
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1082
|
+
className: "space-y-1",
|
|
1083
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
1084
|
+
className: "text-lg font-medium",
|
|
1085
|
+
children: "Gateway URL"
|
|
1086
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
1081
1087
|
className: "text-sm text-muted-foreground",
|
|
1082
|
-
children: "
|
|
1088
|
+
children: "Base URL for API requests through the gateway."
|
|
1083
1089
|
})]
|
|
1084
|
-
})
|
|
1085
|
-
|
|
1090
|
+
}), gatewayBaseUrl ? /* @__PURE__ */ jsx(Value, {
|
|
1091
|
+
className: "max-w-full w-full",
|
|
1092
|
+
value: gatewayBaseUrl
|
|
1093
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
1094
|
+
className: "text-sm text-muted-foreground",
|
|
1095
|
+
children: "Available after your API is deployed to the gateway."
|
|
1096
|
+
})]
|
|
1097
|
+
})]
|
|
1086
1098
|
}) : null,
|
|
1087
1099
|
/* @__PURE__ */ jsxs("div", {
|
|
1088
1100
|
className: "mt-8 flex flex-wrap gap-3",
|
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.74",
|
|
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.74"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"react": ">=19.2.0",
|