@lukoweb/apitogo 0.1.114 → 0.1.116
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
|
@@ -5067,12 +5067,12 @@ async function loadZudokuConfigWithMeta(rootDir) {
|
|
|
5067
5067
|
};
|
|
5068
5068
|
return configWithMetadata;
|
|
5069
5069
|
}
|
|
5070
|
-
function findOutputPathOfServerConfig(
|
|
5071
|
-
if (Array.isArray(
|
|
5070
|
+
function findOutputPathOfServerConfig(output3) {
|
|
5071
|
+
if (Array.isArray(output3)) {
|
|
5072
5072
|
throw new Error("Expected a single output, but got an array");
|
|
5073
5073
|
}
|
|
5074
|
-
if ("output" in
|
|
5075
|
-
const result =
|
|
5074
|
+
if ("output" in output3) {
|
|
5075
|
+
const result = output3.output.find(
|
|
5076
5076
|
(o) => "isEntry" in o && o.isEntry && serverConfigOutputFiles.includes(o.fileName)
|
|
5077
5077
|
);
|
|
5078
5078
|
if (result) {
|
|
@@ -5801,7 +5801,7 @@ import {
|
|
|
5801
5801
|
// package.json
|
|
5802
5802
|
var package_default = {
|
|
5803
5803
|
name: "@lukoweb/apitogo",
|
|
5804
|
-
version: "0.1.
|
|
5804
|
+
version: "0.1.116",
|
|
5805
5805
|
type: "module",
|
|
5806
5806
|
sideEffects: [
|
|
5807
5807
|
"**/*.css",
|
|
@@ -7632,13 +7632,13 @@ var generateCode = (schema2, filePath) => {
|
|
|
7632
7632
|
|
|
7633
7633
|
// src/vite/api/SchemaManager.ts
|
|
7634
7634
|
var FALLBACK_VERSION = "default";
|
|
7635
|
-
var parseInputString = (
|
|
7636
|
-
const idx =
|
|
7635
|
+
var parseInputString = (input4) => {
|
|
7636
|
+
const idx = input4.indexOf("?");
|
|
7637
7637
|
if (idx === -1)
|
|
7638
|
-
return { filePath:
|
|
7638
|
+
return { filePath: input4, params: {} };
|
|
7639
7639
|
return {
|
|
7640
|
-
filePath:
|
|
7641
|
-
params: Object.fromEntries(new URLSearchParams(
|
|
7640
|
+
filePath: input4.slice(0, idx),
|
|
7641
|
+
params: Object.fromEntries(new URLSearchParams(input4.slice(idx)))
|
|
7642
7642
|
};
|
|
7643
7643
|
};
|
|
7644
7644
|
var canonicalParams = (params) => Object.entries(params).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}=${v}`).join("&");
|
|
@@ -7674,8 +7674,8 @@ var SchemaManager = class {
|
|
|
7674
7674
|
...processors
|
|
7675
7675
|
];
|
|
7676
7676
|
}
|
|
7677
|
-
getPathForFile = (
|
|
7678
|
-
const filePath = path11.resolve(this.config.__meta.rootDir,
|
|
7677
|
+
getPathForFile = (input4, params) => {
|
|
7678
|
+
const filePath = path11.resolve(this.config.__meta.rootDir, input4);
|
|
7679
7679
|
const apis = ensureArray(this.config.apis ?? []);
|
|
7680
7680
|
for (const apiConfig of apis) {
|
|
7681
7681
|
if (!apiConfig || apiConfig.type !== "file" || !apiConfig.path) continue;
|
|
@@ -7685,12 +7685,12 @@ var SchemaManager = class {
|
|
|
7685
7685
|
if (match) return apiConfig.path;
|
|
7686
7686
|
}
|
|
7687
7687
|
};
|
|
7688
|
-
processSchema = async (
|
|
7689
|
-
const filePath = path11.resolve(this.config.__meta.rootDir,
|
|
7690
|
-
const params =
|
|
7691
|
-
const configuredPath = this.getPathForFile(
|
|
7688
|
+
processSchema = async (input4) => {
|
|
7689
|
+
const filePath = path11.resolve(this.config.__meta.rootDir, input4.input);
|
|
7690
|
+
const params = input4.params;
|
|
7691
|
+
const configuredPath = this.getPathForFile(input4.input, params);
|
|
7692
7692
|
if (!configuredPath) {
|
|
7693
|
-
console.warn(`No path found for file ${
|
|
7693
|
+
console.warn(`No path found for file ${input4.input}`);
|
|
7694
7694
|
return;
|
|
7695
7695
|
}
|
|
7696
7696
|
const parser = new $RefParser2();
|
|
@@ -7797,20 +7797,20 @@ var SchemaManager = class {
|
|
|
7797
7797
|
if (apiConfig.type !== "file" || !apiConfig.path) continue;
|
|
7798
7798
|
const inputs = normalizeInputs(apiConfig.input);
|
|
7799
7799
|
if (inputs.length === 0) throw new Error("No schema found");
|
|
7800
|
-
this.processedSchemas[apiConfig.path] = inputs.map((
|
|
7800
|
+
this.processedSchemas[apiConfig.path] = inputs.map((input4) => ({
|
|
7801
7801
|
schema: {},
|
|
7802
7802
|
version: "",
|
|
7803
|
-
path:
|
|
7804
|
-
label:
|
|
7805
|
-
inputPath: path11.resolve(this.config.__meta.rootDir,
|
|
7806
|
-
params:
|
|
7803
|
+
path: input4.path ?? "",
|
|
7804
|
+
label: input4.label,
|
|
7805
|
+
inputPath: path11.resolve(this.config.__meta.rootDir, input4.input),
|
|
7806
|
+
params: input4.params,
|
|
7807
7807
|
importKey: "",
|
|
7808
7808
|
downloadUrl: "",
|
|
7809
7809
|
processedJsonPath: "",
|
|
7810
7810
|
processedTime: 0
|
|
7811
7811
|
}));
|
|
7812
7812
|
const results = await Promise.allSettled(
|
|
7813
|
-
inputs.map((
|
|
7813
|
+
inputs.map((input4) => this.processSchema(input4))
|
|
7814
7814
|
);
|
|
7815
7815
|
const errors = results.flatMap(
|
|
7816
7816
|
(r) => r.status === "rejected" ? r.reason : []
|
|
@@ -7889,7 +7889,7 @@ import { readFile as readFile2 } from "node:fs/promises";
|
|
|
7889
7889
|
import matter from "gray-matter";
|
|
7890
7890
|
import { parse, stringify as stringify2 } from "yaml";
|
|
7891
7891
|
var yaml = {
|
|
7892
|
-
parse: (
|
|
7892
|
+
parse: (input4) => parse(input4) ?? {},
|
|
7893
7893
|
stringify: (obj) => stringify2(obj)
|
|
7894
7894
|
};
|
|
7895
7895
|
var readFrontmatter = async (filePath) => {
|
|
@@ -10162,25 +10162,25 @@ function generateOutput({
|
|
|
10162
10162
|
});
|
|
10163
10163
|
}
|
|
10164
10164
|
}
|
|
10165
|
-
const
|
|
10165
|
+
const output3 = {
|
|
10166
10166
|
version: 3,
|
|
10167
10167
|
framework: {
|
|
10168
10168
|
version: pkgJson.version
|
|
10169
10169
|
},
|
|
10170
10170
|
routes
|
|
10171
10171
|
};
|
|
10172
|
-
return
|
|
10172
|
+
return output3;
|
|
10173
10173
|
}
|
|
10174
10174
|
async function writeOutput(dir, {
|
|
10175
10175
|
config: config2,
|
|
10176
10176
|
redirects,
|
|
10177
10177
|
rewrites
|
|
10178
10178
|
}) {
|
|
10179
|
-
const
|
|
10179
|
+
const output3 = generateOutput({ config: config2, redirects, rewrites });
|
|
10180
10180
|
const outputDir = process.env.VERCEL ? path27.join(dir, ".vercel/output") : path27.join(dir, "dist/.output");
|
|
10181
10181
|
await mkdir3(outputDir, { recursive: true });
|
|
10182
10182
|
const outputFile = path27.join(outputDir, "config.json");
|
|
10183
|
-
await writeFile4(outputFile, JSON.stringify(
|
|
10183
|
+
await writeFile4(outputFile, JSON.stringify(output3, null, 2), "utf-8");
|
|
10184
10184
|
if (process.env.VERCEL) {
|
|
10185
10185
|
console.log("Wrote Vercel output to", outputDir);
|
|
10186
10186
|
}
|
|
@@ -10201,12 +10201,12 @@ init_invariant();
|
|
|
10201
10201
|
init_joinUrl();
|
|
10202
10202
|
|
|
10203
10203
|
// src/vite/reporter.ts
|
|
10204
|
-
function writeLine(
|
|
10204
|
+
function writeLine(output3) {
|
|
10205
10205
|
clearLine();
|
|
10206
|
-
if (
|
|
10207
|
-
process.stdout.write(
|
|
10206
|
+
if (output3.length < process.stdout.columns) {
|
|
10207
|
+
process.stdout.write(output3);
|
|
10208
10208
|
} else {
|
|
10209
|
-
process.stdout.write(
|
|
10209
|
+
process.stdout.write(output3.substring(0, process.stdout.columns - 1));
|
|
10210
10210
|
}
|
|
10211
10211
|
}
|
|
10212
10212
|
function isTTY() {
|
|
@@ -10876,7 +10876,7 @@ function isNetworkError(error) {
|
|
|
10876
10876
|
const message = error.message.toLowerCase();
|
|
10877
10877
|
return message.includes("fetch failed") || message.includes("network") || message.includes("econnreset") || message.includes("etimedout") || message.includes("socket hang up") || error.name === "AbortError" || error.name === "TypeError";
|
|
10878
10878
|
}
|
|
10879
|
-
async function fetchWithRetry(
|
|
10879
|
+
async function fetchWithRetry(input4, init4, options) {
|
|
10880
10880
|
const maxRetries = options?.maxRetries ?? 3;
|
|
10881
10881
|
const baseDelayMs = options?.baseDelayMs ?? 1e3;
|
|
10882
10882
|
const maxDelayMs = options?.maxDelayMs ?? 15e3;
|
|
@@ -10886,7 +10886,7 @@ async function fetchWithRetry(input3, init4, options) {
|
|
|
10886
10886
|
let attempt = 0;
|
|
10887
10887
|
while (true) {
|
|
10888
10888
|
try {
|
|
10889
|
-
const response = await fetch(
|
|
10889
|
+
const response = await fetch(input4, init4);
|
|
10890
10890
|
const retriableStatus = isRetriableHttpStatus(response.status);
|
|
10891
10891
|
const mayRetryStatus = retriableStatus && (isSafeMethod || response.status === 429 || retryMutatingOnServerError);
|
|
10892
10892
|
if (mayRetryStatus && attempt < maxRetries) {
|
|
@@ -12762,15 +12762,15 @@ function runCommand(command2, args, cwd, env) {
|
|
|
12762
12762
|
env: env ? { ...process.env, ...env } : process.env,
|
|
12763
12763
|
shell: process.platform === "win32"
|
|
12764
12764
|
});
|
|
12765
|
-
let
|
|
12765
|
+
let output3 = "";
|
|
12766
12766
|
child.stdout.on("data", (chunk) => {
|
|
12767
|
-
|
|
12767
|
+
output3 += chunk.toString();
|
|
12768
12768
|
});
|
|
12769
12769
|
child.stderr.on("data", (chunk) => {
|
|
12770
|
-
|
|
12770
|
+
output3 += chunk.toString();
|
|
12771
12771
|
});
|
|
12772
12772
|
child.on("error", reject);
|
|
12773
|
-
child.on("close", (exitCode) => resolve({ exitCode, output:
|
|
12773
|
+
child.on("close", (exitCode) => resolve({ exitCode, output: output3 }));
|
|
12774
12774
|
});
|
|
12775
12775
|
}
|
|
12776
12776
|
async function runNpmInstall(sourceDirectory, options) {
|
|
@@ -13817,10 +13817,10 @@ ${formatCustomPageNavigationEntry(slug, label, itemIndent)}
|
|
|
13817
13817
|
${inner}],
|
|
13818
13818
|
${indent}},`;
|
|
13819
13819
|
}
|
|
13820
|
-
function findMatchingArrayClose(content,
|
|
13820
|
+
function findMatchingArrayClose(content, open3) {
|
|
13821
13821
|
let depth = 0;
|
|
13822
13822
|
let inString = null;
|
|
13823
|
-
for (let i =
|
|
13823
|
+
for (let i = open3; i < content.length; i++) {
|
|
13824
13824
|
const char = content[i];
|
|
13825
13825
|
if (inString) {
|
|
13826
13826
|
if (char === "\\") {
|
|
@@ -13859,8 +13859,8 @@ function findDocumentationCategoryItemsRange(content, from, to) {
|
|
|
13859
13859
|
if (!itemsMatch) {
|
|
13860
13860
|
return null;
|
|
13861
13861
|
}
|
|
13862
|
-
const
|
|
13863
|
-
const close3 = findMatchingArrayClose(content,
|
|
13862
|
+
const open3 = afterLabel + itemsMatch.index + itemsMatch[0].length - 1;
|
|
13863
|
+
const close3 = findMatchingArrayClose(content, open3);
|
|
13864
13864
|
if (close3 === null || close3 > to) {
|
|
13865
13865
|
return null;
|
|
13866
13866
|
}
|
|
@@ -13871,7 +13871,7 @@ function findDocumentationCategoryItemsRange(content, from, to) {
|
|
|
13871
13871
|
const indentMatch = /^[ \t]*/.exec(content.slice(lineStart));
|
|
13872
13872
|
const itemsIndent = indentMatch?.[0] ?? "";
|
|
13873
13873
|
const entryIndent = `${itemsIndent} `;
|
|
13874
|
-
return { open:
|
|
13874
|
+
return { open: open3, close: close3, indent: entryIndent };
|
|
13875
13875
|
}
|
|
13876
13876
|
function appendEntryToArrayRange(content, range, entry) {
|
|
13877
13877
|
const before = content.slice(0, range.close);
|
|
@@ -13906,11 +13906,11 @@ function appendCustomPageToDirectBuildExport(content, slug, label) {
|
|
|
13906
13906
|
return null;
|
|
13907
13907
|
}
|
|
13908
13908
|
const callStart = exportIndex + exportPrefix.length;
|
|
13909
|
-
const
|
|
13909
|
+
const open3 = callStart + callPrefix.length - 1;
|
|
13910
13910
|
let depth = 0;
|
|
13911
13911
|
let inString = null;
|
|
13912
13912
|
let close3 = -1;
|
|
13913
|
-
for (let i =
|
|
13913
|
+
for (let i = open3; i < content.length; i++) {
|
|
13914
13914
|
const char = content[i];
|
|
13915
13915
|
if (inString) {
|
|
13916
13916
|
if (char === "\\") {
|
|
@@ -13971,10 +13971,10 @@ function findNavigationArrayRange(content) {
|
|
|
13971
13971
|
return null;
|
|
13972
13972
|
}
|
|
13973
13973
|
const indent = match[1] ?? "";
|
|
13974
|
-
const
|
|
13974
|
+
const open3 = match.index + match[0].length - 1;
|
|
13975
13975
|
let depth = 0;
|
|
13976
13976
|
let inString = null;
|
|
13977
|
-
for (let i =
|
|
13977
|
+
for (let i = open3; i < content.length; i++) {
|
|
13978
13978
|
const char = content[i];
|
|
13979
13979
|
if (inString) {
|
|
13980
13980
|
if (char === "\\") {
|
|
@@ -13993,7 +13993,7 @@ function findNavigationArrayRange(content) {
|
|
|
13993
13993
|
} else if (char === "]") {
|
|
13994
13994
|
depth -= 1;
|
|
13995
13995
|
if (depth === 0) {
|
|
13996
|
-
return { open:
|
|
13996
|
+
return { open: open3, close: i, indent };
|
|
13997
13997
|
}
|
|
13998
13998
|
}
|
|
13999
13999
|
}
|
|
@@ -14419,15 +14419,15 @@ function runCommand2(command2, args, cwd) {
|
|
|
14419
14419
|
env: process.env,
|
|
14420
14420
|
shell: process.platform === "win32"
|
|
14421
14421
|
});
|
|
14422
|
-
let
|
|
14422
|
+
let output3 = "";
|
|
14423
14423
|
child.stdout.on("data", (chunk) => {
|
|
14424
|
-
|
|
14424
|
+
output3 += chunk.toString();
|
|
14425
14425
|
});
|
|
14426
14426
|
child.stderr.on("data", (chunk) => {
|
|
14427
|
-
|
|
14427
|
+
output3 += chunk.toString();
|
|
14428
14428
|
});
|
|
14429
14429
|
child.on("error", reject);
|
|
14430
|
-
child.on("close", (exitCode) => resolve({ exitCode, output:
|
|
14430
|
+
child.on("close", (exitCode) => resolve({ exitCode, output: output3 }));
|
|
14431
14431
|
});
|
|
14432
14432
|
}
|
|
14433
14433
|
function buildCreateApitogoCliArgs(invocationArgs, projectName, options) {
|
|
@@ -14613,10 +14613,10 @@ function patchApisConfig(content, config2) {
|
|
|
14613
14613
|
const asArray = match[0].includes("apis: [");
|
|
14614
14614
|
return content.replace(APIS_CONFIG_PATTERN, renderApisConfig(config2, asArray));
|
|
14615
14615
|
}
|
|
14616
|
-
function patchApitogoConfigOpenApiToFile(content,
|
|
14616
|
+
function patchApitogoConfigOpenApiToFile(content, input4 = "./openapi.json") {
|
|
14617
14617
|
return patchApisConfig(content, {
|
|
14618
14618
|
type: "file",
|
|
14619
|
-
input:
|
|
14619
|
+
input: input4,
|
|
14620
14620
|
path: "api"
|
|
14621
14621
|
});
|
|
14622
14622
|
}
|
|
@@ -14828,7 +14828,7 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
|
|
|
14828
14828
|
async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
14829
14829
|
const resolvedSource = path47.resolve(sourceDirectory);
|
|
14830
14830
|
const resolvedOpenApi = path47.resolve(openApiPath);
|
|
14831
|
-
const
|
|
14831
|
+
const input4 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
|
|
14832
14832
|
const validation = await validateOpenApiFile(resolvedOpenApi);
|
|
14833
14833
|
if (!validation.valid) {
|
|
14834
14834
|
return {
|
|
@@ -14842,7 +14842,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
14842
14842
|
const raw = await readFile12(jsonConfigPath, "utf8");
|
|
14843
14843
|
const siteConfig = JSON.parse(raw);
|
|
14844
14844
|
const updated = applyOpenApiToSiteConfig(siteConfig, {
|
|
14845
|
-
input:
|
|
14845
|
+
input: input4,
|
|
14846
14846
|
apiPath: "api"
|
|
14847
14847
|
});
|
|
14848
14848
|
await writeFile11(
|
|
@@ -14855,7 +14855,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
14855
14855
|
const tsxConfigPath = path47.join(resolvedSource, "apitogo.config.tsx");
|
|
14856
14856
|
const configContent = await readFile12(tsxConfigPath, "utf8");
|
|
14857
14857
|
try {
|
|
14858
|
-
const patched = patchApitogoConfigOpenApiToFile(configContent,
|
|
14858
|
+
const patched = patchApitogoConfigOpenApiToFile(configContent, input4);
|
|
14859
14859
|
await writeFile11(tsxConfigPath, patched);
|
|
14860
14860
|
} catch (error) {
|
|
14861
14861
|
return {
|
|
@@ -14868,13 +14868,13 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
|
|
|
14868
14868
|
const manifest = await readManifest(resolvedSource) ?? createScaffoldManifest();
|
|
14869
14869
|
manifest.backend = {
|
|
14870
14870
|
...manifest.backend,
|
|
14871
|
-
openApiPath:
|
|
14871
|
+
openApiPath: input4
|
|
14872
14872
|
};
|
|
14873
14873
|
await writeManifest(resolvedSource, manifest);
|
|
14874
14874
|
return {
|
|
14875
14875
|
status: "succeeded",
|
|
14876
14876
|
openApiPath: resolvedOpenApi,
|
|
14877
|
-
openApiInput:
|
|
14877
|
+
openApiInput: input4,
|
|
14878
14878
|
openApiTitle: validation.title ?? null,
|
|
14879
14879
|
openApiVersion: validation.version
|
|
14880
14880
|
};
|
|
@@ -15295,12 +15295,12 @@ function mergeDocumentationNavigation(navigation, docRoutePaths, options) {
|
|
|
15295
15295
|
}
|
|
15296
15296
|
return [documentation, ...rest];
|
|
15297
15297
|
}
|
|
15298
|
-
function applyOpenApiToJsonConfig(config2,
|
|
15298
|
+
function applyOpenApiToJsonConfig(config2, input4) {
|
|
15299
15299
|
const next = { ...config2 };
|
|
15300
15300
|
next.apis = [
|
|
15301
15301
|
{
|
|
15302
15302
|
type: "file",
|
|
15303
|
-
input:
|
|
15303
|
+
input: input4,
|
|
15304
15304
|
path: "api"
|
|
15305
15305
|
}
|
|
15306
15306
|
];
|
|
@@ -15343,15 +15343,15 @@ function buildLimits(rateLimitCalls, monthlyQuota) {
|
|
|
15343
15343
|
quota: { calls: monthlyQuota, renewalPeriodDays: 30 }
|
|
15344
15344
|
};
|
|
15345
15345
|
}
|
|
15346
|
-
function buildPlanItemFromWizard(
|
|
15347
|
-
const sku =
|
|
15346
|
+
function buildPlanItemFromWizard(input4) {
|
|
15347
|
+
const sku = input4.sku ?? slugifyPlanSku(input4.displayName);
|
|
15348
15348
|
const item = {
|
|
15349
15349
|
sku,
|
|
15350
|
-
displayName:
|
|
15351
|
-
priceAmount:
|
|
15352
|
-
limits: buildLimits(
|
|
15350
|
+
displayName: input4.displayName,
|
|
15351
|
+
priceAmount: input4.priceAmount,
|
|
15352
|
+
limits: buildLimits(input4.rateLimitCalls, input4.monthlyQuota)
|
|
15353
15353
|
};
|
|
15354
|
-
if (
|
|
15354
|
+
if (input4.priceAmount > 0) {
|
|
15355
15355
|
item.priceCurrency = "usd";
|
|
15356
15356
|
item.billingPeriod = "month";
|
|
15357
15357
|
}
|
|
@@ -16552,6 +16552,100 @@ var config_default = {
|
|
|
16552
16552
|
// src/cli/apply/handler.ts
|
|
16553
16553
|
import path63 from "node:path";
|
|
16554
16554
|
|
|
16555
|
+
// src/cli/platform/helpers/progress.ts
|
|
16556
|
+
var RECENT_JOB_MESSAGE_LIMIT = 5;
|
|
16557
|
+
function recentJobMessages(messages) {
|
|
16558
|
+
if (!messages?.length) {
|
|
16559
|
+
return [];
|
|
16560
|
+
}
|
|
16561
|
+
return messages.slice(-RECENT_JOB_MESSAGE_LIMIT);
|
|
16562
|
+
}
|
|
16563
|
+
function newMessagesSince(previousCount, messages) {
|
|
16564
|
+
if (!messages?.length || messages.length <= previousCount) {
|
|
16565
|
+
return [];
|
|
16566
|
+
}
|
|
16567
|
+
return messages.slice(previousCount);
|
|
16568
|
+
}
|
|
16569
|
+
function deriveCurrentStep(platformStatus, messages, stepLabel) {
|
|
16570
|
+
const latest = messages?.at(-1)?.message?.trim();
|
|
16571
|
+
if (latest) {
|
|
16572
|
+
return latest;
|
|
16573
|
+
}
|
|
16574
|
+
const normalized = platformStatus.toLowerCase();
|
|
16575
|
+
if (normalized === "pending" || normalized === "none") {
|
|
16576
|
+
return stepLabel ? `${stepLabel} queued` : "Queued";
|
|
16577
|
+
}
|
|
16578
|
+
if (normalized === "in_progress" || normalized === "running") {
|
|
16579
|
+
return stepLabel ? `${stepLabel} in progress` : "In progress";
|
|
16580
|
+
}
|
|
16581
|
+
if (normalized === "completed" || normalized === "healthy") {
|
|
16582
|
+
return stepLabel ? `${stepLabel} completed` : "Completed";
|
|
16583
|
+
}
|
|
16584
|
+
if (normalized === "failed" || normalized === "cancelled") {
|
|
16585
|
+
return stepLabel ? `${stepLabel} failed` : "Failed";
|
|
16586
|
+
}
|
|
16587
|
+
return stepLabel ?? platformStatus;
|
|
16588
|
+
}
|
|
16589
|
+
function buildProgressSummary(options) {
|
|
16590
|
+
return {
|
|
16591
|
+
stepsCompleted: options.stepLabel,
|
|
16592
|
+
lastMessage: options.messages?.at(-1)?.message ?? null,
|
|
16593
|
+
elapsedMs: Date.now() - options.startedAtMs,
|
|
16594
|
+
terminalStatus: options.terminalStatus
|
|
16595
|
+
};
|
|
16596
|
+
}
|
|
16597
|
+
function createConsoleProgressReporter(stream = process.stderr) {
|
|
16598
|
+
return createScopedConsoleProgressReporter(stream, void 0);
|
|
16599
|
+
}
|
|
16600
|
+
function createScopedConsoleProgressReporter(stream, stepLabel) {
|
|
16601
|
+
let lastMessageCount = 0;
|
|
16602
|
+
let lastLine;
|
|
16603
|
+
const reporter = {
|
|
16604
|
+
async onStep(step, detail) {
|
|
16605
|
+
const message = detail?.message ?? (detail?.platformStatus ? `${step}: ${detail.platformStatus}` : step);
|
|
16606
|
+
const line = stepLabel ? `[${stepLabel}] ${message}` : message;
|
|
16607
|
+
if (line === lastLine) return;
|
|
16608
|
+
lastLine = line;
|
|
16609
|
+
stream.write(`${line}
|
|
16610
|
+
`);
|
|
16611
|
+
},
|
|
16612
|
+
async onNewMessages(messages) {
|
|
16613
|
+
for (const entry of messages) {
|
|
16614
|
+
const line = stepLabel ? `[${stepLabel}] ${entry.message}` : entry.message;
|
|
16615
|
+
stream.write(`${line}
|
|
16616
|
+
`);
|
|
16617
|
+
}
|
|
16618
|
+
},
|
|
16619
|
+
isCancelled: () => false,
|
|
16620
|
+
child(label) {
|
|
16621
|
+
return createScopedConsoleProgressReporter(stream, label);
|
|
16622
|
+
}
|
|
16623
|
+
};
|
|
16624
|
+
const baseOnNewMessages = reporter.onNewMessages.bind(reporter);
|
|
16625
|
+
reporter.onNewMessages = async (messages) => {
|
|
16626
|
+
const delta = newMessagesSince(lastMessageCount, messages);
|
|
16627
|
+
lastMessageCount = messages.length;
|
|
16628
|
+
await baseOnNewMessages(delta);
|
|
16629
|
+
};
|
|
16630
|
+
return reporter;
|
|
16631
|
+
}
|
|
16632
|
+
async function reportPollProgress(progress, stepLabel, value) {
|
|
16633
|
+
if (!progress) {
|
|
16634
|
+
return;
|
|
16635
|
+
}
|
|
16636
|
+
if (progress.isCancelled()) {
|
|
16637
|
+
throw new Error("Operation cancelled.");
|
|
16638
|
+
}
|
|
16639
|
+
const latestMessage = value.messages?.at(-1)?.message;
|
|
16640
|
+
await progress.onStep(stepLabel, {
|
|
16641
|
+
platformStatus: value.status,
|
|
16642
|
+
message: latestMessage
|
|
16643
|
+
});
|
|
16644
|
+
if (value.messages?.length) {
|
|
16645
|
+
await progress.onNewMessages(value.messages);
|
|
16646
|
+
}
|
|
16647
|
+
}
|
|
16648
|
+
|
|
16555
16649
|
// src/cli/platform/tools/dev-portal-publish.ts
|
|
16556
16650
|
init_gateway_limits();
|
|
16557
16651
|
|
|
@@ -16936,13 +17030,13 @@ async function resolveActionKeysOrAllProjectActions(manifestPlan, existingPlan,
|
|
|
16936
17030
|
var GATEWAY_PLAN_SORT_TEMP_OFFSET = 1e3;
|
|
16937
17031
|
function buildGatewayPlanSortTargetsFromIds(manifestPlans, planIdsBySku, skuById) {
|
|
16938
17032
|
const targets = [];
|
|
16939
|
-
for (const [index,
|
|
16940
|
-
const key =
|
|
17033
|
+
for (const [index, input4] of manifestPlans.entries()) {
|
|
17034
|
+
const key = input4.sku.toLowerCase();
|
|
16941
17035
|
const planId = planIdsBySku.get(key);
|
|
16942
17036
|
if (!planId) {
|
|
16943
|
-
throw new Error(`Gateway plan '${
|
|
17037
|
+
throw new Error(`Gateway plan '${input4.sku}' was not found; upsert plans before reordering.`);
|
|
16944
17038
|
}
|
|
16945
|
-
const sku = skuById?.get(key)?.sku ??
|
|
17039
|
+
const sku = skuById?.get(key)?.sku ?? input4.sku;
|
|
16946
17040
|
targets.push({ planId, sku, sortOrder: index });
|
|
16947
17041
|
}
|
|
16948
17042
|
return targets;
|
|
@@ -16988,12 +17082,12 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
16988
17082
|
return cachedProjectActionKeys;
|
|
16989
17083
|
};
|
|
16990
17084
|
for (const [index, inputRaw] of plans.entries()) {
|
|
16991
|
-
const
|
|
16992
|
-
const found = bySku.get(
|
|
17085
|
+
const input4 = normalizePlanForGatewayApi(inputRaw);
|
|
17086
|
+
const found = bySku.get(input4.sku.toLowerCase());
|
|
16993
17087
|
if (found) {
|
|
16994
17088
|
if (options?.syncActionsOnly) {
|
|
16995
17089
|
const actionKeys = await resolveActionKeysOrAllProjectActions(
|
|
16996
|
-
|
|
17090
|
+
input4,
|
|
16997
17091
|
found,
|
|
16998
17092
|
projectActionKeys
|
|
16999
17093
|
);
|
|
@@ -17006,29 +17100,29 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
17006
17100
|
includedActionKeys: actionKeys
|
|
17007
17101
|
});
|
|
17008
17102
|
results.push(JSON.parse(patchedJson2));
|
|
17009
|
-
planIdsBySku.set(
|
|
17103
|
+
planIdsBySku.set(input4.sku.toLowerCase(), found.id);
|
|
17010
17104
|
continue;
|
|
17011
17105
|
}
|
|
17012
17106
|
const patchArgs = {
|
|
17013
17107
|
projectId,
|
|
17014
17108
|
planId: found.id,
|
|
17015
|
-
displayName:
|
|
17109
|
+
displayName: input4.displayName,
|
|
17016
17110
|
isActive: true,
|
|
17017
|
-
limitsJson: planLimitsForPlatform(
|
|
17018
|
-
priceAmount:
|
|
17019
|
-
priceCurrency:
|
|
17020
|
-
billingPeriod:
|
|
17111
|
+
limitsJson: planLimitsForPlatform(input4),
|
|
17112
|
+
priceAmount: input4.priceAmount,
|
|
17113
|
+
priceCurrency: input4.priceCurrency,
|
|
17114
|
+
billingPeriod: input4.billingPeriod ? normalizeBillingPeriod2(input4.billingPeriod) : void 0
|
|
17021
17115
|
};
|
|
17022
17116
|
if (!options?.deferActionKeys) {
|
|
17023
17117
|
patchArgs.includedActionKeys = await resolveActionKeysOrAllProjectActions(
|
|
17024
|
-
|
|
17118
|
+
input4,
|
|
17025
17119
|
found,
|
|
17026
17120
|
projectActionKeys
|
|
17027
17121
|
);
|
|
17028
17122
|
}
|
|
17029
17123
|
const patchedJson = await handlePatchGatewayPlan(client, config2, patchArgs);
|
|
17030
17124
|
results.push(JSON.parse(patchedJson));
|
|
17031
|
-
planIdsBySku.set(
|
|
17125
|
+
planIdsBySku.set(input4.sku.toLowerCase(), found.id);
|
|
17032
17126
|
continue;
|
|
17033
17127
|
}
|
|
17034
17128
|
if (options?.syncActionsOnly) {
|
|
@@ -17036,19 +17130,19 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
|
|
|
17036
17130
|
}
|
|
17037
17131
|
const createdJson = await handleCreateGatewayPlan(client, config2, {
|
|
17038
17132
|
projectId,
|
|
17039
|
-
sku:
|
|
17040
|
-
displayName:
|
|
17041
|
-
priceAmount:
|
|
17042
|
-
priceCurrency:
|
|
17043
|
-
billingPeriod: normalizeBillingPeriod2(
|
|
17044
|
-
limitsJson: planLimitsForPlatform(
|
|
17045
|
-
includedActionKeys: options?.deferActionKeys ? [] : await resolveActionKeysOrAllProjectActions(
|
|
17133
|
+
sku: input4.sku,
|
|
17134
|
+
displayName: input4.displayName,
|
|
17135
|
+
priceAmount: input4.priceAmount,
|
|
17136
|
+
priceCurrency: input4.priceCurrency ?? "usd",
|
|
17137
|
+
billingPeriod: normalizeBillingPeriod2(input4.billingPeriod),
|
|
17138
|
+
limitsJson: planLimitsForPlatform(input4),
|
|
17139
|
+
includedActionKeys: options?.deferActionKeys ? [] : await resolveActionKeysOrAllProjectActions(input4, void 0, projectActionKeys),
|
|
17046
17140
|
skipDefaultActions: true,
|
|
17047
17141
|
sortOrder: index
|
|
17048
17142
|
});
|
|
17049
17143
|
const created = JSON.parse(createdJson);
|
|
17050
17144
|
if (created.plan?.id) {
|
|
17051
|
-
planIdsBySku.set(
|
|
17145
|
+
planIdsBySku.set(input4.sku.toLowerCase(), created.plan.id);
|
|
17052
17146
|
}
|
|
17053
17147
|
results.push(created);
|
|
17054
17148
|
}
|
|
@@ -17164,59 +17258,6 @@ function resolveDevPortalUrls(project, backendFqdn, providerIds = [], platformSi
|
|
|
17164
17258
|
};
|
|
17165
17259
|
}
|
|
17166
17260
|
|
|
17167
|
-
// src/cli/platform/helpers/progress.ts
|
|
17168
|
-
var RECENT_JOB_MESSAGE_LIMIT = 5;
|
|
17169
|
-
function recentJobMessages(messages) {
|
|
17170
|
-
if (!messages?.length) {
|
|
17171
|
-
return [];
|
|
17172
|
-
}
|
|
17173
|
-
return messages.slice(-RECENT_JOB_MESSAGE_LIMIT);
|
|
17174
|
-
}
|
|
17175
|
-
function deriveCurrentStep(platformStatus, messages, stepLabel) {
|
|
17176
|
-
const latest = messages?.at(-1)?.message?.trim();
|
|
17177
|
-
if (latest) {
|
|
17178
|
-
return latest;
|
|
17179
|
-
}
|
|
17180
|
-
const normalized = platformStatus.toLowerCase();
|
|
17181
|
-
if (normalized === "pending" || normalized === "none") {
|
|
17182
|
-
return stepLabel ? `${stepLabel} queued` : "Queued";
|
|
17183
|
-
}
|
|
17184
|
-
if (normalized === "in_progress" || normalized === "running") {
|
|
17185
|
-
return stepLabel ? `${stepLabel} in progress` : "In progress";
|
|
17186
|
-
}
|
|
17187
|
-
if (normalized === "completed" || normalized === "healthy") {
|
|
17188
|
-
return stepLabel ? `${stepLabel} completed` : "Completed";
|
|
17189
|
-
}
|
|
17190
|
-
if (normalized === "failed" || normalized === "cancelled") {
|
|
17191
|
-
return stepLabel ? `${stepLabel} failed` : "Failed";
|
|
17192
|
-
}
|
|
17193
|
-
return stepLabel ?? platformStatus;
|
|
17194
|
-
}
|
|
17195
|
-
function buildProgressSummary(options) {
|
|
17196
|
-
return {
|
|
17197
|
-
stepsCompleted: options.stepLabel,
|
|
17198
|
-
lastMessage: options.messages?.at(-1)?.message ?? null,
|
|
17199
|
-
elapsedMs: Date.now() - options.startedAtMs,
|
|
17200
|
-
terminalStatus: options.terminalStatus
|
|
17201
|
-
};
|
|
17202
|
-
}
|
|
17203
|
-
async function reportPollProgress(progress, stepLabel, value) {
|
|
17204
|
-
if (!progress) {
|
|
17205
|
-
return;
|
|
17206
|
-
}
|
|
17207
|
-
if (progress.isCancelled()) {
|
|
17208
|
-
throw new Error("Operation cancelled.");
|
|
17209
|
-
}
|
|
17210
|
-
const latestMessage = value.messages?.at(-1)?.message;
|
|
17211
|
-
await progress.onStep(stepLabel, {
|
|
17212
|
-
platformStatus: value.status,
|
|
17213
|
-
message: latestMessage
|
|
17214
|
-
});
|
|
17215
|
-
if (value.messages?.length) {
|
|
17216
|
-
await progress.onNewMessages(value.messages);
|
|
17217
|
-
}
|
|
17218
|
-
}
|
|
17219
|
-
|
|
17220
17261
|
// src/cli/platform/helpers/status.ts
|
|
17221
17262
|
function normalizeInfrastructureStatus(platformStatus) {
|
|
17222
17263
|
switch (platformStatus.toLowerCase()) {
|
|
@@ -18024,8 +18065,8 @@ async function prepareOpenApiServersForGatewayBuild(options) {
|
|
|
18024
18065
|
try {
|
|
18025
18066
|
const raw = await readFile16(path56.join(siteDirectory, APITOGO_CONFIG_FILENAME2), "utf8");
|
|
18026
18067
|
const config2 = JSON.parse(raw);
|
|
18027
|
-
const
|
|
18028
|
-
openApiPath = resolveBackendOpenApiPath(
|
|
18068
|
+
const input4 = Array.isArray(config2.apis) ? config2.apis[0]?.input?.trim() : void 0;
|
|
18069
|
+
openApiPath = resolveBackendOpenApiPath(input4, { siteDirectory });
|
|
18029
18070
|
} catch {
|
|
18030
18071
|
}
|
|
18031
18072
|
}
|
|
@@ -18074,15 +18115,15 @@ function runDotnetPublish(projectDir, outputDir) {
|
|
|
18074
18115
|
shell: process.platform === "win32"
|
|
18075
18116
|
}
|
|
18076
18117
|
);
|
|
18077
|
-
let
|
|
18118
|
+
let output3 = "";
|
|
18078
18119
|
child.stdout.on("data", (chunk) => {
|
|
18079
|
-
|
|
18120
|
+
output3 += chunk.toString();
|
|
18080
18121
|
});
|
|
18081
18122
|
child.stderr.on("data", (chunk) => {
|
|
18082
|
-
|
|
18123
|
+
output3 += chunk.toString();
|
|
18083
18124
|
});
|
|
18084
18125
|
child.on("error", reject);
|
|
18085
|
-
child.on("close", (exitCode) => resolve({ exitCode, output:
|
|
18126
|
+
child.on("close", (exitCode) => resolve({ exitCode, output: output3 }));
|
|
18086
18127
|
});
|
|
18087
18128
|
}
|
|
18088
18129
|
async function findCsproj(projectDir) {
|
|
@@ -18169,12 +18210,12 @@ async function packageBackendDirectory(sourceDirectory) {
|
|
|
18169
18210
|
`apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
|
|
18170
18211
|
);
|
|
18171
18212
|
await new Promise((resolve, reject) => {
|
|
18172
|
-
const
|
|
18213
|
+
const output3 = createWriteStream2(zipPath);
|
|
18173
18214
|
const archive = new ZipArchive({ zlib: { level: 6 } });
|
|
18174
|
-
|
|
18215
|
+
output3.on("close", () => resolve());
|
|
18175
18216
|
archive.on("error", reject);
|
|
18176
|
-
|
|
18177
|
-
archive.pipe(
|
|
18217
|
+
output3.on("error", reject);
|
|
18218
|
+
archive.pipe(output3);
|
|
18178
18219
|
for (const rel of files) {
|
|
18179
18220
|
archive.append(createReadStream2(path58.join(resolved, rel)), { name: rel.split(path58.sep).join("/") });
|
|
18180
18221
|
}
|
|
@@ -18777,6 +18818,42 @@ async function loadPlatformPlanSelectionPayload(client) {
|
|
|
18777
18818
|
const quota = freeProjectsQuotaFromTenant(tenant);
|
|
18778
18819
|
return getPlatformPlanCatalogPayload(quota);
|
|
18779
18820
|
}
|
|
18821
|
+
async function handleWaitForPlatformPlan(client, config2, args, progress) {
|
|
18822
|
+
const projectId = resolveProjectId(args.projectId, config2);
|
|
18823
|
+
const wait = args.wait !== false;
|
|
18824
|
+
if (!wait) {
|
|
18825
|
+
const subscription = await client.getSubscription(projectId);
|
|
18826
|
+
return JSON.stringify(
|
|
18827
|
+
{
|
|
18828
|
+
status: isPlatformPlanReady(subscription) ? "succeeded" : "pending",
|
|
18829
|
+
projectId,
|
|
18830
|
+
subscription,
|
|
18831
|
+
ready: isPlatformPlanReady(subscription),
|
|
18832
|
+
nextStep: isPlatformPlanReady(subscription) ? "publish_dev_portal" : "Complete plan selection or wait for Stripe checkout, then retry."
|
|
18833
|
+
},
|
|
18834
|
+
null,
|
|
18835
|
+
2
|
|
18836
|
+
);
|
|
18837
|
+
}
|
|
18838
|
+
const planProgress = progress?.child("Wait for platform plan");
|
|
18839
|
+
const result = await waitForPlatformPlan(client, projectId, {
|
|
18840
|
+
timeoutMs: args.timeoutMs,
|
|
18841
|
+
pollIntervalMs: args.pollIntervalMs,
|
|
18842
|
+
progress: planProgress
|
|
18843
|
+
});
|
|
18844
|
+
return JSON.stringify(
|
|
18845
|
+
{
|
|
18846
|
+
status: result.status === "succeeded" ? "succeeded" : "timeout",
|
|
18847
|
+
projectId,
|
|
18848
|
+
subscription: result.subscription,
|
|
18849
|
+
ready: result.status === "succeeded",
|
|
18850
|
+
timedOut: result.timedOut,
|
|
18851
|
+
nextStep: result.status === "succeeded" ? "publish_dev_portal" : "Plan selection or Stripe checkout did not complete in time. Retry wait_for_platform_plan."
|
|
18852
|
+
},
|
|
18853
|
+
null,
|
|
18854
|
+
2
|
|
18855
|
+
);
|
|
18856
|
+
}
|
|
18780
18857
|
async function handleEnsurePlatformPlan(client, config2, args, progress) {
|
|
18781
18858
|
const wait = args.wait !== false;
|
|
18782
18859
|
const steps = [];
|
|
@@ -19583,12 +19660,12 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
|
|
|
19583
19660
|
`apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
|
|
19584
19661
|
);
|
|
19585
19662
|
await new Promise((resolve, reject) => {
|
|
19586
|
-
const
|
|
19663
|
+
const output3 = createWriteStream3(archivePath);
|
|
19587
19664
|
const archive = new TarArchive({ gzip: true, gzipOptions: { level: 6 } });
|
|
19588
|
-
|
|
19665
|
+
output3.on("close", () => resolve());
|
|
19589
19666
|
archive.on("error", reject);
|
|
19590
|
-
|
|
19591
|
-
archive.pipe(
|
|
19667
|
+
output3.on("error", reject);
|
|
19668
|
+
archive.pipe(output3);
|
|
19592
19669
|
for (const rel of files) {
|
|
19593
19670
|
const entryName = entryPrefix + rel.split(path59.sep).join("/");
|
|
19594
19671
|
archive.append(createReadStream3(path59.join(resolved, rel)), { name: entryName });
|
|
@@ -21121,20 +21198,202 @@ async function handleVerifyDevPortalLive(client, config2, args) {
|
|
|
21121
21198
|
);
|
|
21122
21199
|
}
|
|
21123
21200
|
|
|
21201
|
+
// src/cli/apply/human-output.ts
|
|
21202
|
+
function formatNonSuccessResultForHuman(parsed) {
|
|
21203
|
+
const status2 = parsed.status;
|
|
21204
|
+
if (status2 === "blocked" && parsed.reason === "platform_plan_unselected") {
|
|
21205
|
+
const lines = [
|
|
21206
|
+
"Deploy is blocked: this project doesn't have an API ToGo platform hosting plan yet."
|
|
21207
|
+
];
|
|
21208
|
+
if (typeof parsed.freeProjectsQuotaHint === "string") {
|
|
21209
|
+
lines.push(parsed.freeProjectsQuotaHint);
|
|
21210
|
+
}
|
|
21211
|
+
lines.push(
|
|
21212
|
+
"Pick a plan and re-run:",
|
|
21213
|
+
" apitogo deploy --platform-plan free",
|
|
21214
|
+
" apitogo deploy --platform-plan starter",
|
|
21215
|
+
" apitogo deploy --platform-plan professional",
|
|
21216
|
+
"Run `apitogo deploy --json` to see full plan details (pricing, limits) as data."
|
|
21217
|
+
);
|
|
21218
|
+
return lines;
|
|
21219
|
+
}
|
|
21220
|
+
if (status2 === "blocked" && parsed.reason === "paid_gateway_plans_require_starter") {
|
|
21221
|
+
const lines = [];
|
|
21222
|
+
lines.push(
|
|
21223
|
+
typeof parsed.userMessage === "string" ? parsed.userMessage : "Deploy is blocked: your Free platform plan can't host paid API plans."
|
|
21224
|
+
);
|
|
21225
|
+
lines.push(
|
|
21226
|
+
"Choose one:",
|
|
21227
|
+
" apitogo deploy --platform-plan starter # or professional, to keep the paid plans",
|
|
21228
|
+
" Edit apitogo.config.json to remove those plans or set their price to 0, then re-run apitogo deploy"
|
|
21229
|
+
);
|
|
21230
|
+
return lines;
|
|
21231
|
+
}
|
|
21232
|
+
if (status2 === "blocked") {
|
|
21233
|
+
return [
|
|
21234
|
+
typeof parsed.userMessage === "string" ? parsed.userMessage : `Deploy is blocked${typeof parsed.reason === "string" ? `: ${parsed.reason}` : "."}`
|
|
21235
|
+
];
|
|
21236
|
+
}
|
|
21237
|
+
if (status2 === "failed") {
|
|
21238
|
+
const lines = [
|
|
21239
|
+
`Deploy failed${typeof parsed.failedStep === "string" ? ` at step "${parsed.failedStep}"` : ""}.`
|
|
21240
|
+
];
|
|
21241
|
+
if (typeof parsed.error === "string") {
|
|
21242
|
+
lines.push(parsed.error);
|
|
21243
|
+
}
|
|
21244
|
+
if (typeof parsed.recoveryHint === "string") {
|
|
21245
|
+
lines.push(parsed.recoveryHint);
|
|
21246
|
+
}
|
|
21247
|
+
if (typeof parsed.failedStep === "string") {
|
|
21248
|
+
lines.push(
|
|
21249
|
+
`To retry from there: apitogo deploy --resume-from ${parsed.failedStep}`
|
|
21250
|
+
);
|
|
21251
|
+
}
|
|
21252
|
+
return lines;
|
|
21253
|
+
}
|
|
21254
|
+
return [];
|
|
21255
|
+
}
|
|
21256
|
+
|
|
21257
|
+
// src/cli/apply/platform-plan-prompt.ts
|
|
21258
|
+
import { stdin as input3, stdout as output2 } from "node:process";
|
|
21259
|
+
import { createInterface as createInterface2 } from "node:readline/promises";
|
|
21260
|
+
import open from "open";
|
|
21261
|
+
var PLAN_CHOICES = [
|
|
21262
|
+
"free",
|
|
21263
|
+
"starter",
|
|
21264
|
+
"professional"
|
|
21265
|
+
];
|
|
21266
|
+
function printPlanCatalog(payload) {
|
|
21267
|
+
printDiagnosticsToConsole(
|
|
21268
|
+
"This project needs an API ToGo platform hosting plan before it can deploy."
|
|
21269
|
+
);
|
|
21270
|
+
if (typeof payload.freeProjectsQuotaHint === "string") {
|
|
21271
|
+
printDiagnosticsToConsole(payload.freeProjectsQuotaHint);
|
|
21272
|
+
}
|
|
21273
|
+
const catalog = Array.isArray(payload.platformPlanCatalog) ? payload.platformPlanCatalog : [];
|
|
21274
|
+
for (const entry of catalog) {
|
|
21275
|
+
if (!entry || typeof entry !== "object") continue;
|
|
21276
|
+
const plan = entry;
|
|
21277
|
+
printDiagnosticsToConsole("");
|
|
21278
|
+
printDiagnosticsToConsole(`${plan.displayName} \u2014 ${plan.priceLabel}`);
|
|
21279
|
+
if (plan.summary) {
|
|
21280
|
+
printDiagnosticsToConsole(` ${plan.summary}`);
|
|
21281
|
+
}
|
|
21282
|
+
for (const feature of plan.features ?? []) {
|
|
21283
|
+
printDiagnosticsToConsole(` + ${feature}`);
|
|
21284
|
+
}
|
|
21285
|
+
for (const limitation of plan.limitations ?? []) {
|
|
21286
|
+
printDiagnosticsToConsole(` - ${limitation}`);
|
|
21287
|
+
}
|
|
21288
|
+
}
|
|
21289
|
+
printDiagnosticsToConsole("");
|
|
21290
|
+
}
|
|
21291
|
+
async function askPlanChoice() {
|
|
21292
|
+
const rl = createInterface2({ input: input3, output: output2 });
|
|
21293
|
+
try {
|
|
21294
|
+
while (true) {
|
|
21295
|
+
const answer = (await rl.question(
|
|
21296
|
+
"Choose a plan [free/starter/professional] (leave empty to cancel): "
|
|
21297
|
+
)).trim().toLowerCase();
|
|
21298
|
+
if (!answer) return null;
|
|
21299
|
+
if (PLAN_CHOICES.includes(answer)) {
|
|
21300
|
+
return answer;
|
|
21301
|
+
}
|
|
21302
|
+
printDiagnosticsToConsole('Enter "free", "starter", or "professional".');
|
|
21303
|
+
}
|
|
21304
|
+
} finally {
|
|
21305
|
+
rl.close();
|
|
21306
|
+
}
|
|
21307
|
+
}
|
|
21308
|
+
async function resolvePlatformPlanInteractively(client, config2, payload) {
|
|
21309
|
+
const projectId = typeof payload.projectId === "string" ? payload.projectId : "";
|
|
21310
|
+
if (!projectId) {
|
|
21311
|
+
return false;
|
|
21312
|
+
}
|
|
21313
|
+
printPlanCatalog(payload);
|
|
21314
|
+
if (typeof payload.platformPlanUserPrompt === "string") {
|
|
21315
|
+
printDiagnosticsToConsole(payload.platformPlanUserPrompt);
|
|
21316
|
+
}
|
|
21317
|
+
const choice = await askPlanChoice();
|
|
21318
|
+
if (!choice) {
|
|
21319
|
+
printWarningToConsole(
|
|
21320
|
+
"No plan selected. Re-run with --platform-plan free|starter|professional when you're ready."
|
|
21321
|
+
);
|
|
21322
|
+
return false;
|
|
21323
|
+
}
|
|
21324
|
+
if (choice === "free") {
|
|
21325
|
+
const ensured2 = JSON.parse(
|
|
21326
|
+
await handleEnsurePlatformPlan(client, config2, {
|
|
21327
|
+
projectId,
|
|
21328
|
+
plan: "free"
|
|
21329
|
+
})
|
|
21330
|
+
);
|
|
21331
|
+
if (ensured2.status !== "succeeded") {
|
|
21332
|
+
printWarningToConsole(
|
|
21333
|
+
ensured2.message ?? "Could not activate the Free plan."
|
|
21334
|
+
);
|
|
21335
|
+
return false;
|
|
21336
|
+
}
|
|
21337
|
+
printDiagnosticsToConsole(
|
|
21338
|
+
ensured2.message ?? "Free platform plan selected."
|
|
21339
|
+
);
|
|
21340
|
+
return true;
|
|
21341
|
+
}
|
|
21342
|
+
const ensured = JSON.parse(
|
|
21343
|
+
await handleEnsurePlatformPlan(client, config2, {
|
|
21344
|
+
projectId,
|
|
21345
|
+
plan: choice,
|
|
21346
|
+
wait: false
|
|
21347
|
+
})
|
|
21348
|
+
);
|
|
21349
|
+
if (ensured.status !== "awaiting_checkout" || !ensured.checkoutUrl) {
|
|
21350
|
+
printWarningToConsole(
|
|
21351
|
+
ensured.message ?? `Could not start checkout for the ${choice} plan.`
|
|
21352
|
+
);
|
|
21353
|
+
return false;
|
|
21354
|
+
}
|
|
21355
|
+
printDiagnosticsToConsole(
|
|
21356
|
+
`Opening your browser to complete ${choice} checkout. If it doesn't open, visit:
|
|
21357
|
+
${ensured.checkoutUrl}`
|
|
21358
|
+
);
|
|
21359
|
+
try {
|
|
21360
|
+
await open(ensured.checkoutUrl);
|
|
21361
|
+
} catch {
|
|
21362
|
+
}
|
|
21363
|
+
printDiagnosticsToConsole("Waiting for checkout to complete...");
|
|
21364
|
+
const waited = JSON.parse(
|
|
21365
|
+
await handleWaitForPlatformPlan(client, config2, { projectId, wait: true })
|
|
21366
|
+
);
|
|
21367
|
+
if (waited.status !== "succeeded") {
|
|
21368
|
+
printWarningToConsole(
|
|
21369
|
+
"Checkout didn't complete in time. Finish checkout, then re-run `apitogo deploy`."
|
|
21370
|
+
);
|
|
21371
|
+
return false;
|
|
21372
|
+
}
|
|
21373
|
+
printDiagnosticsToConsole(
|
|
21374
|
+
`${choice.charAt(0).toUpperCase()}${choice.slice(1)} platform plan active.`
|
|
21375
|
+
);
|
|
21376
|
+
return true;
|
|
21377
|
+
}
|
|
21378
|
+
|
|
21124
21379
|
// src/cli/apply/handler.ts
|
|
21125
21380
|
function normalizeOnly(only) {
|
|
21126
21381
|
if (!only) return [];
|
|
21127
21382
|
const values = Array.isArray(only) ? only : [only];
|
|
21128
21383
|
return values.flatMap((value) => value.split(",")).map((value) => value.trim()).filter(Boolean);
|
|
21129
21384
|
}
|
|
21130
|
-
function
|
|
21385
|
+
function safeParseResult(payload) {
|
|
21131
21386
|
try {
|
|
21132
|
-
|
|
21133
|
-
return parsed.status === "failed" || parsed.status === "blocked";
|
|
21387
|
+
return JSON.parse(payload);
|
|
21134
21388
|
} catch {
|
|
21135
|
-
return
|
|
21389
|
+
return null;
|
|
21136
21390
|
}
|
|
21137
21391
|
}
|
|
21392
|
+
function resultLooksFailed(payload) {
|
|
21393
|
+
const parsed = safeParseResult(payload);
|
|
21394
|
+
if (!parsed) return true;
|
|
21395
|
+
return parsed.status === "failed" || parsed.status === "blocked";
|
|
21396
|
+
}
|
|
21138
21397
|
async function apply(argv) {
|
|
21139
21398
|
const sourceDirectory = path63.resolve(process.cwd(), argv.dir);
|
|
21140
21399
|
const config2 = loadConfig();
|
|
@@ -21152,25 +21411,63 @@ async function apply(argv) {
|
|
|
21152
21411
|
}
|
|
21153
21412
|
}
|
|
21154
21413
|
const platformPlan = argv.platformPlan?.trim();
|
|
21155
|
-
|
|
21156
|
-
|
|
21157
|
-
|
|
21414
|
+
const progress = createConsoleProgressReporter();
|
|
21415
|
+
const runOnce = (plan) => runApplyFromSiteDirectory(
|
|
21416
|
+
client,
|
|
21417
|
+
config2,
|
|
21418
|
+
{
|
|
21158
21419
|
sourceDirectory,
|
|
21159
21420
|
projectId: argv.projectId?.trim(),
|
|
21160
21421
|
projectName: argv.projectName?.trim(),
|
|
21161
|
-
platformPlan,
|
|
21422
|
+
platformPlan: plan,
|
|
21162
21423
|
only,
|
|
21163
21424
|
force: argv.force,
|
|
21164
21425
|
resumeFromStep: argv.resumeFrom?.trim(),
|
|
21165
21426
|
wait: argv.wait !== false
|
|
21166
|
-
}
|
|
21427
|
+
},
|
|
21428
|
+
progress
|
|
21429
|
+
);
|
|
21430
|
+
let result;
|
|
21431
|
+
try {
|
|
21432
|
+
result = await runOnce(platformPlan);
|
|
21167
21433
|
} catch (error) {
|
|
21168
21434
|
await printCriticalFailureToConsoleAndExit(
|
|
21169
21435
|
error instanceof Error ? error.message : String(error)
|
|
21170
21436
|
);
|
|
21171
21437
|
return;
|
|
21172
21438
|
}
|
|
21173
|
-
|
|
21439
|
+
let parsed = safeParseResult(result);
|
|
21440
|
+
const canPromptInteractively = !argv.json && Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
21441
|
+
if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "platform_plan_unselected") {
|
|
21442
|
+
const resolved = await resolvePlatformPlanInteractively(
|
|
21443
|
+
client,
|
|
21444
|
+
config2,
|
|
21445
|
+
parsed
|
|
21446
|
+
);
|
|
21447
|
+
if (resolved) {
|
|
21448
|
+
try {
|
|
21449
|
+
result = await runOnce(void 0);
|
|
21450
|
+
} catch (error) {
|
|
21451
|
+
await printCriticalFailureToConsoleAndExit(
|
|
21452
|
+
error instanceof Error ? error.message : String(error)
|
|
21453
|
+
);
|
|
21454
|
+
return;
|
|
21455
|
+
}
|
|
21456
|
+
parsed = safeParseResult(result);
|
|
21457
|
+
}
|
|
21458
|
+
}
|
|
21459
|
+
if (argv.json) {
|
|
21460
|
+
console.log(result);
|
|
21461
|
+
} else {
|
|
21462
|
+
const humanLines = parsed ? formatNonSuccessResultForHuman(parsed) : [];
|
|
21463
|
+
if (humanLines.length > 0) {
|
|
21464
|
+
for (const line of humanLines) {
|
|
21465
|
+
console.log(line);
|
|
21466
|
+
}
|
|
21467
|
+
} else {
|
|
21468
|
+
console.log(result);
|
|
21469
|
+
}
|
|
21470
|
+
}
|
|
21174
21471
|
if (resultLooksFailed(result)) {
|
|
21175
21472
|
process.exit(1);
|
|
21176
21473
|
}
|
|
@@ -21555,10 +21852,10 @@ function siteRelative(siteDirectory, filePath) {
|
|
|
21555
21852
|
function formatOpenApiDiscoveryLines(siteDirectory, openApiDiscovery) {
|
|
21556
21853
|
const status2 = String(openApiDiscovery.status ?? "unknown");
|
|
21557
21854
|
if (status2 === "wired") {
|
|
21558
|
-
const
|
|
21855
|
+
const input4 = typeof openApiDiscovery.openApiInput === "string" ? openApiDiscovery.openApiInput : typeof openApiDiscovery.openApiPath === "string" ? siteRelative(siteDirectory, openApiDiscovery.openApiPath) : "OpenAPI";
|
|
21559
21856
|
const title = typeof openApiDiscovery.openApiTitle === "string" ? ` (${openApiDiscovery.openApiTitle})` : "";
|
|
21560
21857
|
const apiPath = typeof openApiDiscovery.apiReferencePath === "string" ? openApiDiscovery.apiReferencePath : "/api";
|
|
21561
|
-
return [`OpenAPI: wired ${
|
|
21858
|
+
return [`OpenAPI: wired ${input4}${title} \u2192 ${apiPath}`];
|
|
21562
21859
|
}
|
|
21563
21860
|
if (status2 === "skipped") {
|
|
21564
21861
|
return ["OpenAPI: search skipped"];
|
|
@@ -21610,23 +21907,23 @@ async function pathExists6(filePath) {
|
|
|
21610
21907
|
}
|
|
21611
21908
|
}
|
|
21612
21909
|
async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
|
|
21613
|
-
const
|
|
21910
|
+
const input4 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
|
|
21614
21911
|
const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
|
|
21615
21912
|
const raw = await readFile19(jsonConfigPath, "utf8");
|
|
21616
21913
|
const siteConfig = JSON.parse(raw);
|
|
21617
21914
|
const updated = applyOpenApiToSiteConfig(siteConfig, {
|
|
21618
|
-
input:
|
|
21915
|
+
input: input4,
|
|
21619
21916
|
apiPath: "api"
|
|
21620
21917
|
});
|
|
21621
21918
|
const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
|
|
21622
|
-
updated.backend = { ...backend, openApiPath:
|
|
21919
|
+
updated.backend = { ...backend, openApiPath: input4 };
|
|
21623
21920
|
await writeFile18(
|
|
21624
21921
|
jsonConfigPath,
|
|
21625
21922
|
`${JSON.stringify(updated, null, 2)}
|
|
21626
21923
|
`,
|
|
21627
21924
|
"utf8"
|
|
21628
21925
|
);
|
|
21629
|
-
return { input:
|
|
21926
|
+
return { input: input4 };
|
|
21630
21927
|
}
|
|
21631
21928
|
async function discoverAndWireOpenApiLite(siteDirectory, mode) {
|
|
21632
21929
|
if (mode === "none") {
|
|
@@ -21678,7 +21975,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
|
|
|
21678
21975
|
};
|
|
21679
21976
|
}
|
|
21680
21977
|
try {
|
|
21681
|
-
const { input:
|
|
21978
|
+
const { input: input4 } = await wireOpenApiIntoJsonConfig(
|
|
21682
21979
|
siteDirectory,
|
|
21683
21980
|
selected.path
|
|
21684
21981
|
);
|
|
@@ -21686,7 +21983,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
|
|
|
21686
21983
|
openApiDiscovery: {
|
|
21687
21984
|
status: "wired",
|
|
21688
21985
|
openApiPath: selected.path,
|
|
21689
|
-
openApiInput:
|
|
21986
|
+
openApiInput: input4,
|
|
21690
21987
|
openApiTitle: selected.title ?? null,
|
|
21691
21988
|
openApiVersion: selected.version ?? null,
|
|
21692
21989
|
apiReferencePath: "/api",
|
|
@@ -21884,7 +22181,7 @@ var init_default = {
|
|
|
21884
22181
|
|
|
21885
22182
|
// src/cli/login/handler.ts
|
|
21886
22183
|
import readline from "node:readline/promises";
|
|
21887
|
-
import
|
|
22184
|
+
import open2 from "open";
|
|
21888
22185
|
|
|
21889
22186
|
// src/cli/platform/device-auth.ts
|
|
21890
22187
|
function url(apiUrl, path72) {
|
|
@@ -21958,7 +22255,7 @@ async function login() {
|
|
|
21958
22255
|
await waitForEnter("Press Enter to open your browser...");
|
|
21959
22256
|
let openedBrowser = true;
|
|
21960
22257
|
try {
|
|
21961
|
-
await
|
|
22258
|
+
await open2(device.verificationUriComplete);
|
|
21962
22259
|
} catch {
|
|
21963
22260
|
openedBrowser = false;
|
|
21964
22261
|
}
|
|
@@ -22084,14 +22381,19 @@ async function createProject(argv) {
|
|
|
22084
22381
|
const client = new PlatformApiClient(config2);
|
|
22085
22382
|
let result;
|
|
22086
22383
|
try {
|
|
22087
|
-
result = await handleBootstrapProject(
|
|
22088
|
-
|
|
22089
|
-
|
|
22090
|
-
|
|
22091
|
-
|
|
22092
|
-
|
|
22093
|
-
|
|
22094
|
-
|
|
22384
|
+
result = await handleBootstrapProject(
|
|
22385
|
+
client,
|
|
22386
|
+
config2,
|
|
22387
|
+
{
|
|
22388
|
+
name,
|
|
22389
|
+
description: argv.description?.trim(),
|
|
22390
|
+
modules: modules.length > 0 ? modules : ["apihub"],
|
|
22391
|
+
selectFreePlan: false,
|
|
22392
|
+
wait: argv.wait !== false,
|
|
22393
|
+
configureGatewayBaseline: false
|
|
22394
|
+
},
|
|
22395
|
+
createConsoleProgressReporter()
|
|
22396
|
+
);
|
|
22095
22397
|
} catch (error) {
|
|
22096
22398
|
await printCriticalFailureToConsoleAndExit(
|
|
22097
22399
|
error instanceof Error ? error.message : String(error)
|
|
@@ -22646,10 +22948,15 @@ async function teardown(argv) {
|
|
|
22646
22948
|
}
|
|
22647
22949
|
let result;
|
|
22648
22950
|
try {
|
|
22649
|
-
result = await handleTeardownProject(
|
|
22650
|
-
|
|
22651
|
-
|
|
22652
|
-
|
|
22951
|
+
result = await handleTeardownProject(
|
|
22952
|
+
client,
|
|
22953
|
+
config2,
|
|
22954
|
+
{
|
|
22955
|
+
projectId,
|
|
22956
|
+
wait: argv.wait !== false
|
|
22957
|
+
},
|
|
22958
|
+
createConsoleProgressReporter()
|
|
22959
|
+
);
|
|
22653
22960
|
} catch (error) {
|
|
22654
22961
|
await printCriticalFailureToConsoleAndExit(
|
|
22655
22962
|
error instanceof Error ? error.message : String(error)
|
|
@@ -38,6 +38,7 @@ export declare function buildProgressSummary(options: {
|
|
|
38
38
|
terminalStatus: string;
|
|
39
39
|
};
|
|
40
40
|
export declare function createMcpProgressReporter(extra?: McpToolExtra): ProgressReporter;
|
|
41
|
+
export declare function createConsoleProgressReporter(stream?: NodeJS.WritableStream): ProgressReporter;
|
|
41
42
|
export interface PollableJobValue {
|
|
42
43
|
status: string;
|
|
43
44
|
messages?: JobLogMessage[];
|