@lukoweb/apitogo 0.1.133 → 0.1.135
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
CHANGED
|
@@ -5809,7 +5809,7 @@ import {
|
|
|
5809
5809
|
// package.json
|
|
5810
5810
|
var package_default = {
|
|
5811
5811
|
name: "@lukoweb/apitogo",
|
|
5812
|
-
version: "0.1.
|
|
5812
|
+
version: "0.1.135",
|
|
5813
5813
|
type: "module",
|
|
5814
5814
|
sideEffects: [
|
|
5815
5815
|
"**/*.css",
|
|
@@ -11252,6 +11252,17 @@ var PlatformApiClient = class {
|
|
|
11252
11252
|
}
|
|
11253
11253
|
);
|
|
11254
11254
|
}
|
|
11255
|
+
/**
|
|
11256
|
+
* Check every plan at once without persisting. Without `projectId` (site not deployed yet)
|
|
11257
|
+
* the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
|
|
11258
|
+
*/
|
|
11259
|
+
validateGatewayPlans(plans, options = {}) {
|
|
11260
|
+
const path73 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
|
|
11261
|
+
return this.request("POST", path73, {
|
|
11262
|
+
headers: { "Content-Type": "application/json" },
|
|
11263
|
+
body: JSON.stringify({ plans, planTier: options.planTier })
|
|
11264
|
+
});
|
|
11265
|
+
}
|
|
11255
11266
|
getGatewayPlan(projectId, planId) {
|
|
11256
11267
|
return this.request(
|
|
11257
11268
|
"GET",
|
|
@@ -16805,6 +16816,73 @@ var config_default = {
|
|
|
16805
16816
|
// src/cli/apply/handler.ts
|
|
16806
16817
|
import path63 from "node:path";
|
|
16807
16818
|
|
|
16819
|
+
// src/cli/platform/helpers/gateway-plan-validation.ts
|
|
16820
|
+
init_gateway_limits();
|
|
16821
|
+
function buildGatewayPlansValidationRequest(plans) {
|
|
16822
|
+
return plans.map((plan, index) => {
|
|
16823
|
+
const currency = tryNormalizePriceCurrency(plan.priceCurrency);
|
|
16824
|
+
return {
|
|
16825
|
+
sku: plan.sku?.trim() ?? "",
|
|
16826
|
+
displayName: plan.displayName?.trim() ?? "",
|
|
16827
|
+
limitsJson: planLimitsForPlatform(plan) ?? null,
|
|
16828
|
+
includedActionKeys: plan.includedActionKeys,
|
|
16829
|
+
priceAmount: plan.priceAmount ?? 0,
|
|
16830
|
+
pricingModel: plan.pricingModel ?? "fixed",
|
|
16831
|
+
priceLabel: plan.priceLabel,
|
|
16832
|
+
priceCurrency: currency.ok ? currency.value : plan.priceCurrency ?? "",
|
|
16833
|
+
billingPeriod: normalizeBillingPeriod2(plan.billingPeriod),
|
|
16834
|
+
sortOrder: index
|
|
16835
|
+
};
|
|
16836
|
+
});
|
|
16837
|
+
}
|
|
16838
|
+
function toConfigIssue(issue) {
|
|
16839
|
+
return {
|
|
16840
|
+
...issue,
|
|
16841
|
+
field: issue.field.replace(/\.limitsJson$/, ".limits")
|
|
16842
|
+
};
|
|
16843
|
+
}
|
|
16844
|
+
function formatGatewayPlanIssue(issue) {
|
|
16845
|
+
const sku = issue.sku ? ` (${issue.sku})` : "";
|
|
16846
|
+
return `${issue.field}${sku}: ${issue.message}`;
|
|
16847
|
+
}
|
|
16848
|
+
async function checkGatewayPlansOnPlatform(client, args) {
|
|
16849
|
+
let result;
|
|
16850
|
+
try {
|
|
16851
|
+
result = await client.validateGatewayPlans(
|
|
16852
|
+
buildGatewayPlansValidationRequest(args.plans),
|
|
16853
|
+
{ projectId: args.projectId, planTier: args.planTier }
|
|
16854
|
+
);
|
|
16855
|
+
} catch (error) {
|
|
16856
|
+
if (error instanceof PlatformApiError && (error.status === 404 || error.status === 405)) {
|
|
16857
|
+
return null;
|
|
16858
|
+
}
|
|
16859
|
+
throw error;
|
|
16860
|
+
}
|
|
16861
|
+
return {
|
|
16862
|
+
errors: result.errors.map(toConfigIssue),
|
|
16863
|
+
warnings: result.warnings.map(toConfigIssue)
|
|
16864
|
+
};
|
|
16865
|
+
}
|
|
16866
|
+
async function assertGatewayPlansValidForPublish(client, args) {
|
|
16867
|
+
const check2 = await checkGatewayPlansOnPlatform(client, args);
|
|
16868
|
+
if (!check2 || check2.errors.length === 0) {
|
|
16869
|
+
return { blocked: false };
|
|
16870
|
+
}
|
|
16871
|
+
const { errors, warnings } = check2;
|
|
16872
|
+
return {
|
|
16873
|
+
blocked: true,
|
|
16874
|
+
payload: {
|
|
16875
|
+
status: "blocked",
|
|
16876
|
+
reason: "gateway_plans_invalid",
|
|
16877
|
+
...args.projectId ? { projectId: args.projectId } : {},
|
|
16878
|
+
errors,
|
|
16879
|
+
warnings,
|
|
16880
|
+
userMessage: `Deploy is blocked: apitogo.config.json has ${errors.length} plan ${errors.length === 1 ? "error" : "errors"}.`,
|
|
16881
|
+
nextStep: "Fix every issue listed in errors in apitogo.config.json plans, then retry publish."
|
|
16882
|
+
}
|
|
16883
|
+
};
|
|
16884
|
+
}
|
|
16885
|
+
|
|
16808
16886
|
// src/cli/platform/helpers/progress.ts
|
|
16809
16887
|
var RECENT_JOB_MESSAGE_LIMIT = 5;
|
|
16810
16888
|
function recentJobMessages(messages) {
|
|
@@ -20983,6 +21061,25 @@ async function runApplyFromSiteDirectory(client, config2, args, progress) {
|
|
|
20983
21061
|
emailOptions
|
|
20984
21062
|
);
|
|
20985
21063
|
await writeManifest(args.sourceDirectory, manifest);
|
|
21064
|
+
if (includeApihub) {
|
|
21065
|
+
await publishProgress?.onStep("Validating gateway plans");
|
|
21066
|
+
const plansGate = await assertGatewayPlansValidForPublish(client, {
|
|
21067
|
+
projectId: args.createNewProject ? void 0 : projectIdHint,
|
|
21068
|
+
plans: manifest.plans ?? [],
|
|
21069
|
+
planTier: args.platformPlan
|
|
21070
|
+
});
|
|
21071
|
+
if (plansGate.blocked) {
|
|
21072
|
+
return JSON.stringify(
|
|
21073
|
+
{
|
|
21074
|
+
...plansGate.payload,
|
|
21075
|
+
completedSteps,
|
|
21076
|
+
sourceDirectory: args.sourceDirectory
|
|
21077
|
+
},
|
|
21078
|
+
null,
|
|
21079
|
+
2
|
|
21080
|
+
);
|
|
21081
|
+
}
|
|
21082
|
+
}
|
|
20986
21083
|
const stripeRequired = manifestRequiresStripe(manifest.plans);
|
|
20987
21084
|
const ledgerResume = resolveResumeStepFromLedger(ledger, PUBLISH_STEPS);
|
|
20988
21085
|
const effectiveResumeFromStep = args.resumeFromStep ?? ledgerResume;
|
|
@@ -21899,6 +21996,26 @@ function formatBlockedOrFailedResultForHuman(parsed) {
|
|
|
21899
21996
|
);
|
|
21900
21997
|
return lines;
|
|
21901
21998
|
}
|
|
21999
|
+
if (status2 === "blocked" && parsed.reason === "gateway_plans_invalid") {
|
|
22000
|
+
const lines = [
|
|
22001
|
+
typeof parsed.userMessage === "string" ? parsed.userMessage : "Deploy is blocked: apitogo.config.json has plan errors."
|
|
22002
|
+
];
|
|
22003
|
+
for (const issue of Array.isArray(parsed.errors) ? parsed.errors : []) {
|
|
22004
|
+
lines.push(` - ${formatGatewayPlanIssue(issue)}`);
|
|
22005
|
+
}
|
|
22006
|
+
const warnings = Array.isArray(parsed.warnings) ? parsed.warnings : [];
|
|
22007
|
+
if (warnings.length > 0) {
|
|
22008
|
+
lines.push("", "Warnings:");
|
|
22009
|
+
for (const issue of warnings) {
|
|
22010
|
+
lines.push(` - ${formatGatewayPlanIssue(issue)}`);
|
|
22011
|
+
}
|
|
22012
|
+
}
|
|
22013
|
+
lines.push(
|
|
22014
|
+
"",
|
|
22015
|
+
"Fix these in apitogo.config.json, then re-run `apitogo deploy`."
|
|
22016
|
+
);
|
|
22017
|
+
return lines;
|
|
22018
|
+
}
|
|
21902
22019
|
if (status2 === "blocked") {
|
|
21903
22020
|
return [
|
|
21904
22021
|
typeof parsed.userMessage === "string" ? parsed.userMessage : `Deploy is blocked${typeof parsed.reason === "string" ? `: ${parsed.reason}` : "."}`
|
|
@@ -21981,7 +22098,25 @@ async function askPlanChoice() {
|
|
|
21981
22098
|
rl.close();
|
|
21982
22099
|
}
|
|
21983
22100
|
}
|
|
21984
|
-
async function
|
|
22101
|
+
async function askValidPlanChoice(validatePlansForTier) {
|
|
22102
|
+
while (true) {
|
|
22103
|
+
const choice = await askPlanChoice();
|
|
22104
|
+
if (!choice || !validatePlansForTier) return choice;
|
|
22105
|
+
printDiagnosticsToConsole(`Checking your API plans against ${choice}...`);
|
|
22106
|
+
const errors = await validatePlansForTier(choice);
|
|
22107
|
+
if (errors.length === 0) return choice;
|
|
22108
|
+
printWarningToConsole(
|
|
22109
|
+
`apitogo.config.json has ${errors.length} plan ${errors.length === 1 ? "error" : "errors"} for the ${choice} plan:`
|
|
22110
|
+
);
|
|
22111
|
+
for (const error of errors) {
|
|
22112
|
+
printDiagnosticsToConsole(` - ${error}`);
|
|
22113
|
+
}
|
|
22114
|
+
printDiagnosticsToConsole(
|
|
22115
|
+
"Pick a different plan, or leave empty to cancel and fix apitogo.config.json."
|
|
22116
|
+
);
|
|
22117
|
+
}
|
|
22118
|
+
}
|
|
22119
|
+
async function resolvePlatformPlanInteractively(client, config2, payload, validatePlansForTier) {
|
|
21985
22120
|
const projectId = typeof payload.projectId === "string" ? payload.projectId : "";
|
|
21986
22121
|
if (!projectId) {
|
|
21987
22122
|
return false;
|
|
@@ -21990,7 +22125,7 @@ async function resolvePlatformPlanInteractively(client, config2, payload) {
|
|
|
21990
22125
|
if (typeof payload.platformPlanUserPrompt === "string") {
|
|
21991
22126
|
printDiagnosticsToConsole(payload.platformPlanUserPrompt);
|
|
21992
22127
|
}
|
|
21993
|
-
const choice = await
|
|
22128
|
+
const choice = await askValidPlanChoice(validatePlansForTier);
|
|
21994
22129
|
if (!choice) {
|
|
21995
22130
|
printWarningToConsole(
|
|
21996
22131
|
"No plan selected. Re-run with --platform-plan free|starter|professional when you're ready."
|
|
@@ -22177,10 +22312,20 @@ async function apply(argv) {
|
|
|
22177
22312
|
}
|
|
22178
22313
|
}
|
|
22179
22314
|
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "platform_plan_unselected") {
|
|
22315
|
+
const blockedProjectId = typeof parsed.projectId === "string" ? parsed.projectId : void 0;
|
|
22180
22316
|
const resolved = await resolvePlatformPlanInteractively(
|
|
22181
22317
|
client,
|
|
22182
22318
|
config2,
|
|
22183
|
-
parsed
|
|
22319
|
+
parsed,
|
|
22320
|
+
async (planTier) => {
|
|
22321
|
+
const manifest = await readManifest(sourceDirectory);
|
|
22322
|
+
const check2 = await checkGatewayPlansOnPlatform(client, {
|
|
22323
|
+
projectId: blockedProjectId,
|
|
22324
|
+
plans: manifest?.plans ?? [],
|
|
22325
|
+
planTier
|
|
22326
|
+
});
|
|
22327
|
+
return (check2?.errors ?? []).map(formatGatewayPlanIssue);
|
|
22328
|
+
}
|
|
22184
22329
|
);
|
|
22185
22330
|
if (resolved) {
|
|
22186
22331
|
try {
|
|
@@ -343,6 +343,20 @@ export interface BackendDeploymentDetailDto {
|
|
|
343
343
|
runtimeVersion: string;
|
|
344
344
|
backendUrl?: string | null;
|
|
345
345
|
}
|
|
346
|
+
export interface GatewayPlanValidationIssueDto {
|
|
347
|
+
field: string;
|
|
348
|
+
message: string;
|
|
349
|
+
planIndex?: number | null;
|
|
350
|
+
sku?: string | null;
|
|
351
|
+
}
|
|
352
|
+
export interface GatewayPlansValidationResultDto {
|
|
353
|
+
valid: boolean;
|
|
354
|
+
errors: GatewayPlanValidationIssueDto[];
|
|
355
|
+
warnings: GatewayPlanValidationIssueDto[];
|
|
356
|
+
}
|
|
357
|
+
export type ValidateGatewayPlanInput = Omit<CreateGatewayPlanRequest, "includedActionKeys"> & {
|
|
358
|
+
includedActionKeys?: string[];
|
|
359
|
+
};
|
|
346
360
|
export declare class PlatformApiClient {
|
|
347
361
|
private readonly config;
|
|
348
362
|
constructor(config: ApitogoConfig);
|
|
@@ -389,6 +403,10 @@ export declare class PlatformApiClient {
|
|
|
389
403
|
deployBackend(projectId: string, options: DeployBackendOptions): Promise<StartBackendDeploymentResponse>;
|
|
390
404
|
listGatewayPlans(projectId: string): Promise<GatewayPlanDto[]>;
|
|
391
405
|
createGatewayPlan(projectId: string, body: CreateGatewayPlanRequest): Promise<GatewayPlanDto>;
|
|
406
|
+
validateGatewayPlans(plans: ValidateGatewayPlanInput[], options?: {
|
|
407
|
+
projectId?: string;
|
|
408
|
+
planTier?: string;
|
|
409
|
+
}): Promise<GatewayPlansValidationResultDto>;
|
|
392
410
|
getGatewayPlan(projectId: string, planId: string): Promise<GatewayPlanDto>;
|
|
393
411
|
updateGatewayPlan(projectId: string, planId: string, body: UpdateGatewayPlanRequest): Promise<GatewayPlanDto>;
|
|
394
412
|
deleteGatewayPlan(projectId: string, planId: string): Promise<void>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { GatewayPlanValidationIssueDto, PlatformApiClient, ValidateGatewayPlanInput } from "../client/platform-api.js";
|
|
2
|
+
import { type ManifestPlanInput } from "./dev-portal-manifest.js";
|
|
3
|
+
export declare function buildGatewayPlansValidationRequest(plans: ManifestPlanInput[]): ValidateGatewayPlanInput[];
|
|
4
|
+
export declare function formatGatewayPlanIssue(issue: GatewayPlanValidationIssueDto): string;
|
|
5
|
+
export type GatewayPlansCheck = {
|
|
6
|
+
errors: GatewayPlanValidationIssueDto[];
|
|
7
|
+
warnings: GatewayPlanValidationIssueDto[];
|
|
8
|
+
};
|
|
9
|
+
export declare function checkGatewayPlansOnPlatform(client: PlatformApiClient, args: {
|
|
10
|
+
projectId?: string;
|
|
11
|
+
plans: ManifestPlanInput[];
|
|
12
|
+
planTier?: string;
|
|
13
|
+
}): Promise<GatewayPlansCheck | null>;
|
|
14
|
+
export declare function assertGatewayPlansValidForPublish(client: PlatformApiClient, args: {
|
|
15
|
+
projectId?: string;
|
|
16
|
+
plans: ManifestPlanInput[];
|
|
17
|
+
planTier?: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
blocked: true;
|
|
20
|
+
payload: Record<string, unknown>;
|
|
21
|
+
} | {
|
|
22
|
+
blocked: false;
|
|
23
|
+
}>;
|