@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(output2) {
5071
- if (Array.isArray(output2)) {
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 output2) {
5075
- const result = output2.output.find(
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.114",
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 = (input3) => {
7636
- const idx = input3.indexOf("?");
7635
+ var parseInputString = (input4) => {
7636
+ const idx = input4.indexOf("?");
7637
7637
  if (idx === -1)
7638
- return { filePath: input3, params: {} };
7638
+ return { filePath: input4, params: {} };
7639
7639
  return {
7640
- filePath: input3.slice(0, idx),
7641
- params: Object.fromEntries(new URLSearchParams(input3.slice(idx)))
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 = (input3, params) => {
7678
- const filePath = path11.resolve(this.config.__meta.rootDir, input3);
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 (input3) => {
7689
- const filePath = path11.resolve(this.config.__meta.rootDir, input3.input);
7690
- const params = input3.params;
7691
- const configuredPath = this.getPathForFile(input3.input, params);
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 ${input3.input}`);
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((input3) => ({
7800
+ this.processedSchemas[apiConfig.path] = inputs.map((input4) => ({
7801
7801
  schema: {},
7802
7802
  version: "",
7803
- path: input3.path ?? "",
7804
- label: input3.label,
7805
- inputPath: path11.resolve(this.config.__meta.rootDir, input3.input),
7806
- params: input3.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((input3) => this.processSchema(input3))
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: (input3) => parse(input3) ?? {},
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 output2 = {
10165
+ const output3 = {
10166
10166
  version: 3,
10167
10167
  framework: {
10168
10168
  version: pkgJson.version
10169
10169
  },
10170
10170
  routes
10171
10171
  };
10172
- return output2;
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 output2 = generateOutput({ config: config2, redirects, rewrites });
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(output2, null, 2), "utf-8");
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(output2) {
10204
+ function writeLine(output3) {
10205
10205
  clearLine();
10206
- if (output2.length < process.stdout.columns) {
10207
- process.stdout.write(output2);
10206
+ if (output3.length < process.stdout.columns) {
10207
+ process.stdout.write(output3);
10208
10208
  } else {
10209
- process.stdout.write(output2.substring(0, process.stdout.columns - 1));
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(input3, init4, options) {
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(input3, init4);
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 output2 = "";
12765
+ let output3 = "";
12766
12766
  child.stdout.on("data", (chunk) => {
12767
- output2 += chunk.toString();
12767
+ output3 += chunk.toString();
12768
12768
  });
12769
12769
  child.stderr.on("data", (chunk) => {
12770
- output2 += chunk.toString();
12770
+ output3 += chunk.toString();
12771
12771
  });
12772
12772
  child.on("error", reject);
12773
- child.on("close", (exitCode) => resolve({ exitCode, output: output2 }));
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, open2) {
13820
+ function findMatchingArrayClose(content, open3) {
13821
13821
  let depth = 0;
13822
13822
  let inString = null;
13823
- for (let i = open2; i < content.length; 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 open2 = afterLabel + itemsMatch.index + itemsMatch[0].length - 1;
13863
- const close3 = findMatchingArrayClose(content, open2);
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: open2, close: close3, indent: entryIndent };
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 open2 = callStart + callPrefix.length - 1;
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 = open2; i < content.length; 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 open2 = match.index + match[0].length - 1;
13974
+ const open3 = match.index + match[0].length - 1;
13975
13975
  let depth = 0;
13976
13976
  let inString = null;
13977
- for (let i = open2; i < content.length; 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: open2, close: i, indent };
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 output2 = "";
14422
+ let output3 = "";
14423
14423
  child.stdout.on("data", (chunk) => {
14424
- output2 += chunk.toString();
14424
+ output3 += chunk.toString();
14425
14425
  });
14426
14426
  child.stderr.on("data", (chunk) => {
14427
- output2 += chunk.toString();
14427
+ output3 += chunk.toString();
14428
14428
  });
14429
14429
  child.on("error", reject);
14430
- child.on("close", (exitCode) => resolve({ exitCode, output: output2 }));
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, input3 = "./openapi.json") {
14616
+ function patchApitogoConfigOpenApiToFile(content, input4 = "./openapi.json") {
14617
14617
  return patchApisConfig(content, {
14618
14618
  type: "file",
14619
- input: input3,
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 input3 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
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: input3,
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, input3);
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: input3
14871
+ openApiPath: input4
14872
14872
  };
14873
14873
  await writeManifest(resolvedSource, manifest);
14874
14874
  return {
14875
14875
  status: "succeeded",
14876
14876
  openApiPath: resolvedOpenApi,
14877
- openApiInput: input3,
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, input3) {
15298
+ function applyOpenApiToJsonConfig(config2, input4) {
15299
15299
  const next = { ...config2 };
15300
15300
  next.apis = [
15301
15301
  {
15302
15302
  type: "file",
15303
- input: input3,
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(input3) {
15347
- const sku = input3.sku ?? slugifyPlanSku(input3.displayName);
15346
+ function buildPlanItemFromWizard(input4) {
15347
+ const sku = input4.sku ?? slugifyPlanSku(input4.displayName);
15348
15348
  const item = {
15349
15349
  sku,
15350
- displayName: input3.displayName,
15351
- priceAmount: input3.priceAmount,
15352
- limits: buildLimits(input3.rateLimitCalls, input3.monthlyQuota)
15350
+ displayName: input4.displayName,
15351
+ priceAmount: input4.priceAmount,
15352
+ limits: buildLimits(input4.rateLimitCalls, input4.monthlyQuota)
15353
15353
  };
15354
- if (input3.priceAmount > 0) {
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, input3] of manifestPlans.entries()) {
16940
- const key = input3.sku.toLowerCase();
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 '${input3.sku}' was not found; upsert plans before reordering.`);
17037
+ throw new Error(`Gateway plan '${input4.sku}' was not found; upsert plans before reordering.`);
16944
17038
  }
16945
- const sku = skuById?.get(key)?.sku ?? input3.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 input3 = normalizePlanForGatewayApi(inputRaw);
16992
- const found = bySku.get(input3.sku.toLowerCase());
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
- input3,
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(input3.sku.toLowerCase(), found.id);
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: input3.displayName,
17109
+ displayName: input4.displayName,
17016
17110
  isActive: true,
17017
- limitsJson: planLimitsForPlatform(input3),
17018
- priceAmount: input3.priceAmount,
17019
- priceCurrency: input3.priceCurrency,
17020
- billingPeriod: input3.billingPeriod ? normalizeBillingPeriod2(input3.billingPeriod) : void 0
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
- input3,
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(input3.sku.toLowerCase(), found.id);
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: input3.sku,
17040
- displayName: input3.displayName,
17041
- priceAmount: input3.priceAmount,
17042
- priceCurrency: input3.priceCurrency ?? "usd",
17043
- billingPeriod: normalizeBillingPeriod2(input3.billingPeriod),
17044
- limitsJson: planLimitsForPlatform(input3),
17045
- includedActionKeys: options?.deferActionKeys ? [] : await resolveActionKeysOrAllProjectActions(input3, void 0, projectActionKeys),
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(input3.sku.toLowerCase(), created.plan.id);
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 input3 = Array.isArray(config2.apis) ? config2.apis[0]?.input?.trim() : void 0;
18028
- openApiPath = resolveBackendOpenApiPath(input3, { siteDirectory });
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 output2 = "";
18118
+ let output3 = "";
18078
18119
  child.stdout.on("data", (chunk) => {
18079
- output2 += chunk.toString();
18120
+ output3 += chunk.toString();
18080
18121
  });
18081
18122
  child.stderr.on("data", (chunk) => {
18082
- output2 += chunk.toString();
18123
+ output3 += chunk.toString();
18083
18124
  });
18084
18125
  child.on("error", reject);
18085
- child.on("close", (exitCode) => resolve({ exitCode, output: output2 }));
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 output2 = createWriteStream2(zipPath);
18213
+ const output3 = createWriteStream2(zipPath);
18173
18214
  const archive = new ZipArchive({ zlib: { level: 6 } });
18174
- output2.on("close", () => resolve());
18215
+ output3.on("close", () => resolve());
18175
18216
  archive.on("error", reject);
18176
- output2.on("error", reject);
18177
- archive.pipe(output2);
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 output2 = createWriteStream3(archivePath);
19663
+ const output3 = createWriteStream3(archivePath);
19587
19664
  const archive = new TarArchive({ gzip: true, gzipOptions: { level: 6 } });
19588
- output2.on("close", () => resolve());
19665
+ output3.on("close", () => resolve());
19589
19666
  archive.on("error", reject);
19590
- output2.on("error", reject);
19591
- archive.pipe(output2);
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 resultLooksFailed(payload) {
21385
+ function safeParseResult(payload) {
21131
21386
  try {
21132
- const parsed = JSON.parse(payload);
21133
- return parsed.status === "failed" || parsed.status === "blocked";
21387
+ return JSON.parse(payload);
21134
21388
  } catch {
21135
- return true;
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
- let result;
21156
- try {
21157
- result = await runApplyFromSiteDirectory(client, config2, {
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
- console.log(result);
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 input3 = typeof openApiDiscovery.openApiInput === "string" ? openApiDiscovery.openApiInput : typeof openApiDiscovery.openApiPath === "string" ? siteRelative(siteDirectory, openApiDiscovery.openApiPath) : "OpenAPI";
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 ${input3}${title} \u2192 ${apiPath}`];
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 input3 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
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: input3,
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: input3 };
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: input3 };
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: input3 } = await wireOpenApiIntoJsonConfig(
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: input3,
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 open from "open";
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 open(device.verificationUriComplete);
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(client, config2, {
22088
- name,
22089
- description: argv.description?.trim(),
22090
- modules: modules.length > 0 ? modules : ["apihub"],
22091
- selectFreePlan: false,
22092
- wait: argv.wait !== false,
22093
- configureGatewayBaseline: false
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(client, config2, {
22650
- projectId,
22651
- wait: argv.wait !== false
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[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lukoweb/apitogo",
3
- "version": "0.1.114",
3
+ "version": "0.1.116",
4
4
  "type": "module",
5
5
  "sideEffects": [
6
6
  "**/*.css",