@lukoweb/apitogo 0.2.54 → 0.2.56
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/cli/cli.js +1192 -834
- package/dist/declarations/cli/platform/client/platform-api.d.ts +23 -0
- package/dist/declarations/cli/platform/helpers/platform-plan-catalog.d.ts +6 -0
- package/docs/cli/walkthrough.md +1 -1
- package/package.json +1 -1
- package/src/config/v2/services.ts +12 -13
- package/src/config/v2/wrapper.ts +14 -0
|
@@ -246,6 +246,27 @@ export interface DevPortalEmailDnsRecordDto {
|
|
|
246
246
|
value: string;
|
|
247
247
|
ttlSeconds?: number | null;
|
|
248
248
|
}
|
|
249
|
+
export interface PlatformPlanDto {
|
|
250
|
+
id: string;
|
|
251
|
+
displayName: string;
|
|
252
|
+
tagline: string;
|
|
253
|
+
priceAmount: string;
|
|
254
|
+
pricePeriod: string;
|
|
255
|
+
ctaLabel: string;
|
|
256
|
+
sortOrder: number;
|
|
257
|
+
highlights: string[];
|
|
258
|
+
entitlements: {
|
|
259
|
+
featureKey: string;
|
|
260
|
+
valueType: string;
|
|
261
|
+
value: string;
|
|
262
|
+
}[];
|
|
263
|
+
}
|
|
264
|
+
export interface BillingWebhookStatusDto {
|
|
265
|
+
webhookSecretConfigured: boolean;
|
|
266
|
+
lastEventAtUtc: string | null;
|
|
267
|
+
lastEventType: string | null;
|
|
268
|
+
eventCount: number;
|
|
269
|
+
}
|
|
249
270
|
export interface DevPortalBackendDto {
|
|
250
271
|
fqdn: string | null;
|
|
251
272
|
containerAppName: string;
|
|
@@ -573,6 +594,8 @@ export declare class PlatformApiClient {
|
|
|
573
594
|
cancelUrl?: string;
|
|
574
595
|
}): Promise<DevPortalBillingDto>;
|
|
575
596
|
linkDevPortalIdentity(projectId: string): Promise<DevPortalIdentityLinkDto>;
|
|
597
|
+
listPlatformPlans(): Promise<PlatformPlanDto[]>;
|
|
598
|
+
getBillingWebhookStatus(projectId: string): Promise<BillingWebhookStatusDto | null>;
|
|
576
599
|
getDevPortalBackend(projectId: string): Promise<DevPortalBackendDto | null>;
|
|
577
600
|
getDevPortalSetupStatus(projectId: string): Promise<DevPortalSetupStatusDto>;
|
|
578
601
|
getDevPortalSettings(projectId: string): Promise<DevPortalSettingsDto | null>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PlatformPlanDto } from "../client/platform-api.js";
|
|
1
2
|
import type { FreeProjectsQuota } from "./free-projects-quota.js";
|
|
2
3
|
export type PlatformPlanId = "free" | "starter" | "professional";
|
|
3
4
|
export interface PlatformPlanOption {
|
|
@@ -12,6 +13,11 @@ export interface PlatformPlanOption {
|
|
|
12
13
|
limitations: string[];
|
|
13
14
|
}
|
|
14
15
|
export declare const PLATFORM_PLAN_CATALOG: PlatformPlanOption[];
|
|
16
|
+
export type PlatformPlanDisplay = Pick<PlatformPlanOption, "displayName" | "priceLabel" | "summary" | "features" | "limitations"> & {
|
|
17
|
+
id: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function toPlanDisplays(plans: readonly PlatformPlanDto[]): PlatformPlanDisplay[];
|
|
20
|
+
export declare function loadPlanDisplays(listPlatformPlans: () => Promise<PlatformPlanDto[]>): Promise<PlatformPlanDisplay[]>;
|
|
15
21
|
export declare const PLATFORM_PLAN_USER_PROMPT = "Which API ToGo platform plan do you want for this project \u2014 Free, Starter, or Professional?";
|
|
16
22
|
export declare function formatFreeProjectsQuotaHint(quota: FreeProjectsQuota): string;
|
|
17
23
|
export declare function buildPlatformPlanSelectionAgentInstruction(quota?: FreeProjectsQuota | null): string;
|
package/docs/cli/walkthrough.md
CHANGED
|
@@ -49,7 +49,7 @@ npx apitogo add plans --template free
|
|
|
49
49
|
`--create-spec` writes a small OpenAPI file with one `GET /health` operation, so the gateway has
|
|
50
50
|
something to expose. For a real API, point `gateway.specs` at your own OpenAPI file instead.
|
|
51
51
|
|
|
52
|
-
The Free template in `plans.json` allows
|
|
52
|
+
The Free template in `plans.json` allows 60 calls per minute and 1000 calls per 30 days. Change the
|
|
53
53
|
numbers in `plans.json` and deploy again to change the limits.
|
|
54
54
|
|
|
55
55
|
With plans in the project, customers call the gateway with their API key alone. Their login token is
|
package/package.json
CHANGED
|
@@ -249,21 +249,23 @@ const PLAN_TEMPLATES: Record<
|
|
|
249
249
|
displayName: "Free",
|
|
250
250
|
default: true,
|
|
251
251
|
limits: {
|
|
252
|
-
// The platform's Free tier allows at most
|
|
253
|
-
rateLimit: { calls:
|
|
252
|
+
// The platform's Free tier allows at most 60 calls per minute per plan (its rate_limit_per_minute ceiling).
|
|
253
|
+
rateLimit: { calls: 60, periodSeconds: 60 },
|
|
254
254
|
quota: { calls: 1000, periodDays: 30 },
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
257
|
],
|
|
258
|
-
// Sample plans for the
|
|
259
|
-
//
|
|
258
|
+
// Sample plans for the full template: a free plan and one paid example (API-124). The example's price is in the file
|
|
259
|
+
// but it is a contact-us plan, so the first deploy works on a Free project (a plan with a price needs Starter or
|
|
260
|
+
// Professional and billing). `apitogo plan` names the command that starts selling it. It has no limits of its own,
|
|
261
|
+
// so it stays within any project's ceiling until the tenant sets them.
|
|
260
262
|
starter: [
|
|
261
263
|
{
|
|
262
264
|
sku: "free",
|
|
263
265
|
displayName: "Free",
|
|
264
266
|
default: true,
|
|
265
267
|
limits: {
|
|
266
|
-
rateLimit: { calls:
|
|
268
|
+
rateLimit: { calls: 60, periodSeconds: 60 },
|
|
267
269
|
quota: { calls: 1000, periodDays: 30 },
|
|
268
270
|
},
|
|
269
271
|
},
|
|
@@ -272,12 +274,9 @@ const PLAN_TEMPLATES: Record<
|
|
|
272
274
|
displayName: "Pro",
|
|
273
275
|
pricingModel: "custom",
|
|
274
276
|
priceLabel: "Contact us",
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
displayName: "Enterprise",
|
|
279
|
-
pricingModel: "custom",
|
|
280
|
-
priceLabel: "Contact us",
|
|
277
|
+
priceAmount: 19,
|
|
278
|
+
priceCurrency: "usd",
|
|
279
|
+
billingInterval: "month",
|
|
281
280
|
},
|
|
282
281
|
],
|
|
283
282
|
tiered: [
|
|
@@ -286,8 +285,8 @@ const PLAN_TEMPLATES: Record<
|
|
|
286
285
|
displayName: "Free",
|
|
287
286
|
default: true,
|
|
288
287
|
limits: {
|
|
289
|
-
// The platform's Free tier allows at most
|
|
290
|
-
rateLimit: { calls:
|
|
288
|
+
// The platform's Free tier allows at most 60 calls per minute per plan (its rate_limit_per_minute ceiling).
|
|
289
|
+
rateLimit: { calls: 60, periodSeconds: 60 },
|
|
291
290
|
quota: { calls: 1000, periodDays: 30 },
|
|
292
291
|
},
|
|
293
292
|
},
|
package/src/config/v2/wrapper.ts
CHANGED
|
@@ -94,6 +94,8 @@ export type PortalPlan = {
|
|
|
94
94
|
keyHeader?: string;
|
|
95
95
|
/** The gateway's address, for code samples on the portal's pages. */
|
|
96
96
|
gatewayBaseUrl?: string;
|
|
97
|
+
/** The plan shown as "Popular": only the one the tenant marked `featured` in plans.json (API-124). */
|
|
98
|
+
featuredPlanSku?: string;
|
|
97
99
|
};
|
|
98
100
|
/** Account pages. */
|
|
99
101
|
userPanel: boolean;
|
|
@@ -685,6 +687,18 @@ export async function preparePortal(
|
|
|
685
687
|
for (const page of tsxPages)
|
|
686
688
|
if (page.order !== undefined && !pageOrders.has(page.route))
|
|
687
689
|
pageOrders.set(page.route, page.order);
|
|
690
|
+
// "Popular" is the tenant's choice, never guessed (API-124).
|
|
691
|
+
if (plan.plansPlugin) {
|
|
692
|
+
const featured = (await readDemoPlans(resolved.plans?.file))?.find(
|
|
693
|
+
(item): item is { sku: string } =>
|
|
694
|
+
typeof item === "object" &&
|
|
695
|
+
item !== null &&
|
|
696
|
+
(item as { featured?: unknown }).featured === true &&
|
|
697
|
+
typeof (item as { sku?: unknown }).sku === "string",
|
|
698
|
+
);
|
|
699
|
+
if (featured)
|
|
700
|
+
plan.plansPlugin.featuredPlanSku = featured.sku.trim().toLowerCase();
|
|
701
|
+
}
|
|
688
702
|
// The account pages' "Documentation" link goes to a page the portal really has, or is left out.
|
|
689
703
|
if (plan.plansPlugin && plan.docs) {
|
|
690
704
|
const landing = hostedDocRoutes.some(
|