@lukoweb/apitogo 0.2.17 → 0.2.20

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
@@ -836,7 +836,7 @@ import { stat as stat4 } from "node:fs/promises";
836
836
  var fileExists;
837
837
  var init_file_exists = __esm({
838
838
  "src/config/file-exists.ts"() {
839
- fileExists = (path101) => stat4(path101).then(() => true).catch(() => false);
839
+ fileExists = (path103) => stat4(path103).then(() => true).catch(() => false);
840
840
  }
841
841
  });
842
842
 
@@ -5267,7 +5267,7 @@ __export(llms_exports, {
5267
5267
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
5268
5268
  });
5269
5269
  import { writeFile as writeFile11 } from "node:fs/promises";
5270
- import path43 from "node:path";
5270
+ import path44 from "node:path";
5271
5271
  import colors10 from "picocolors";
5272
5272
  async function generateLlmsTxtFiles({
5273
5273
  markdownFileInfos,
@@ -5302,7 +5302,7 @@ async function generateLlmsTxtFiles({
5302
5302
  }
5303
5303
  }
5304
5304
  const llmsTxt2 = llmsTxtParts.join("\n");
5305
- await writeFile11(path43.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5305
+ await writeFile11(path44.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5306
5306
  if (process.env.APITOGO_JSON_ONLY !== "1") {
5307
5307
  console.log(colors10.blue("\u2713 generated llms.txt"));
5308
5308
  }
@@ -5330,7 +5330,7 @@ ${info.content}
5330
5330
  }
5331
5331
  const llmsFull = llmsFullParts.join("\n");
5332
5332
  await writeFile11(
5333
- path43.join(baseOutputDir, "llms-full.txt"),
5333
+ path44.join(baseOutputDir, "llms-full.txt"),
5334
5334
  llmsFull,
5335
5335
  "utf-8"
5336
5336
  );
@@ -5809,7 +5809,7 @@ init_package_json();
5809
5809
  import yargs from "yargs/yargs";
5810
5810
 
5811
5811
  // src/cli/services/handler.ts
5812
- import path50 from "node:path";
5812
+ import path53 from "node:path";
5813
5813
  import { createInterface as createInterface2 } from "node:readline/promises";
5814
5814
 
5815
5815
  // src/config/v2/errors.ts
@@ -6189,8 +6189,8 @@ var ConfigV2Schema = z.strictObject({
6189
6189
  var REMOVED_KEYS = {
6190
6190
  "plans.provider": "plans.provider was removed. Only plans.billing.provider (stripe or none) is selectable."
6191
6191
  };
6192
- function pathToString(path101) {
6193
- return path101.reduce(
6192
+ function pathToString(path103) {
6193
+ return path103.reduce(
6194
6194
  (acc, segment) => typeof segment === "number" ? `${acc}[${segment}]` : acc === "" ? String(segment) : `${acc}.${String(segment)}`,
6195
6195
  ""
6196
6196
  );
@@ -6210,9 +6210,9 @@ function step(schema2, segment) {
6210
6210
  }
6211
6211
  return void 0;
6212
6212
  }
6213
- function knownKeysAt(path101) {
6213
+ function knownKeysAt(path103) {
6214
6214
  let current = ConfigV2Schema;
6215
- for (const segment of path101) {
6215
+ for (const segment of path103) {
6216
6216
  if (!current) return [];
6217
6217
  current = step(current, segment);
6218
6218
  }
@@ -6248,7 +6248,7 @@ function unknownKeyHint(fullPath, key, known) {
6248
6248
  return known.length > 0 ? `Allowed keys: ${known.join(", ")}.` : void 0;
6249
6249
  }
6250
6250
  function mapIssue(issue3) {
6251
- const path101 = pathToString(issue3.path);
6251
+ const path103 = pathToString(issue3.path);
6252
6252
  switch (issue3.code) {
6253
6253
  case "unrecognized_keys":
6254
6254
  return issue3.keys.map((key) => {
@@ -6264,20 +6264,20 @@ function mapIssue(issue3) {
6264
6264
  return [
6265
6265
  {
6266
6266
  code: "CONFIG_INVALID_VALUE",
6267
- path: path101,
6267
+ path: path103,
6268
6268
  message: `must be one of: ${issue3.values.map((v) => JSON.stringify(v)).join(", ")}.`
6269
6269
  }
6270
6270
  ];
6271
6271
  case "custom": {
6272
6272
  const code = typeof issue3.params?.code === "string" ? issue3.params.code : "CONFIG_INVALID_VALUE";
6273
- return [{ code, path: path101, message: issue3.message ?? "is invalid." }];
6273
+ return [{ code, path: path103, message: issue3.message ?? "is invalid." }];
6274
6274
  }
6275
6275
  case "invalid_type":
6276
6276
  return [
6277
- /received undefined/.test(issue3.message) ? { code: "CONFIG_MISSING_FIELD", path: path101, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path101, message: issue3.message }
6277
+ /received undefined/.test(issue3.message) ? { code: "CONFIG_MISSING_FIELD", path: path103, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path103, message: issue3.message }
6278
6278
  ];
6279
6279
  default:
6280
- return [{ code: "CONFIG_INVALID_VALUE", path: path101, message: issue3.message }];
6280
+ return [{ code: "CONFIG_INVALID_VALUE", path: path103, message: issue3.message }];
6281
6281
  }
6282
6282
  }
6283
6283
  function isRecord(value) {
@@ -7301,7 +7301,7 @@ var ServiceManifestSchema = z3.looseObject({
7301
7301
  }).optional()
7302
7302
  }).default({})
7303
7303
  });
7304
- var issue = (code, path101, message, hint) => ({ code, path: path101, message, hint });
7304
+ var issue = (code, path103, message, hint) => ({ code, path: path103, message, hint });
7305
7305
  function parseManifest(raw, file = "services.json") {
7306
7306
  const version = typeof raw === "object" && raw !== null && "schemaVersion" in raw ? raw.schemaVersion : void 0;
7307
7307
  if (typeof version === "number" && version > SUPPORTED_MANIFEST_SCHEMA) {
@@ -7504,8 +7504,8 @@ var METHODS = [
7504
7504
  "trace"
7505
7505
  ];
7506
7506
  var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
7507
- function actionKey(method, path101) {
7508
- const trimmed = path101.trim();
7507
+ function actionKey(method, path103) {
7508
+ const trimmed = path103.trim();
7509
7509
  const withSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
7510
7510
  const normalized = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") || "/" : withSlash;
7511
7511
  return `${method.trim().toLowerCase()}:${normalized}`;
@@ -7542,8 +7542,8 @@ var ReferenceSpecError = class extends Error {
7542
7542
  };
7543
7543
  function operationsOf(paths) {
7544
7544
  return Object.entries(paths).flatMap(
7545
- ([path101, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
7546
- (method) => [path101, item, method]
7545
+ ([path103, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
7546
+ (method) => [path103, item, method]
7547
7547
  ) : []
7548
7548
  );
7549
7549
  }
@@ -7558,14 +7558,14 @@ function buildReferenceSpec(specText, options) {
7558
7558
  throw new ReferenceSpecError("The OpenAPI file could not be read.");
7559
7559
  const doc = structuredClone(root);
7560
7560
  const paths = isObject(doc.paths) ? doc.paths : {};
7561
- for (const [path101, item, method] of operationsOf(paths))
7562
- if (options.deniedOperations.has(actionKey(method, path101)))
7561
+ for (const [path103, item, method] of operationsOf(paths))
7562
+ if (options.deniedOperations.has(actionKey(method, path103)))
7563
7563
  delete item[method];
7564
- for (const [path101, item] of Object.entries(paths))
7564
+ for (const [path103, item] of Object.entries(paths))
7565
7565
  if (!isObject(item) || !METHODS.some((method) => method in item))
7566
- delete paths[path101];
7567
- for (const [path101, item, method] of operationsOf(paths))
7568
- if (options.publicOperations.has(actionKey(method, path101)))
7566
+ delete paths[path103];
7567
+ for (const [path103, item, method] of operationsOf(paths))
7568
+ if (options.publicOperations.has(actionKey(method, path103)))
7569
7569
  item[method].security = [];
7570
7570
  doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
7571
7571
  for (const item of Object.values(paths)) {
@@ -8049,7 +8049,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
8049
8049
  if (mode === "production") {
8050
8050
  issues.push(...missingManifestServices(resolved, manifest));
8051
8051
  }
8052
- } else if (mode === "development") {
8052
+ } else if (mode === "development" && requiredServices(resolved).length > 0) {
8053
8053
  effective = stubManifest(resolved);
8054
8054
  manifestSource = "preview-stub";
8055
8055
  } else {
@@ -8836,8 +8836,8 @@ init_invariant();
8836
8836
 
8837
8837
  // src/cli/check/v2.ts
8838
8838
  init_apitogo_config_core();
8839
- import { readFile as readFile13 } from "node:fs/promises";
8840
- import path47 from "node:path";
8839
+ import { readFile as readFile14 } from "node:fs/promises";
8840
+ import path49 from "node:path";
8841
8841
 
8842
8842
  // src/cli/platform/client/platform-api.ts
8843
8843
  import { basename } from "node:path";
@@ -8950,8 +8950,8 @@ var PlatformApiClient = class {
8950
8950
  constructor(config2) {
8951
8951
  this.config = config2;
8952
8952
  }
8953
- url(path101) {
8954
- return `${this.config.apiUrl}${path101.startsWith("/") ? path101 : `/${path101}`}`;
8953
+ url(path103) {
8954
+ return `${this.config.apiUrl}${path103.startsWith("/") ? path103 : `/${path103}`}`;
8955
8955
  }
8956
8956
  headers(extra) {
8957
8957
  return {
@@ -8961,9 +8961,9 @@ var PlatformApiClient = class {
8961
8961
  ...extra
8962
8962
  };
8963
8963
  }
8964
- async request(method, path101, init4) {
8964
+ async request(method, path103, init4) {
8965
8965
  const response = await fetchWithRetry(
8966
- this.url(path101),
8966
+ this.url(path103),
8967
8967
  {
8968
8968
  method,
8969
8969
  ...init4,
@@ -9326,15 +9326,15 @@ var PlatformApiClient = class {
9326
9326
  }
9327
9327
  );
9328
9328
  }
9329
- deleteDevPortalPage(projectId, path101) {
9330
- const query = new URLSearchParams({ path: path101 });
9329
+ deleteDevPortalPage(projectId, path103) {
9330
+ const query = new URLSearchParams({ path: path103 });
9331
9331
  return this.request(
9332
9332
  "DELETE",
9333
9333
  `/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
9334
9334
  );
9335
9335
  }
9336
- renameDevPortalPage(projectId, path101, newName) {
9337
- const query = new URLSearchParams({ path: path101 });
9336
+ renameDevPortalPage(projectId, path103, newName) {
9337
+ const query = new URLSearchParams({ path: path103 });
9338
9338
  return this.request(
9339
9339
  "POST",
9340
9340
  `/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
@@ -9450,8 +9450,8 @@ var PlatformApiClient = class {
9450
9450
  * the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
9451
9451
  */
9452
9452
  validateGatewayPlans(plans, options = {}) {
9453
- const path101 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
9454
- return this.request("POST", path101, {
9453
+ const path103 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
9454
+ return this.request("POST", path103, {
9455
9455
  headers: { "Content-Type": "application/json" },
9456
9456
  body: JSON.stringify({ plans, planTier: options.planTier })
9457
9457
  });
@@ -9552,8 +9552,8 @@ var PlatformApiClient = class {
9552
9552
  }
9553
9553
  };
9554
9554
  async function readFileBytes(filePath) {
9555
- const { readFile: readFile30 } = await import("node:fs/promises");
9556
- const buffer = await readFile30(filePath);
9555
+ const { readFile: readFile31 } = await import("node:fs/promises");
9556
+ const buffer = await readFile31(filePath);
9557
9557
  const arrayBuffer = new ArrayBuffer(buffer.byteLength);
9558
9558
  new Uint8Array(arrayBuffer).set(buffer);
9559
9559
  return arrayBuffer;
@@ -9650,17 +9650,17 @@ function resolveProjectId(explicit, config2) {
9650
9650
  import {
9651
9651
  access as access4,
9652
9652
  mkdir as mkdir12,
9653
- readFile as readFile11,
9653
+ readFile as readFile12,
9654
9654
  rename as rename6,
9655
9655
  rm as rm8,
9656
- writeFile as writeFile13
9656
+ writeFile as writeFile14
9657
9657
  } from "node:fs/promises";
9658
9658
  import { createRequire as createRequire2 } from "node:module";
9659
- import path46 from "node:path";
9659
+ import path48 from "node:path";
9660
9660
 
9661
9661
  // src/vite/build.ts
9662
9662
  import { mkdir as mkdir11, readFile as readFile10, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
9663
- import path45 from "node:path";
9663
+ import path46 from "node:path";
9664
9664
  import { build as esbuild } from "esbuild";
9665
9665
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
9666
9666
 
@@ -9796,7 +9796,7 @@ init_invariant();
9796
9796
  init_joinUrl();
9797
9797
 
9798
9798
  // src/vite/config.ts
9799
- import path40 from "node:path";
9799
+ import path41 from "node:path";
9800
9800
  import dotenv from "dotenv";
9801
9801
  import colors8 from "picocolors";
9802
9802
  import {
@@ -9807,7 +9807,7 @@ import {
9807
9807
  // package.json
9808
9808
  var package_default = {
9809
9809
  name: "@lukoweb/apitogo",
9810
- version: "0.2.17",
9810
+ version: "0.2.20",
9811
9811
  type: "module",
9812
9812
  sideEffects: [
9813
9813
  "**/*.css",
@@ -10589,14 +10589,14 @@ var flattenAllOf = (schema2) => {
10589
10589
  };
10590
10590
 
10591
10591
  // src/lib/util/traverse.ts
10592
- var traverse = (specification, transform, path101 = []) => {
10593
- const transformed = transform(specification, path101);
10592
+ var traverse = (specification, transform, path103 = []) => {
10593
+ const transformed = transform(specification, path103);
10594
10594
  if (typeof transformed !== "object" || transformed === null) {
10595
10595
  return transformed;
10596
10596
  }
10597
10597
  const result = Array.isArray(transformed) ? [] : {};
10598
10598
  for (const [key, value] of Object.entries(transformed)) {
10599
- const currentPath = [...path101, key];
10599
+ const currentPath = [...path103, key];
10600
10600
  if (Array.isArray(value)) {
10601
10601
  result[key] = value.map(
10602
10602
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -10624,9 +10624,9 @@ var resolveLocalRef = (schema2, ref) => {
10624
10624
  if (schemaCache?.has(ref)) {
10625
10625
  return schemaCache.get(ref);
10626
10626
  }
10627
- const path101 = ref.split("/").slice(1);
10627
+ const path103 = ref.split("/").slice(1);
10628
10628
  let current = schema2;
10629
- for (const segment of path101) {
10629
+ for (const segment of path103) {
10630
10630
  if (!current || typeof current !== "object") {
10631
10631
  current = null;
10632
10632
  }
@@ -10645,7 +10645,7 @@ var dereference = async (schema2, resolvers = []) => {
10645
10645
  }
10646
10646
  const cloned = structuredClone(schema2);
10647
10647
  const visited = /* @__PURE__ */ new Set();
10648
- const resolve = async (current, path101) => {
10648
+ const resolve = async (current, path103) => {
10649
10649
  if (isIndexableObject(current)) {
10650
10650
  if (visited.has(current)) {
10651
10651
  return CIRCULAR_REF;
@@ -10653,7 +10653,7 @@ var dereference = async (schema2, resolvers = []) => {
10653
10653
  visited.add(current);
10654
10654
  if (Array.isArray(current)) {
10655
10655
  for (let index = 0; index < current.length; index++) {
10656
- current[index] = await resolve(current[index], `${path101}/${index}`);
10656
+ current[index] = await resolve(current[index], `${path103}/${index}`);
10657
10657
  }
10658
10658
  } else {
10659
10659
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -10664,13 +10664,13 @@ var dereference = async (schema2, resolvers = []) => {
10664
10664
  for (const resolver of resolvers) {
10665
10665
  const resolved = await resolver($ref);
10666
10666
  if (resolved) {
10667
- result2 = await resolve(resolved, path101);
10667
+ result2 = await resolve(resolved, path103);
10668
10668
  break;
10669
10669
  }
10670
10670
  }
10671
10671
  if (result2 === void 0) {
10672
10672
  const resolved = await resolveLocalRef(cloned, $ref);
10673
- result2 = await resolve(resolved, path101);
10673
+ result2 = await resolve(resolved, path103);
10674
10674
  }
10675
10675
  if (hasSiblings) {
10676
10676
  if (result2 === CIRCULAR_REF) {
@@ -10683,7 +10683,7 @@ var dereference = async (schema2, resolvers = []) => {
10683
10683
  return result2;
10684
10684
  }
10685
10685
  for (const key in current) {
10686
- current[key] = await resolve(current[key], `${path101}/${key}`);
10686
+ current[key] = await resolve(current[key], `${path103}/${key}`);
10687
10687
  }
10688
10688
  }
10689
10689
  visited.delete(current);
@@ -10722,9 +10722,9 @@ var upgradeSchema = (schema2) => {
10722
10722
  }
10723
10723
  return sub;
10724
10724
  });
10725
- schema2 = traverse(schema2, (sub, path101) => {
10725
+ schema2 = traverse(schema2, (sub, path103) => {
10726
10726
  if (sub.example !== void 0) {
10727
- if (isSchemaPath(path101 ?? [])) {
10727
+ if (isSchemaPath(path103 ?? [])) {
10728
10728
  sub.examples = [sub.example];
10729
10729
  } else {
10730
10730
  sub.examples = {
@@ -10737,11 +10737,11 @@ var upgradeSchema = (schema2) => {
10737
10737
  }
10738
10738
  return sub;
10739
10739
  });
10740
- schema2 = traverse(schema2, (schema3, path101) => {
10740
+ schema2 = traverse(schema2, (schema3, path103) => {
10741
10741
  if (schema3.type === "object" && schema3.properties !== void 0) {
10742
- const parentPath = path101?.slice(0, -1);
10742
+ const parentPath = path103?.slice(0, -1);
10743
10743
  const isMultipart = parentPath?.some((segment, index) => {
10744
- return segment === "content" && path101?.[index + 1] === "multipart/form-data";
10744
+ return segment === "content" && path103?.[index + 1] === "multipart/form-data";
10745
10745
  });
10746
10746
  if (isMultipart) {
10747
10747
  const entries = Object.entries(schema3.properties);
@@ -10755,8 +10755,8 @@ var upgradeSchema = (schema2) => {
10755
10755
  }
10756
10756
  return schema3;
10757
10757
  });
10758
- schema2 = traverse(schema2, (schema3, path101) => {
10759
- if (path101?.includes("content") && path101.includes("application/octet-stream")) {
10758
+ schema2 = traverse(schema2, (schema3, path103) => {
10759
+ if (path103?.includes("content") && path103.includes("application/octet-stream")) {
10760
10760
  return {};
10761
10761
  }
10762
10762
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -10782,11 +10782,11 @@ var upgradeSchema = (schema2) => {
10782
10782
  }
10783
10783
  return sub;
10784
10784
  });
10785
- schema2 = traverse(schema2, (schema3, path101) => {
10785
+ schema2 = traverse(schema2, (schema3, path103) => {
10786
10786
  if (schema3.type === "string" && schema3.format === "byte") {
10787
- const parentPath = path101?.slice(0, -1);
10787
+ const parentPath = path103?.slice(0, -1);
10788
10788
  const contentMediaType = parentPath?.find(
10789
- (_, index) => path101?.[index - 1] === "content"
10789
+ (_, index) => path103?.[index - 1] === "content"
10790
10790
  );
10791
10791
  return {
10792
10792
  type: "string",
@@ -10798,7 +10798,7 @@ var upgradeSchema = (schema2) => {
10798
10798
  });
10799
10799
  return schema2;
10800
10800
  };
10801
- function isSchemaPath(path101) {
10801
+ function isSchemaPath(path103) {
10802
10802
  const schemaLocations = [
10803
10803
  ["components", "schemas"],
10804
10804
  "properties",
@@ -10811,10 +10811,10 @@ function isSchemaPath(path101) {
10811
10811
  ];
10812
10812
  return schemaLocations.some((location) => {
10813
10813
  if (Array.isArray(location)) {
10814
- return location.every((segment, index) => path101[index] === segment);
10814
+ return location.every((segment, index) => path103[index] === segment);
10815
10815
  }
10816
- return path101.includes(location);
10817
- }) || path101.includes("schema") || path101.some((segment) => segment.endsWith("Schema"));
10816
+ return path103.includes(location);
10817
+ }) || path103.includes("schema") || path103.some((segment) => segment.endsWith("Schema"));
10818
10818
  }
10819
10819
 
10820
10820
  // src/lib/oas/parser/index.ts
@@ -10896,13 +10896,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
10896
10896
  "anyOf",
10897
10897
  "oneOf"
10898
10898
  ]);
10899
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path101 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
10899
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path103 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
10900
10900
  if (obj === null || typeof obj !== "object") return obj;
10901
10901
  const refPath = obj.__$ref;
10902
10902
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
10903
10903
  if (isCircular) {
10904
10904
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
10905
- const circularProp = path101.find((p) => !OPENAPI_PROPS.has(p)) || path101[0];
10905
+ const circularProp = path103.find((p) => !OPENAPI_PROPS.has(p)) || path103[0];
10906
10906
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
10907
10907
  }
10908
10908
  if (refs.has(obj)) return refs.get(obj);
@@ -10912,7 +10912,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
10912
10912
  value,
10913
10913
  currentPath,
10914
10914
  refs,
10915
- [...path101, key],
10915
+ [...path103, key],
10916
10916
  currentRefPaths
10917
10917
  );
10918
10918
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -10947,7 +10947,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
10947
10947
  var getAllTags = (schema2) => {
10948
10948
  const rootTags = schema2.tags ?? [];
10949
10949
  const operations = Object.values(schema2.paths ?? {}).flatMap(
10950
- (path101) => HttpMethods.map((k) => path101?.[k]).filter((op) => op != null)
10950
+ (path103) => HttpMethods.map((k) => path103?.[k]).filter((op) => op != null)
10951
10951
  );
10952
10952
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
10953
10953
  const hasUntaggedOperations = operations.some(
@@ -11002,7 +11002,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
11002
11002
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
11003
11003
  var getAllOperations = (paths) => {
11004
11004
  const operations = Object.entries(paths ?? {}).flatMap(
11005
- ([path101, value]) => HttpMethods.flatMap((method) => {
11005
+ ([path103, value]) => HttpMethods.flatMap((method) => {
11006
11006
  if (!value?.[method]) return [];
11007
11007
  const operation = value[method];
11008
11008
  const pathParameters = value.parameters ?? [];
@@ -11022,7 +11022,7 @@ var getAllOperations = (paths) => {
11022
11022
  return {
11023
11023
  ...operation,
11024
11024
  method,
11025
- path: path101,
11025
+ path: path103,
11026
11026
  parameters,
11027
11027
  servers,
11028
11028
  tags: operation.tags ?? []
@@ -11380,8 +11380,8 @@ var Schema = builder.objectRef("Schema").implement({
11380
11380
  }),
11381
11381
  paths: t.field({
11382
11382
  type: [PathItem],
11383
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path101, value]) => ({
11384
- path: path101,
11383
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path103, value]) => ({
11384
+ path: path103,
11385
11385
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
11386
11386
  methods: Object.keys(value)
11387
11387
  }))
@@ -11546,7 +11546,7 @@ init_joinUrl();
11546
11546
 
11547
11547
  // src/vite/api/schema-codegen.ts
11548
11548
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
11549
- var getSegmentsFromPath = (path101) => path101.split("/").slice(1).map(unescapeJsonPointer);
11549
+ var getSegmentsFromPath = (path103) => path103.split("/").slice(1).map(unescapeJsonPointer);
11550
11550
  var createLocalRefMap = (obj) => {
11551
11551
  const refMap = /* @__PURE__ */ new Map();
11552
11552
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -11577,16 +11577,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
11577
11577
  /"__refMap\+Siblings:(.*?)"/g,
11578
11578
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
11579
11579
  );
11580
- var lookup = (schema2, path101, filePath) => {
11581
- const parts = getSegmentsFromPath(path101);
11580
+ var lookup = (schema2, path103, filePath) => {
11581
+ const parts = getSegmentsFromPath(path103);
11582
11582
  let val = schema2;
11583
11583
  for (const part of parts) {
11584
11584
  while (val.$ref?.startsWith("#/")) {
11585
- val = val.$ref === path101 ? val : lookup(schema2, val.$ref, filePath);
11585
+ val = val.$ref === path103 ? val : lookup(schema2, val.$ref, filePath);
11586
11586
  }
11587
11587
  if (val[part] === void 0) {
11588
11588
  throw new Error(
11589
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path101}`
11589
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path103}`
11590
11590
  );
11591
11591
  }
11592
11592
  val = val[part];
@@ -11831,8 +11831,8 @@ var SchemaManager = class {
11831
11831
  }
11832
11832
  }
11833
11833
  };
11834
- getLatestSchema = (path101) => this.processedSchemas[path101]?.at(0);
11835
- getSchemasForPath = (path101) => this.processedSchemas[path101];
11834
+ getLatestSchema = (path103) => this.processedSchemas[path103]?.at(0);
11835
+ getSchemasForPath = (path103) => this.processedSchemas[path103];
11836
11836
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
11837
11837
  getUrlToFilePathMap = () => {
11838
11838
  const map = /* @__PURE__ */ new Map();
@@ -13855,14 +13855,38 @@ function vitePlugin() {
13855
13855
  ];
13856
13856
  }
13857
13857
 
13858
+ // src/vite/watch-ignore.ts
13859
+ import { lstatSync, realpathSync } from "node:fs";
13860
+ import path40 from "node:path";
13861
+ var STATE_INSIDE_CONTENT = /[\\/]content[\\/](?:\.apitogo|apitogo[\\/]\.state)(?:[\\/]|$)/;
13862
+ var within = (base, file) => file === base || file.startsWith(base + path40.sep);
13863
+ var unique = (paths) => [...new Set(paths)];
13864
+ function stateIgnore(root) {
13865
+ let workspace = false;
13866
+ try {
13867
+ workspace = path40.basename(root) === "generated" && lstatSync(path40.join(root, "content")).isSymbolicLink();
13868
+ } catch {
13869
+ workspace = false;
13870
+ }
13871
+ if (!workspace) return void 0;
13872
+ const state = path40.dirname(root);
13873
+ const states = unique([state, realpathSync(state)]);
13874
+ const roots = unique([root, realpathSync(root)]);
13875
+ return (file) => {
13876
+ if (!states.some((base) => within(base, file))) return false;
13877
+ if (!roots.some((base) => within(base, file))) return true;
13878
+ return STATE_INSIDE_CONTENT.test(file);
13879
+ };
13880
+ }
13881
+
13858
13882
  // src/vite/config.ts
13859
13883
  var resolveMergedPublicDir = (rootDir, merged) => {
13860
13884
  if (merged.publicDir === false) return void 0;
13861
13885
  const rel2 = typeof merged.publicDir === "string" ? merged.publicDir : "public";
13862
- return path40.resolve(rootDir, rel2);
13886
+ return path41.resolve(rootDir, rel2);
13863
13887
  };
13864
- var getAppClientEntryPath = () => path40.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
13865
- var getAppServerEntryPath = () => path40.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
13888
+ var getAppClientEntryPath = () => path41.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
13889
+ var getAppServerEntryPath = () => path41.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
13866
13890
  var hasLoggedCdnInfo = false;
13867
13891
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
13868
13892
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -13890,9 +13914,10 @@ async function getViteConfig(dir, configEnv) {
13890
13914
  value
13891
13915
  ])
13892
13916
  );
13917
+ const ignoreState = stateIgnore(dir);
13893
13918
  if (ZuploEnv.isZuplo) {
13894
13919
  dotenv.config({
13895
- path: path40.resolve(config2.__meta.rootDir, "../.env.zuplo"),
13920
+ path: path41.resolve(config2.__meta.rootDir, "../.env.zuplo"),
13896
13921
  quiet: true
13897
13922
  });
13898
13923
  }
@@ -13938,7 +13963,7 @@ async function getViteConfig(dir, configEnv) {
13938
13963
  middlewareMode: true,
13939
13964
  open: true,
13940
13965
  fs: {
13941
- allow: [dir, path40.dirname(dir)]
13966
+ allow: [dir, path41.dirname(dir)]
13942
13967
  },
13943
13968
  watch: {
13944
13969
  ignored: [
@@ -13946,7 +13971,8 @@ async function getViteConfig(dir, configEnv) {
13946
13971
  `${dir}/lib`,
13947
13972
  `${dir}/.git`,
13948
13973
  `${config2.__meta.moduleDir}/src/vite`,
13949
- `${config2.__meta.moduleDir}/src/cli`
13974
+ `${config2.__meta.moduleDir}/src/cli`,
13975
+ ...ignoreState ? [ignoreState] : []
13950
13976
  ]
13951
13977
  }
13952
13978
  },
@@ -13954,8 +13980,8 @@ async function getViteConfig(dir, configEnv) {
13954
13980
  ssr: configEnv.isSsrBuild,
13955
13981
  sourcemap: true,
13956
13982
  target: "es2022",
13957
- outDir: path40.resolve(
13958
- path40.join(
13983
+ outDir: path41.resolve(
13984
+ path41.join(
13959
13985
  dir,
13960
13986
  "dist",
13961
13987
  config2.basePath ?? "",
@@ -13974,7 +14000,7 @@ async function getViteConfig(dir, configEnv) {
13974
14000
  },
13975
14001
  experimental: {
13976
14002
  renderBuiltUrl(filename) {
13977
- if (cdnUrl?.base && [".js", ".css"].includes(path40.extname(filename))) {
14003
+ if (cdnUrl?.base && [".js", ".css"].includes(path41.extname(filename))) {
13978
14004
  return joinUrl(cdnUrl.base, filename);
13979
14005
  }
13980
14006
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -13987,7 +14013,7 @@ async function getViteConfig(dir, configEnv) {
13987
14013
  esbuildOptions: {
13988
14014
  target: "es2022"
13989
14015
  },
13990
- entries: [path40.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
14016
+ entries: [path41.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
13991
14017
  exclude: [
13992
14018
  "@lukoweb/apitogo",
13993
14019
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -14091,7 +14117,7 @@ init_package_json();
14091
14117
  init_joinUrl();
14092
14118
  import assert from "node:assert";
14093
14119
  import { cp, mkdir as mkdir9, writeFile as writeFile10 } from "node:fs/promises";
14094
- import path41 from "node:path";
14120
+ import path42 from "node:path";
14095
14121
  var pkgJson = getZudokuPackageJson();
14096
14122
  function generateOutput({
14097
14123
  config: config2,
@@ -14148,9 +14174,9 @@ async function writeOutput(dir, {
14148
14174
  rewrites
14149
14175
  }) {
14150
14176
  const output4 = generateOutput({ config: config2, redirects, rewrites });
14151
- const outputDir = process.env.VERCEL ? path41.join(dir, ".vercel/output") : path41.join(dir, "dist/.output");
14177
+ const outputDir = process.env.VERCEL ? path42.join(dir, ".vercel/output") : path42.join(dir, "dist/.output");
14152
14178
  await mkdir9(outputDir, { recursive: true });
14153
- const outputFile = path41.join(outputDir, "config.json");
14179
+ const outputFile = path42.join(outputDir, "config.json");
14154
14180
  await writeFile10(outputFile, JSON.stringify(output4, null, 2), "utf-8");
14155
14181
  if (process.env.VERCEL) {
14156
14182
  console.log("Wrote Vercel output to", outputDir);
@@ -14162,7 +14188,7 @@ init_logger();
14162
14188
  init_file_exists();
14163
14189
  import { readFile as readFile9, rm as rm6 } from "node:fs/promises";
14164
14190
  import os from "node:os";
14165
- import path44 from "node:path";
14191
+ import path45 from "node:path";
14166
14192
  import { pathToFileURL } from "node:url";
14167
14193
  import { createIndex } from "pagefind";
14168
14194
  import colors11 from "picocolors";
@@ -14204,7 +14230,7 @@ function throttle(fn) {
14204
14230
  init_joinUrl();
14205
14231
  import { createWriteStream, existsSync as existsSync4 } from "node:fs";
14206
14232
  import { mkdir as mkdir10 } from "node:fs/promises";
14207
- import path42 from "node:path";
14233
+ import path43 from "node:path";
14208
14234
  import colors9 from "picocolors";
14209
14235
  import { SitemapStream } from "sitemap";
14210
14236
  async function generateSitemap({
@@ -14218,11 +14244,11 @@ async function generateSitemap({
14218
14244
  return;
14219
14245
  }
14220
14246
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
14221
- const outputDir = path42.resolve(baseOutputDir, config2.outDir ?? "");
14247
+ const outputDir = path43.resolve(baseOutputDir, config2.outDir ?? "");
14222
14248
  if (!existsSync4(outputDir)) {
14223
14249
  await mkdir10(outputDir, { recursive: true });
14224
14250
  }
14225
- const sitemapOutputPath = path42.join(outputDir, "sitemap.xml");
14251
+ const sitemapOutputPath = path43.join(outputDir, "sitemap.xml");
14226
14252
  const writeStream = createWriteStream(sitemapOutputPath);
14227
14253
  sitemap.pipe(writeStream);
14228
14254
  let lastmod;
@@ -14252,14 +14278,14 @@ async function generateSitemap({
14252
14278
 
14253
14279
  // src/vite/prerender/utils.ts
14254
14280
  init_joinUrl();
14255
- var resolveRoutePath = (path101) => {
14256
- const segments = path101.split("/");
14281
+ var resolveRoutePath = (path103) => {
14282
+ const segments = path103.split("/");
14257
14283
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
14258
14284
  return void 0;
14259
14285
  }
14260
14286
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
14261
14287
  };
14262
- var isSkipped = (path101) => path101.includes("*") || /^\d+$/.test(path101);
14288
+ var isSkipped = (path103) => path103.includes("*") || /^\d+$/.test(path103);
14263
14289
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
14264
14290
  if (route.path && isSkipped(route.path)) return [];
14265
14291
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -14308,12 +14334,12 @@ var prerender = async ({
14308
14334
  serverConfigFilename,
14309
14335
  writeRedirects = true
14310
14336
  }) => {
14311
- const distDir = path44.join(dir, "dist", basePath);
14337
+ const distDir = path45.join(dir, "dist", basePath);
14312
14338
  const serverConfigPath = pathToFileURL(
14313
- path44.join(distDir, "server", serverConfigFilename)
14339
+ path45.join(distDir, "server", serverConfigFilename)
14314
14340
  ).href;
14315
14341
  const entryServerPath = pathToFileURL(
14316
- path44.join(distDir, "server/entry.server.js")
14342
+ path45.join(distDir, "server/entry.server.js")
14317
14343
  ).href;
14318
14344
  const rawConfig = await import(serverConfigPath).then(
14319
14345
  (m) => m.default
@@ -14398,7 +14424,7 @@ var prerender = async ({
14398
14424
  })
14399
14425
  );
14400
14426
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
14401
- outputPath: path44.join(distDir, "pagefind")
14427
+ outputPath: path45.join(distDir, "pagefind")
14402
14428
  });
14403
14429
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
14404
14430
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
@@ -14430,7 +14456,7 @@ var prerender = async ({
14430
14456
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
14431
14457
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
14432
14458
  const llmsConfig = docsConfig.llms ?? {};
14433
- const markdownInfoPath = path44.join(
14459
+ const markdownInfoPath = path45.join(
14434
14460
  dir,
14435
14461
  "node_modules/.apitogo/markdown-info.json"
14436
14462
  );
@@ -14521,7 +14547,7 @@ async function runBuild(options) {
14521
14547
  html,
14522
14548
  basePath: config2.basePath
14523
14549
  });
14524
- await rm7(path45.join(clientOutDir, "index.html"), { force: true });
14550
+ await rm7(path46.join(clientOutDir, "index.html"), { force: true });
14525
14551
  } else {
14526
14552
  await runPrerender({
14527
14553
  dir,
@@ -14545,7 +14571,7 @@ var runPrerender = async (options) => {
14545
14571
  serverConfigFilename,
14546
14572
  writeRedirects: process.env.VERCEL === void 0
14547
14573
  });
14548
- const indexHtml = path45.join(clientOutDir, "index.html");
14574
+ const indexHtml = path46.join(clientOutDir, "index.html");
14549
14575
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
14550
14576
  await writeFile12(indexHtml, html, "utf-8");
14551
14577
  }
@@ -14555,15 +14581,15 @@ var runPrerender = async (options) => {
14555
14581
  for (const statusPage of statusPages) {
14556
14582
  await rename5(
14557
14583
  statusPage,
14558
- path45.join(dir, DIST_DIR, path45.basename(statusPage))
14584
+ path46.join(dir, DIST_DIR, path46.basename(statusPage))
14559
14585
  );
14560
14586
  }
14561
14587
  await rm7(serverOutDir, { recursive: true, force: true });
14562
14588
  if (process.env.VERCEL) {
14563
- await mkdir11(path45.join(dir, ".vercel/output/static"), { recursive: true });
14589
+ await mkdir11(path46.join(dir, ".vercel/output/static"), { recursive: true });
14564
14590
  await rename5(
14565
- path45.join(dir, DIST_DIR),
14566
- path45.join(dir, ".vercel/output/static")
14591
+ path46.join(dir, DIST_DIR),
14592
+ path46.join(dir, ".vercel/output/static")
14567
14593
  );
14568
14594
  }
14569
14595
  await writeOutput(dir, {
@@ -14573,7 +14599,7 @@ var runPrerender = async (options) => {
14573
14599
  });
14574
14600
  if (ZuploEnv.isZuplo && issuer) {
14575
14601
  await writeFile12(
14576
- path45.join(dir, DIST_DIR, ".output/zuplo.json"),
14602
+ path46.join(dir, DIST_DIR, ".output/zuplo.json"),
14577
14603
  JSON.stringify({ issuer }, null, 2),
14578
14604
  "utf-8"
14579
14605
  );
@@ -14585,10 +14611,10 @@ var runPrerender = async (options) => {
14585
14611
  };
14586
14612
  var bundleSSREntry = async (options) => {
14587
14613
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
14588
- const tempEntryPath = path45.join(dir, "__ssr-entry.ts");
14614
+ const tempEntryPath = path46.join(dir, "__ssr-entry.ts");
14589
14615
  const packageRoot = getZudokuRootDir();
14590
14616
  const templateContent = await readFile10(
14591
- path45.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
14617
+ path46.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
14592
14618
  "utf-8"
14593
14619
  );
14594
14620
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
@@ -14603,9 +14629,9 @@ var bundleSSREntry = async (options) => {
14603
14629
  platform: adapter === "node" ? "node" : "neutral",
14604
14630
  target: "es2022",
14605
14631
  format: "esm",
14606
- outfile: path45.join(serverOutDir, "entry.js"),
14632
+ outfile: path46.join(serverOutDir, "entry.js"),
14607
14633
  external: ["./entry.server.js", `./${serverConfigFilename}`],
14608
- nodePaths: [path45.join(packageRoot, "node_modules")],
14634
+ nodePaths: [path46.join(packageRoot, "node_modules")],
14609
14635
  banner: { js: "// Bundled SSR entry" }
14610
14636
  });
14611
14637
  } finally {
@@ -14615,8 +14641,60 @@ var bundleSSREntry = async (options) => {
14615
14641
 
14616
14642
  // src/cli/portal/v2.ts
14617
14643
  init_package_json();
14644
+
14645
+ // src/cli/init/v2-packages.ts
14646
+ import { existsSync as existsSync5 } from "node:fs";
14647
+ import { readFile as readFile11, writeFile as writeFile13 } from "node:fs/promises";
14648
+ import path47 from "node:path";
14649
+ var CORE_PACKAGES = [
14650
+ "@lukoweb/apitogo",
14651
+ "react",
14652
+ "react-dom"
14653
+ ];
14654
+ var portalPackageSpecs = (version) => [
14655
+ `@lukoweb/apitogo@${version}`,
14656
+ "react@19",
14657
+ "react-dom@19"
14658
+ ];
14659
+ var installCommand = (version) => `npm install --save-dev ${portalPackageSpecs(version).join(" ")}`;
14660
+ function packageNameFrom(name) {
14661
+ const slug = name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
14662
+ return slug || "portal";
14663
+ }
14664
+ async function ensurePackageJson(dir, name) {
14665
+ const file = path47.join(dir, "package.json");
14666
+ if (existsSync5(file)) return false;
14667
+ await writeFile13(
14668
+ file,
14669
+ `${JSON.stringify(
14670
+ {
14671
+ name: packageNameFrom(name),
14672
+ version: "0.0.1",
14673
+ private: true,
14674
+ type: "module"
14675
+ },
14676
+ null,
14677
+ 2
14678
+ )}
14679
+ `
14680
+ );
14681
+ return true;
14682
+ }
14683
+ function isPackageInstalled(startDir, name) {
14684
+ let dir = path47.resolve(startDir);
14685
+ for (; ; ) {
14686
+ if (existsSync5(path47.join(dir, "node_modules", name, "package.json")))
14687
+ return true;
14688
+ const parent = path47.dirname(dir);
14689
+ if (parent === dir) return false;
14690
+ dir = parent;
14691
+ }
14692
+ }
14693
+ var missingCorePackages = (dir) => CORE_PACKAGES.filter((name) => !isPackageInstalled(dir, name));
14694
+
14695
+ // src/cli/portal/v2.ts
14618
14696
  function assertPackagesInstalled(resolved, prepared) {
14619
- const require2 = createRequire2(path46.join(resolved.configDir, "package.json"));
14697
+ const require2 = createRequire2(path48.join(resolved.configDir, "package.json"));
14620
14698
  const missing = requiredPackages(prepared.plan).filter((name) => {
14621
14699
  try {
14622
14700
  require2.resolve(name);
@@ -14625,16 +14703,22 @@ function assertPackagesInstalled(resolved, prepared) {
14625
14703
  return true;
14626
14704
  }
14627
14705
  });
14628
- if (missing.length === 0) return;
14629
- throw new ConfigError(
14630
- resolved.configPath,
14631
- missing.map((name) => ({
14706
+ const missingCore = missingCorePackages(resolved.configDir);
14707
+ if (missing.length === 0 && missingCore.length === 0) return;
14708
+ throw new ConfigError(resolved.configPath, [
14709
+ ...missingCore.map((name) => ({
14710
+ code: "PORTAL_PACKAGE_MISSING",
14711
+ path: "",
14712
+ message: `the portal is built with ${name}, which is not installed in this project.`,
14713
+ hint: `Run \`${installCommand(getZudokuPackageJson().version)}\` in ${resolved.configDir}.`
14714
+ })),
14715
+ ...missing.map((name) => ({
14632
14716
  code: "PORTAL_PACKAGE_MISSING",
14633
14717
  path: "",
14634
14718
  message: `the portal registers a feature that needs ${name}, which is not installed.`,
14635
14719
  hint: `Run \`npm install ${name}\` in ${resolved.configDir}.`
14636
14720
  }))
14637
- );
14721
+ ]);
14638
14722
  }
14639
14723
  async function preparePortalWorkspace(dir, mode) {
14640
14724
  const { resolved } = loadConfigV2(dir);
@@ -14663,7 +14747,7 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
14663
14747
  return {
14664
14748
  name: "build",
14665
14749
  hash: () => hash2,
14666
- stillValid: () => access4(path46.join(buildDir, "index.html")).then(
14750
+ stillValid: () => access4(path48.join(buildDir, "index.html")).then(
14667
14751
  () => true,
14668
14752
  () => false
14669
14753
  ),
@@ -14676,11 +14760,11 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
14676
14760
  process.chdir(originalCwd);
14677
14761
  }
14678
14762
  await rm8(buildDir, { recursive: true, force: true });
14679
- await mkdir12(path46.dirname(buildDir), { recursive: true });
14680
- await rename6(path46.join(root, "dist"), buildDir);
14763
+ await mkdir12(path48.dirname(buildDir), { recursive: true });
14764
+ await rename6(path48.join(root, "dist"), buildDir);
14681
14765
  if (prepared.publishedManifest) {
14682
- await writeFile13(
14683
- path46.join(buildDir, MANIFEST_FILE),
14766
+ await writeFile14(
14767
+ path48.join(buildDir, MANIFEST_FILE),
14684
14768
  `${JSON.stringify(prepared.publishedManifest, null, 2)}
14685
14769
  `
14686
14770
  );
@@ -14709,17 +14793,17 @@ async function buildV2(options) {
14709
14793
  }
14710
14794
 
14711
14795
  // src/cli/check/gateway-online.ts
14712
- import { readFile as readFile12 } from "node:fs/promises";
14796
+ import { readFile as readFile13 } from "node:fs/promises";
14713
14797
  var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
14714
- var issue2 = (code, path101, message, hint) => ({ code, path: path101, message, hint });
14798
+ var issue2 = (code, path103, message, hint) => ({ code, path: path103, message, hint });
14715
14799
  function capabilityIssues(gateway, answer) {
14716
14800
  const can = answer.capabilities;
14717
14801
  const plan2 = `your ${answer.tier} plan`;
14718
14802
  const found = [];
14719
- const unsupported = (path101, what, hint) => found.push(
14803
+ const unsupported = (path103, what, hint) => found.push(
14720
14804
  issue2(
14721
14805
  "GATEWAY_CAPABILITY_UNSUPPORTED",
14722
- path101,
14806
+ path103,
14723
14807
  `${what} is not available on ${plan2}.`,
14724
14808
  hint
14725
14809
  )
@@ -14765,7 +14849,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
14765
14849
  const specFile = gateway.specs[0];
14766
14850
  if (specFile) {
14767
14851
  try {
14768
- const text = await readFile12(specFile, "utf8");
14852
+ const text = await readFile13(specFile, "utf8");
14769
14853
  if (text.length <= SPEC_SEND_LIMIT) spec = text;
14770
14854
  } catch {
14771
14855
  }
@@ -14795,7 +14879,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
14795
14879
  async function isConfigV2(dir) {
14796
14880
  try {
14797
14881
  return /"version"\s*:\s*2\b/.test(
14798
- await readFile13(path47.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
14882
+ await readFile14(path49.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
14799
14883
  );
14800
14884
  } catch {
14801
14885
  return false;
@@ -14889,7 +14973,7 @@ async function validatePortalBuild(dir) {
14889
14973
  }
14890
14974
  }
14891
14975
  async function runCheckV2(dir, args = {}, deps = {}) {
14892
- const configPath = path47.join(dir, APITOGO_CONFIG_FILENAME);
14976
+ const configPath = path49.join(dir, APITOGO_CONFIG_FILENAME);
14893
14977
  let report;
14894
14978
  let layout;
14895
14979
  try {
@@ -14978,8 +15062,155 @@ async function checkV2(dir, args, deps = platformDependencies(args)) {
14978
15062
  init_package_json();
14979
15063
 
14980
15064
  // src/cli/init/v2-handler.ts
14981
- import path48 from "node:path";
15065
+ import path51 from "node:path";
14982
15066
  import { createInterface } from "node:readline/promises";
15067
+ init_package_json();
15068
+
15069
+ // src/cli/platform/helpers/npm-build.ts
15070
+ import { spawn } from "node:child_process";
15071
+ import { access as access5, readFile as readFile15 } from "node:fs/promises";
15072
+ import path50 from "node:path";
15073
+ var BUILD_LOG_TAIL_BYTES = 8192;
15074
+ var MIN_NODE_MAJOR = 20;
15075
+ var NpmBuildError = class extends Error {
15076
+ buildLog;
15077
+ exitCode;
15078
+ constructor(message, buildLog, exitCode) {
15079
+ super(message);
15080
+ this.name = "NpmBuildError";
15081
+ this.buildLog = buildLog;
15082
+ this.exitCode = exitCode;
15083
+ }
15084
+ };
15085
+ function parseNodeMajor(version) {
15086
+ const match = /^v?(\d+)/.exec(version.trim());
15087
+ return match ? Number.parseInt(match[1], 10) : Number.NaN;
15088
+ }
15089
+ function assertNodeVersion(required) {
15090
+ const major = parseNodeMajor(process.version);
15091
+ if (Number.isNaN(major) || major < MIN_NODE_MAJOR) {
15092
+ throw new Error(
15093
+ `Node.js ${MIN_NODE_MAJOR}+ is required (current: ${process.version}).`
15094
+ );
15095
+ }
15096
+ if (required) {
15097
+ const requiredMajor = parseNodeMajor(required);
15098
+ if (!Number.isNaN(requiredMajor) && major < requiredMajor) {
15099
+ throw new Error(
15100
+ `Node.js ${requiredMajor}+ is required by nodeVersion option (current: ${process.version}).`
15101
+ );
15102
+ }
15103
+ }
15104
+ }
15105
+ function truncateBuildLog(log, success) {
15106
+ if (success && log.length > BUILD_LOG_TAIL_BYTES) {
15107
+ return log.slice(-BUILD_LOG_TAIL_BYTES);
15108
+ }
15109
+ return log;
15110
+ }
15111
+ async function pathExists(filePath) {
15112
+ try {
15113
+ await access5(filePath);
15114
+ return true;
15115
+ } catch {
15116
+ return false;
15117
+ }
15118
+ }
15119
+ function runCommand(command2, args, cwd, env) {
15120
+ return new Promise((resolve, reject) => {
15121
+ const child = spawn(command2, args, {
15122
+ cwd,
15123
+ env: env ? { ...process.env, ...env } : process.env,
15124
+ shell: process.platform === "win32"
15125
+ });
15126
+ let output4 = "";
15127
+ child.stdout.on("data", (chunk) => {
15128
+ output4 += chunk.toString();
15129
+ });
15130
+ child.stderr.on("data", (chunk) => {
15131
+ output4 += chunk.toString();
15132
+ });
15133
+ child.on("error", reject);
15134
+ child.on("close", (exitCode) => resolve({ exitCode, output: output4 }));
15135
+ });
15136
+ }
15137
+ async function runNpmCommand(args, cwd) {
15138
+ assertNodeVersion();
15139
+ const startedAt = Date.now();
15140
+ const result = await runCommand("npm", args, path50.resolve(cwd));
15141
+ if (result.exitCode !== 0) {
15142
+ throw new NpmBuildError(
15143
+ `npm ${args.join(" ")} exited ${result.exitCode ?? "unknown"}`,
15144
+ result.output,
15145
+ result.exitCode
15146
+ );
15147
+ }
15148
+ return {
15149
+ durationMs: Date.now() - startedAt,
15150
+ log: truncateBuildLog(result.output, true)
15151
+ };
15152
+ }
15153
+ async function runNpmInstall(sourceDirectory, options) {
15154
+ assertNodeVersion(options?.nodeVersion);
15155
+ const cwd = path50.resolve(sourceDirectory);
15156
+ const packageJsonPath = path50.join(cwd, "package.json");
15157
+ if (!await pathExists(packageJsonPath)) {
15158
+ throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
15159
+ }
15160
+ const startedAt = Date.now();
15161
+ const lockPath = path50.join(cwd, "package-lock.json");
15162
+ const installArgs = await pathExists(lockPath) ? ["ci"] : ["install"];
15163
+ const install = await runCommand("npm", installArgs, cwd);
15164
+ const installLog = install.output;
15165
+ if (install.exitCode !== 0) {
15166
+ throw new NpmBuildError(
15167
+ `npm ${installArgs.join(" ")} exited ${install.exitCode ?? "unknown"}`,
15168
+ installLog,
15169
+ install.exitCode
15170
+ );
15171
+ }
15172
+ return {
15173
+ durationMs: Date.now() - startedAt,
15174
+ installLog: truncateBuildLog(installLog, true)
15175
+ };
15176
+ }
15177
+ async function runNpmBuild(sourceDirectory, options) {
15178
+ assertNodeVersion(options?.nodeVersion);
15179
+ const cwd = path50.resolve(sourceDirectory);
15180
+ const packageJsonPath = path50.join(cwd, "package.json");
15181
+ if (!await pathExists(packageJsonPath)) {
15182
+ throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
15183
+ }
15184
+ const startedAt = Date.now();
15185
+ let buildLog = "";
15186
+ const install = await runNpmInstall(sourceDirectory, options);
15187
+ buildLog += install.installLog;
15188
+ const build2 = await runCommand("npm", ["run", "build"], cwd, options?.env);
15189
+ buildLog += build2.output;
15190
+ if (build2.exitCode !== 0) {
15191
+ throw new NpmBuildError(
15192
+ `npm run build exited ${build2.exitCode ?? "unknown"}`,
15193
+ buildLog,
15194
+ build2.exitCode
15195
+ );
15196
+ }
15197
+ const distPath = path50.join(cwd, "dist");
15198
+ const indexPath = path50.join(distPath, "index.html");
15199
+ if (!await pathExists(indexPath)) {
15200
+ throw new NpmBuildError(
15201
+ `Build completed but dist/index.html was not found at ${indexPath}`,
15202
+ buildLog,
15203
+ build2.exitCode
15204
+ );
15205
+ }
15206
+ return {
15207
+ distPath,
15208
+ durationMs: Date.now() - startedAt,
15209
+ buildLog: truncateBuildLog(buildLog, true)
15210
+ };
15211
+ }
15212
+
15213
+ // src/cli/init/v2-handler.ts
14983
15214
  function parseOnlyFlag(value) {
14984
15215
  const services = (value ?? "portal").split(",").map((name) => name.trim()).filter(Boolean);
14985
15216
  const unsupported = services.filter((name) => name !== "portal");
@@ -15031,17 +15262,34 @@ function describePlan(plan2) {
15031
15262
  layoutReason: plan2.layoutReason,
15032
15263
  docsIncluded: plan2.docsIncluded,
15033
15264
  willCreate: plan2.entries.map(
15034
- (entry) => path48.relative(plan2.dir, entry.path)
15265
+ (entry) => path51.relative(plan2.dir, entry.path)
15035
15266
  ),
15036
- willKeep: plan2.keep.map((target) => path48.relative(plan2.dir, target)),
15267
+ willKeep: plan2.keep.map((target) => path51.relative(plan2.dir, target)),
15037
15268
  replacesConfig: plan2.replacesConfig
15038
15269
  };
15039
15270
  }
15271
+ async function setUpPackages(options) {
15272
+ const version = getZudokuPackageJson().version;
15273
+ const command2 = installCommand(version);
15274
+ if (options.layout !== "standalone" || !options.install) {
15275
+ return { packageJsonCreated: false, installed: false, command: command2 };
15276
+ }
15277
+ const packageJsonCreated = await ensurePackageJson(options.dir, options.name);
15278
+ await withSpinner(
15279
+ "Installing @lukoweb/apitogo, react and react-dom\u2026",
15280
+ () => runNpmCommand(
15281
+ ["install", "--save-dev", ...portalPackageSpecs(version)],
15282
+ options.dir
15283
+ ),
15284
+ { silent: options.quiet }
15285
+ );
15286
+ return { packageJsonCreated, installed: true, command: command2 };
15287
+ }
15040
15288
  async function initV2(argv) {
15041
15289
  const json = argv.json === true;
15042
15290
  try {
15043
15291
  parseOnlyFlag(argv.only);
15044
- const dir = path48.resolve(process.cwd(), argv.dir ?? ".");
15292
+ const dir = path51.resolve(process.cwd(), argv.dir ?? ".");
15045
15293
  const options = {
15046
15294
  dir,
15047
15295
  layout: argv.layout,
@@ -15091,6 +15339,13 @@ async function initV2(argv) {
15091
15339
  }
15092
15340
  }
15093
15341
  const result = await applyInitPlan(plan2);
15342
+ const packages = await setUpPackages({
15343
+ dir,
15344
+ layout: plan2.layout,
15345
+ name: argv.name ?? path51.basename(dir),
15346
+ install: argv.install === true,
15347
+ quiet: json
15348
+ });
15094
15349
  if (json) {
15095
15350
  console.log(
15096
15351
  JSON.stringify(
@@ -15098,8 +15353,9 @@ async function initV2(argv) {
15098
15353
  status: "created",
15099
15354
  dir,
15100
15355
  ...describePlan(plan2),
15101
- created: result.created.map((p) => path48.relative(dir, p)),
15102
- kept: result.kept.map((p) => path48.relative(dir, p))
15356
+ created: result.created.map((p) => path51.relative(dir, p)),
15357
+ kept: result.kept.map((p) => path51.relative(dir, p)),
15358
+ packages
15103
15359
  },
15104
15360
  null,
15105
15361
  2
@@ -15108,8 +15364,16 @@ async function initV2(argv) {
15108
15364
  return;
15109
15365
  }
15110
15366
  printResultToConsole(
15111
- `Created ${path48.basename(plan2.configPath)} (config version 2, ${plan2.layout} layout) in ${dir}.`
15367
+ `Created ${path51.basename(plan2.configPath)} (config version 2, ${plan2.layout} layout) in ${dir}.`
15112
15368
  );
15369
+ if (packages.installed)
15370
+ printResultToConsole(
15371
+ "Installed @lukoweb/apitogo, react and react-dom (package.json was created for them)."
15372
+ );
15373
+ else
15374
+ printHintToConsole(
15375
+ `The portal needs @lukoweb/apitogo, react and react-dom in this project. Run: ${packages.command}`
15376
+ );
15113
15377
  printHintToConsole(
15114
15378
  "Config version 2 is a preview: add, remove, check, run, build, plan, status, deploy and secrets read it."
15115
15379
  );
@@ -15134,9 +15398,9 @@ async function initV2(argv) {
15134
15398
  }
15135
15399
 
15136
15400
  // src/cli/services/packages.ts
15137
- import { spawn } from "node:child_process";
15138
- import { existsSync as existsSync5 } from "node:fs";
15139
- import path49 from "node:path";
15401
+ import { spawn as spawn2 } from "node:child_process";
15402
+ import { existsSync as existsSync6 } from "node:fs";
15403
+ import path52 from "node:path";
15140
15404
  var USER_PANEL_PACKAGE = "@lukoweb/apitogo-module-user-panel";
15141
15405
  var BILLING_PLUGIN_PACKAGE = "@lukoweb/apitogo-plugin-dev-portal-billing";
15142
15406
  function packagesForConfig(config2) {
@@ -15151,26 +15415,26 @@ function packagesForConfig(config2) {
15151
15415
  ];
15152
15416
  }
15153
15417
  function isInstalled(dir, name) {
15154
- for (let current = path49.resolve(dir); ; current = path49.dirname(current)) {
15155
- if (existsSync5(path49.join(current, "node_modules", name, "package.json")))
15418
+ for (let current = path52.resolve(dir); ; current = path52.dirname(current)) {
15419
+ if (existsSync6(path52.join(current, "node_modules", name, "package.json")))
15156
15420
  return true;
15157
- if (path49.dirname(current) === current) return false;
15421
+ if (path52.dirname(current) === current) return false;
15158
15422
  }
15159
15423
  }
15160
15424
  function missingPackages(dir, names) {
15161
15425
  return names.filter((name) => !isInstalled(dir, name));
15162
15426
  }
15163
15427
  function detectPackageManager(dir) {
15164
- if (existsSync5(path49.join(dir, "pnpm-lock.yaml"))) return "pnpm";
15165
- if (existsSync5(path49.join(dir, "yarn.lock"))) return "yarn";
15428
+ if (existsSync6(path52.join(dir, "pnpm-lock.yaml"))) return "pnpm";
15429
+ if (existsSync6(path52.join(dir, "yarn.lock"))) return "yarn";
15166
15430
  return "npm";
15167
15431
  }
15168
- function installCommand(manager, names, version) {
15432
+ function installCommand2(manager, names, version) {
15169
15433
  const specs = names.map((name) => `${name}@${version}`);
15170
15434
  return manager === "npm" ? { command: "npm", args: ["install", ...specs] } : { command: manager, args: ["add", ...specs] };
15171
15435
  }
15172
15436
  var runInstaller = (dir, { command: command2, args }) => new Promise((resolve, reject) => {
15173
- const child = spawn(command2, args, {
15437
+ const child = spawn2(command2, args, {
15174
15438
  cwd: dir,
15175
15439
  stdio: "inherit",
15176
15440
  shell: process.platform === "win32"
@@ -15188,7 +15452,7 @@ var runInstaller = (dir, { command: command2, args }) => new Promise((resolve, r
15188
15452
  async function installMissingPackages(dir, config2, version, options) {
15189
15453
  const missing = missingPackages(dir, packagesForConfig(config2));
15190
15454
  if (missing.length === 0) return void 0;
15191
- const command2 = installCommand(detectPackageManager(dir), missing, version);
15455
+ const command2 = installCommand2(detectPackageManager(dir), missing, version);
15192
15456
  const shown = `${command2.command} ${command2.args.join(" ")}`;
15193
15457
  if (!options.install)
15194
15458
  return {
@@ -15197,7 +15461,7 @@ async function installMissingPackages(dir, config2, version, options) {
15197
15461
  reason: "--no-install was given",
15198
15462
  command: shown
15199
15463
  };
15200
- if (!existsSync5(path49.join(dir, "package.json")))
15464
+ if (!existsSync6(path52.join(dir, "package.json")))
15201
15465
  return {
15202
15466
  status: "skipped",
15203
15467
  packages: missing,
@@ -15216,7 +15480,7 @@ var list = (value) => {
15216
15480
  return items.length > 0 ? items : void 0;
15217
15481
  };
15218
15482
  function addOptionsFromArguments(service, argv) {
15219
- const dir = path50.resolve(process.cwd(), argv.dir ?? ".");
15483
+ const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
15220
15484
  const issuers = list(argv.issuer);
15221
15485
  return {
15222
15486
  dir,
@@ -15275,8 +15539,8 @@ function describe(edit, dir) {
15275
15539
  return {
15276
15540
  service: edit.service,
15277
15541
  action: edit.action,
15278
- willCreate: edit.files.map((file) => path50.relative(dir, file.path)),
15279
- keep: edit.keep.map((file) => path50.relative(dir, file)),
15542
+ willCreate: edit.files.map((file) => path53.relative(dir, file.path)),
15543
+ keep: edit.keep.map((file) => path53.relative(dir, file)),
15280
15544
  notes: edit.notes
15281
15545
  };
15282
15546
  }
@@ -15289,11 +15553,11 @@ async function run(action, argv, plan2, deps = {}) {
15289
15553
  `Choose one of ${SERVICES.join(", ")}.`
15290
15554
  );
15291
15555
  }
15292
- const dir = path50.resolve(process.cwd(), argv.dir ?? ".");
15556
+ const dir = path53.resolve(process.cwd(), argv.dir ?? ".");
15293
15557
  if (!await isConfigV2(dir)) {
15294
15558
  throw new ServiceEditError(
15295
15559
  `${action} works with a config version 2 project, and there is none in ${dir}.`,
15296
- "Create one with `apitogo init --v2`."
15560
+ "Create one with `apitogo init`."
15297
15561
  );
15298
15562
  }
15299
15563
  const edit = await plan2(argv.service);
@@ -15336,7 +15600,7 @@ async function run(action, argv, plan2, deps = {}) {
15336
15600
  {
15337
15601
  status: action === "add" ? "added" : "removed",
15338
15602
  ...describe(edit, dir),
15339
- created: created.map((file) => path50.relative(dir, file)),
15603
+ created: created.map((file) => path53.relative(dir, file)),
15340
15604
  ...install ? { packages: install } : {}
15341
15605
  },
15342
15606
  null,
@@ -15346,7 +15610,7 @@ async function run(action, argv, plan2, deps = {}) {
15346
15610
  return;
15347
15611
  }
15348
15612
  printResultToConsole(
15349
- `${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path50.basename(edit.configPath)}.`
15613
+ `${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path53.basename(edit.configPath)}.`
15350
15614
  );
15351
15615
  } catch (error) {
15352
15616
  const message = error instanceof Error ? error.message : String(error);
@@ -15404,7 +15668,7 @@ var removeService = (argv) => run(
15404
15668
  "remove",
15405
15669
  argv,
15406
15670
  (service) => planRemoveService(service, {
15407
- dir: path50.resolve(process.cwd(), argv.dir ?? ".")
15671
+ dir: path53.resolve(process.cwd(), argv.dir ?? ".")
15408
15672
  })
15409
15673
  );
15410
15674
 
@@ -15552,16 +15816,16 @@ var add_default = {
15552
15816
  };
15553
15817
 
15554
15818
  // src/cli/build/handler.ts
15555
- import path52 from "node:path";
15819
+ import path55 from "node:path";
15556
15820
  init_logger();
15557
15821
  init_package_json();
15558
15822
 
15559
15823
  // src/cli/preview/handler.ts
15560
- import path51 from "node:path";
15824
+ import path54 from "node:path";
15561
15825
  import { preview as vitePreview } from "vite";
15562
15826
  var DEFAULT_PREVIEW_PORT = 4e3;
15563
15827
  async function preview(argv) {
15564
- const dir = path51.resolve(process.cwd(), argv.dir);
15828
+ const dir = path54.resolve(process.cwd(), argv.dir);
15565
15829
  const viteConfig = await getViteConfig(dir, {
15566
15830
  command: "serve",
15567
15831
  mode: "production",
@@ -15604,7 +15868,7 @@ async function build(argv) {
15604
15868
  printDiagnosticsToConsole("");
15605
15869
  printDiagnosticsToConsole("");
15606
15870
  }
15607
- const dir = path52.resolve(process.cwd(), argv.dir);
15871
+ const dir = path55.resolve(process.cwd(), argv.dir);
15608
15872
  try {
15609
15873
  if (await isConfigV2(dir)) {
15610
15874
  const result = await buildV2({ dir, jsonOnly });
@@ -15669,10 +15933,10 @@ var build_default = {
15669
15933
  };
15670
15934
 
15671
15935
  // src/cli/check/handler.ts
15672
- import path59 from "node:path";
15936
+ import path61 from "node:path";
15673
15937
 
15674
15938
  // src/cli/platform/tools/check-publish-readiness.ts
15675
- import path58 from "node:path";
15939
+ import path60 from "node:path";
15676
15940
 
15677
15941
  // src/cli/platform/helpers/dev-portal-backend.ts
15678
15942
  function deriveProvisioningState(backend) {
@@ -15755,12 +16019,12 @@ function formatDevPortalBackendResponse(projectId, backend) {
15755
16019
 
15756
16020
  // src/cli/platform/helpers/dev-portal-manifest.ts
15757
16021
  init_gateway_limits();
15758
- import { existsSync as existsSync6 } from "node:fs";
15759
- import { access as access5, mkdir as mkdir13, readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
15760
- import path54 from "node:path";
16022
+ import { existsSync as existsSync7 } from "node:fs";
16023
+ import { access as access6, mkdir as mkdir13, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
16024
+ import path57 from "node:path";
15761
16025
 
15762
16026
  // src/cli/make-config/json-config.ts
15763
- import path53 from "node:path";
16027
+ import path56 from "node:path";
15764
16028
 
15765
16029
  // src/cli/make-config/branding-assets.ts
15766
16030
  var LOGO_LIGHT = '<svg xmlns="http://www.w3.org/2000/svg" width="201.57" height="72.66" viewBox="-0.09 -46.99 201.57 72.66">\n <path d="M13.5 0.39Q8.03 0.39 4.76 -2.09Q1.48 -4.57 1.41 -9.61H8.03Q8.14 -7.48 9.6 -6.41Q11.05 -5.33 13.42 -5.33Q15.57 -5.33 16.8 -6.2Q18.03 -7.07 18.03 -8.46Q18.03 -9.71 16.87 -10.44Q15.7 -11.17 13.32 -11.72L10.23 -12.44Q6.46 -13.3 4.32 -15.25Q2.17 -17.21 2.17 -20.49Q2.17 -23.18 3.62 -25.21Q5.08 -27.23 7.64 -28.36Q10.2 -29.49 13.5 -29.49Q16.88 -29.49 19.36 -28.35Q21.84 -27.21 23.2 -25.17Q24.57 -23.12 24.61 -20.43H17.99Q17.85 -22.01 16.7 -22.89Q15.55 -23.77 13.48 -23.77Q11.41 -23.77 10.35 -22.97Q9.3 -22.17 9.3 -20.96Q9.3 -19.61 10.47 -18.88Q11.64 -18.14 13.59 -17.71L16.11 -17.13Q20.33 -16.19 22.67 -14.06Q25 -11.93 25 -8.44Q25 -4.3 21.95 -1.95Q18.91 0.39 13.5 0.39Z M32.97 0.39Q29.82 0.39 27.8 -1.21Q25.78 -2.81 25.78 -6.05Q25.78 -8.48 26.89 -9.9Q28 -11.33 29.85 -12.01Q31.7 -12.7 33.9 -12.89Q36.68 -13.12 37.88 -13.47Q39.08 -13.81 39.08 -14.82V-14.9Q39.08 -16.04 38.29 -16.65Q37.5 -17.27 36.11 -17.27Q34.68 -17.27 33.77 -16.66Q32.85 -16.05 32.58 -15.02L26.4 -15.82Q27.05 -18.61 29.56 -20.36Q32.07 -22.11 36.17 -22.11Q38.88 -22.11 41.08 -21.27Q43.28 -20.43 44.58 -18.8Q45.88 -17.17 45.88 -14.82V0H39.47V-3.07H39.29Q37.48 0.39 32.97 0.39ZM35.04 -4.12Q36.75 -4.12 37.95 -5.14Q39.14 -6.15 39.14 -7.77V-9.86Q38.55 -9.55 37.44 -9.34Q36.33 -9.12 35.37 -8.96Q32.22 -8.5 32.22 -6.37Q32.22 -5.27 33.01 -4.7Q33.81 -4.12 35.04 -4.12Z M48.59 0V-21.84H54.86L55.17 -17.5Q56.07 -19.96 57.78 -21.04Q59.49 -22.13 61.46 -22.13Q63.53 -22.13 64.91 -20.94Q66.28 -19.75 67.08 -17.07Q68.08 -19.77 70.02 -20.95Q71.97 -22.13 74.17 -22.13Q77.24 -22.13 79.2 -20.16Q81.17 -18.18 81.17 -14.73V0H74.37V-13.18Q74.37 -14.84 73.5 -15.7Q72.63 -16.56 71.28 -16.56Q69.84 -16.56 69 -15.62Q68.16 -14.67 68.16 -13.11V0H61.61V-13.28Q61.61 -14.79 60.77 -15.67Q59.92 -16.56 58.57 -16.56Q57.18 -16.56 56.29 -15.62Q55.4 -14.69 55.4 -12.97V0Z M83.88 8.16V-21.84H90.62V-18.09H90.85Q91.26 -19.06 92.04 -19.99Q92.82 -20.92 94.05 -21.51Q95.28 -22.11 97.02 -22.11Q99.33 -22.11 101.31 -20.9Q103.29 -19.69 104.51 -17.21Q105.73 -14.73 105.73 -10.9Q105.73 -7.19 104.55 -4.7Q103.37 -2.21 101.39 -0.95Q99.4 0.31 96.98 0.31Q94.48 0.31 92.99 -0.87Q91.49 -2.05 90.85 -3.54H90.69V8.16ZM94.66 -5Q96.63 -5 97.68 -6.62Q98.72 -8.24 98.72 -10.9Q98.72 -13.55 97.68 -15.17Q96.63 -16.78 94.66 -16.78Q92.71 -16.78 91.62 -15.2Q90.54 -13.61 90.54 -10.9Q90.54 -8.22 91.62 -6.61Q92.71 -5 94.66 -5Z M114.4 -29.1V0H107.59V-29.1Z M127.29 0.41Q122.15 0.41 119.21 -2.59Q116.27 -5.59 116.27 -10.84Q116.27 -14.2 117.59 -16.74Q118.91 -19.28 121.33 -20.69Q123.75 -22.11 127.04 -22.11Q130.1 -22.11 132.47 -20.83Q134.85 -19.55 136.21 -17.06Q137.56 -14.57 137.56 -10.98V-9.26H122.97Q123.07 -6.89 124.27 -5.71Q125.47 -4.53 127.41 -4.53Q128.77 -4.53 129.77 -5.11Q130.77 -5.68 131.18 -6.78L137.25 -5.78Q136.43 -2.95 133.84 -1.27Q131.25 0.41 127.29 0.41ZM123.01 -13.22H131.1Q130.9 -15.08 129.89 -16.12Q128.87 -17.17 127.09 -17.17Q125.3 -17.17 124.25 -16.1Q123.21 -15.04 123.01 -13.22Z" fill="#202633"/>\n <path d="M138.48 0 148.19 -29.1H157.43L167.43 0H159.69L157.72 -6.19H148.03L146.14 0ZM149.65 -11.46H156.04L155.65 -12.71Q154.89 -15.21 154.16 -17.95Q153.44 -20.68 152.74 -23.61Q152.07 -20.66 151.42 -17.93Q150.77 -15.2 150.04 -12.71Z M168.81 0V-29.1H180.72Q184 -29.1 186.39 -27.83Q188.77 -26.56 190.05 -24.3Q191.33 -22.03 191.33 -19.04Q191.33 -16.04 190.02 -13.8Q188.71 -11.56 186.29 -10.32Q183.87 -9.08 180.53 -9.08H175.7V0ZM175.7 -14.53H179.28Q181.7 -14.53 182.94 -15.77Q184.18 -17.01 184.18 -19.04Q184.18 -21.09 182.93 -22.3Q181.68 -23.52 179.26 -23.52H175.7Z M199.98 -29.1V0H193.08V-29.1Z" fill="#008A7D"/>\n</svg>\n';
@@ -16230,9 +16494,9 @@ function openapiInputForConfig(specRelativePosix) {
16230
16494
  return `./${specRelativePosix}`;
16231
16495
  }
16232
16496
  function toRelativeOpenApiInput(projectDir, inputPath) {
16233
- const resolved = path53.isAbsolute(inputPath) ? inputPath : path53.resolve(projectDir, inputPath);
16234
- const relative = path53.relative(projectDir, resolved);
16235
- const posix = relative.split(path53.sep).join(path53.posix.sep);
16497
+ const resolved = path56.isAbsolute(inputPath) ? inputPath : path56.resolve(projectDir, inputPath);
16498
+ const relative = path56.relative(projectDir, resolved);
16499
+ const posix = relative.split(path56.sep).join(path56.posix.sep);
16236
16500
  if (!posix) {
16237
16501
  throw new Error("OpenAPI path must point to a file.");
16238
16502
  }
@@ -16512,7 +16776,7 @@ function isPlanFree(plan2) {
16512
16776
  return (plan2.priceAmount ?? 0) <= 0;
16513
16777
  }
16514
16778
  function manifestFilePath(siteDirectory) {
16515
- return path54.join(path54.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
16779
+ return path57.join(path57.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
16516
16780
  }
16517
16781
  var STORED_MANIFEST_KEYS = [
16518
16782
  "authentication",
@@ -16737,9 +17001,9 @@ function applyManifestToConfig(config2, manifest) {
16737
17001
  async function readLegacyManifest(_siteDirectory) {
16738
17002
  return null;
16739
17003
  }
16740
- async function pathExists(filePath) {
17004
+ async function pathExists2(filePath) {
16741
17005
  try {
16742
- await access5(filePath);
17006
+ await access6(filePath);
16743
17007
  return true;
16744
17008
  } catch {
16745
17009
  return false;
@@ -16985,39 +17249,39 @@ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
16985
17249
  if (!trimmed) {
16986
17250
  return void 0;
16987
17251
  }
16988
- return path54.resolve(siteDirectory, trimmed);
17252
+ return path57.resolve(siteDirectory, trimmed);
16989
17253
  }
16990
17254
  function resolveBackendOpenApiPath(openApiPath, options) {
16991
17255
  const trimmed = openApiPath?.trim();
16992
17256
  if (!trimmed) {
16993
17257
  return void 0;
16994
17258
  }
16995
- if (path54.isAbsolute(trimmed)) {
17259
+ if (path57.isAbsolute(trimmed)) {
16996
17260
  return trimmed;
16997
17261
  }
16998
- const siteResolved = path54.resolve(options.siteDirectory, trimmed);
16999
- if (existsSync6(siteResolved)) {
17262
+ const siteResolved = path57.resolve(options.siteDirectory, trimmed);
17263
+ if (existsSync7(siteResolved)) {
17000
17264
  return siteResolved;
17001
17265
  }
17002
17266
  const backendDir = options.backendSourceDirectory?.trim();
17003
17267
  if (backendDir) {
17004
- const backendResolved = path54.resolve(backendDir, trimmed);
17005
- if (existsSync6(backendResolved)) {
17268
+ const backendResolved = path57.resolve(backendDir, trimmed);
17269
+ if (existsSync7(backendResolved)) {
17006
17270
  return backendResolved;
17007
17271
  }
17008
17272
  }
17009
17273
  return siteResolved;
17010
17274
  }
17011
17275
  function toSiteRelativeOpenApiInput(siteDirectory, openApiAbsolutePath) {
17012
- const relative = path54.relative(
17013
- path54.resolve(siteDirectory),
17014
- path54.resolve(openApiAbsolutePath)
17276
+ const relative = path57.relative(
17277
+ path57.resolve(siteDirectory),
17278
+ path57.resolve(openApiAbsolutePath)
17015
17279
  );
17016
- const posix = relative.split(path54.sep).join("/");
17280
+ const posix = relative.split(path57.sep).join("/");
17017
17281
  if (!posix || posix === ".") {
17018
17282
  return "./";
17019
17283
  }
17020
- if (path54.isAbsolute(posix) || posix.startsWith("..")) {
17284
+ if (path57.isAbsolute(posix) || posix.startsWith("..")) {
17021
17285
  return posix;
17022
17286
  }
17023
17287
  return posix.startsWith("./") ? posix : `./${posix}`;
@@ -17055,8 +17319,8 @@ function applyOpenApiToSiteConfig(config2, options) {
17055
17319
  }
17056
17320
  async function readManifest2(siteDirectory) {
17057
17321
  const filePath = manifestFilePath(siteDirectory);
17058
- if (await pathExists(filePath)) {
17059
- const raw = await readFile14(filePath, "utf8");
17322
+ if (await pathExists2(filePath)) {
17323
+ const raw = await readFile16(filePath, "utf8");
17060
17324
  const config2 = JSON.parse(raw);
17061
17325
  return extractManifestFromConfig(config2);
17062
17326
  }
@@ -17064,10 +17328,10 @@ async function readManifest2(siteDirectory) {
17064
17328
  }
17065
17329
  async function writeManifest2(siteDirectory, manifest) {
17066
17330
  const filePath = manifestFilePath(siteDirectory);
17067
- await mkdir13(path54.dirname(filePath), { recursive: true });
17331
+ await mkdir13(path57.dirname(filePath), { recursive: true });
17068
17332
  let config2 = {};
17069
- if (await pathExists(filePath)) {
17070
- const raw = await readFile14(filePath, "utf8");
17333
+ if (await pathExists2(filePath)) {
17334
+ const raw = await readFile16(filePath, "utf8");
17071
17335
  config2 = JSON.parse(raw);
17072
17336
  }
17073
17337
  const {
@@ -17076,21 +17340,21 @@ async function writeManifest2(siteDirectory, manifest) {
17076
17340
  ...safeManifest
17077
17341
  } = manifest;
17078
17342
  config2 = applyManifestToConfig(config2, safeManifest);
17079
- await writeFile14(filePath, `${JSON.stringify(config2, null, 2)}
17343
+ await writeFile15(filePath, `${JSON.stringify(config2, null, 2)}
17080
17344
  `, "utf8");
17081
17345
  return filePath;
17082
17346
  }
17083
17347
 
17084
17348
  // src/cli/platform/helpers/dev-portal-secrets.ts
17085
17349
  import {
17086
- access as access6,
17350
+ access as access7,
17087
17351
  appendFile,
17088
17352
  mkdir as mkdir14,
17089
- readFile as readFile15,
17353
+ readFile as readFile17,
17090
17354
  unlink,
17091
- writeFile as writeFile15
17355
+ writeFile as writeFile16
17092
17356
  } from "node:fs/promises";
17093
- import path55 from "node:path";
17357
+ import path58 from "node:path";
17094
17358
  var ENV_FILENAME = ".env";
17095
17359
  var COLLAPSED_UPPERCASE_ALIASES2 = {
17096
17360
  SECRETKEY: "secretKey",
@@ -17192,7 +17456,7 @@ function applyEnvOverrides2(config2, env) {
17192
17456
  }
17193
17457
  async function readEnvFile(filePath) {
17194
17458
  try {
17195
- const raw = await readFile15(filePath, "utf8");
17459
+ const raw = await readFile17(filePath, "utf8");
17196
17460
  const env = {};
17197
17461
  for (const line2 of raw.split("\n")) {
17198
17462
  const trimmed = line2.trim();
@@ -17209,12 +17473,12 @@ async function readEnvFile(filePath) {
17209
17473
  }
17210
17474
  }
17211
17475
  async function loadSiteEnv(siteDirectory) {
17212
- const resolvedDirectory = path55.resolve(siteDirectory);
17476
+ const resolvedDirectory = path58.resolve(siteDirectory);
17213
17477
  const merged = { ...process.env };
17214
17478
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
17215
17479
  Object.assign(
17216
17480
  merged,
17217
- await readEnvFile(path55.join(resolvedDirectory, fileName))
17481
+ await readEnvFile(path58.join(resolvedDirectory, fileName))
17218
17482
  );
17219
17483
  }
17220
17484
  return merged;
@@ -17251,7 +17515,7 @@ function buildAuthSecretsJson(secrets2, options) {
17251
17515
  return payload;
17252
17516
  }
17253
17517
  function envFilePath(siteDirectory) {
17254
- return path55.join(path55.resolve(siteDirectory), ENV_FILENAME);
17518
+ return path58.join(path58.resolve(siteDirectory), ENV_FILENAME);
17255
17519
  }
17256
17520
  function createEnvContent() {
17257
17521
  return [
@@ -17315,7 +17579,7 @@ function validateSecretsForPublish(manifest, secrets2, emailOptions) {
17315
17579
  }
17316
17580
  async function siteEnvFileHasEntries(siteDirectory) {
17317
17581
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
17318
- const loaded = await readEnvFile(path55.join(siteDirectory, fileName));
17582
+ const loaded = await readEnvFile(path58.join(siteDirectory, fileName));
17319
17583
  if (Object.keys(loaded).length > 0) {
17320
17584
  return true;
17321
17585
  }
@@ -17323,7 +17587,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
17323
17587
  return false;
17324
17588
  }
17325
17589
  async function resolvePublishConfig(siteDirectory, emailOptions) {
17326
- const resolvedDirectory = path55.resolve(siteDirectory);
17590
+ const resolvedDirectory = path58.resolve(siteDirectory);
17327
17591
  const manifestRaw = await readManifest2(resolvedDirectory);
17328
17592
  if (!manifestRaw) {
17329
17593
  throw new Error("apitogo.config.json not found in sourceDirectory.");
@@ -17356,20 +17620,20 @@ function envFileHasActiveAssignments(content) {
17356
17620
  });
17357
17621
  }
17358
17622
  async function writeScaffoldEnv(siteDirectory) {
17359
- const resolvedDirectory = path55.resolve(siteDirectory);
17623
+ const resolvedDirectory = path58.resolve(siteDirectory);
17360
17624
  const filesWritten = [];
17361
17625
  const envPath = envFilePath(resolvedDirectory);
17362
17626
  try {
17363
- await access6(envPath);
17627
+ await access7(envPath);
17364
17628
  } catch {
17365
17629
  await mkdir14(resolvedDirectory, { recursive: true });
17366
- await writeFile15(envPath, createEnvContent(), "utf8");
17630
+ await writeFile16(envPath, createEnvContent(), "utf8");
17367
17631
  filesWritten.push(ENV_FILENAME);
17368
17632
  }
17369
17633
  for (const legacyName of [".env.example"]) {
17370
- const legacyPath = path55.join(resolvedDirectory, legacyName);
17634
+ const legacyPath = path58.join(resolvedDirectory, legacyName);
17371
17635
  try {
17372
- const legacy = await readFile15(legacyPath, "utf8");
17636
+ const legacy = await readFile17(legacyPath, "utf8");
17373
17637
  if (!envFileHasActiveAssignments(legacy)) {
17374
17638
  await unlink(legacyPath);
17375
17639
  filesWritten.push(`removed:${legacyName}`);
@@ -17377,10 +17641,10 @@ async function writeScaffoldEnv(siteDirectory) {
17377
17641
  } catch {
17378
17642
  }
17379
17643
  }
17380
- const gitignorePath = path55.join(resolvedDirectory, ".gitignore");
17644
+ const gitignorePath = path58.join(resolvedDirectory, ".gitignore");
17381
17645
  let gitignore = "";
17382
17646
  try {
17383
- gitignore = await readFile15(gitignorePath, "utf8");
17647
+ gitignore = await readFile17(gitignorePath, "utf8");
17384
17648
  } catch {
17385
17649
  gitignore = "";
17386
17650
  }
@@ -17392,7 +17656,7 @@ async function writeScaffoldEnv(siteDirectory) {
17392
17656
  if (!hasEntry) {
17393
17657
  const suffix = gitignore.length === 0 ? "" : gitignore.endsWith("\n") ? "" : "\n";
17394
17658
  if (gitignore.length === 0) {
17395
- await writeFile15(gitignorePath, `${entry}
17659
+ await writeFile16(gitignorePath, `${entry}
17396
17660
  `, "utf8");
17397
17661
  } else {
17398
17662
  await appendFile(gitignorePath, `${suffix}${entry}
@@ -17412,13 +17676,13 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
17412
17676
 
17413
17677
  // src/cli/platform/helpers/dev-portal-site-validation.ts
17414
17678
  init_gateway_limits();
17415
- import { readFile as readFile16 } from "node:fs/promises";
17679
+ import { readFile as readFile18 } from "node:fs/promises";
17416
17680
  import { createRequire as createRequire3 } from "node:module";
17417
- import path56 from "node:path";
17681
+ import path59 from "node:path";
17418
17682
  var cachedFallbackTs;
17419
17683
  async function loadTypeScriptForSite(sourceDirectory) {
17420
17684
  const require2 = createRequire3(
17421
- path56.join(path56.resolve(sourceDirectory), "package.json")
17685
+ path59.join(path59.resolve(sourceDirectory), "package.json")
17422
17686
  );
17423
17687
  try {
17424
17688
  return require2("typescript");
@@ -17464,8 +17728,8 @@ async function referencedFileExists(sourceDirectory, reference) {
17464
17728
  if (/^https?:\/\//i.test(reference)) {
17465
17729
  return true;
17466
17730
  }
17467
- return pathExists(
17468
- path56.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
17731
+ return pathExists2(
17732
+ path59.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
17469
17733
  );
17470
17734
  }
17471
17735
  async function validateSiteConfigStructure(config2, sourceDirectory) {
@@ -17580,17 +17844,17 @@ var DEFAULT_TSX_CANDIDATES = [
17580
17844
  "landing/LandingPage.tsx"
17581
17845
  ];
17582
17846
  async function validateDevPortalSiteConfig(sourceDirectory, options) {
17583
- const resolvedDir = path56.resolve(sourceDirectory);
17847
+ const resolvedDir = path59.resolve(sourceDirectory);
17584
17848
  const issues = [];
17585
17849
  const checkedFiles = [];
17586
17850
  const skippedChecks = [];
17587
- const jsonPath = path56.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
17588
- if (await pathExists(jsonPath)) {
17851
+ const jsonPath = path59.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
17852
+ if (await pathExists2(jsonPath)) {
17589
17853
  checkedFiles.push(APITOGO_CONFIG_FILENAME2);
17590
17854
  let parsed;
17591
17855
  let parseFailed = false;
17592
17856
  try {
17593
- parsed = JSON.parse(await readFile16(jsonPath, "utf8"));
17857
+ parsed = JSON.parse(await readFile18(jsonPath, "utf8"));
17594
17858
  } catch (error) {
17595
17859
  parseFailed = true;
17596
17860
  issues.push({
@@ -17616,7 +17880,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
17616
17880
  );
17617
17881
  const existingTsxFiles = [];
17618
17882
  for (const relativeFile of tsxFiles) {
17619
- if (await pathExists(path56.join(resolvedDir, relativeFile))) {
17883
+ if (await pathExists2(path59.join(resolvedDir, relativeFile))) {
17620
17884
  existingTsxFiles.push(relativeFile);
17621
17885
  }
17622
17886
  }
@@ -17629,8 +17893,8 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
17629
17893
  } else {
17630
17894
  for (const relativeFile of existingTsxFiles) {
17631
17895
  checkedFiles.push(relativeFile);
17632
- const content = await readFile16(
17633
- path56.join(resolvedDir, relativeFile),
17896
+ const content = await readFile18(
17897
+ path59.join(resolvedDir, relativeFile),
17634
17898
  "utf8"
17635
17899
  );
17636
17900
  issues.push(
@@ -17665,134 +17929,6 @@ function buildSiteValidationResponseFields(result) {
17665
17929
  };
17666
17930
  }
17667
17931
 
17668
- // src/cli/platform/helpers/npm-build.ts
17669
- import { spawn as spawn2 } from "node:child_process";
17670
- import { access as access7, readFile as readFile17 } from "node:fs/promises";
17671
- import path57 from "node:path";
17672
- var BUILD_LOG_TAIL_BYTES = 8192;
17673
- var MIN_NODE_MAJOR = 20;
17674
- var NpmBuildError = class extends Error {
17675
- buildLog;
17676
- exitCode;
17677
- constructor(message, buildLog, exitCode) {
17678
- super(message);
17679
- this.name = "NpmBuildError";
17680
- this.buildLog = buildLog;
17681
- this.exitCode = exitCode;
17682
- }
17683
- };
17684
- function parseNodeMajor(version) {
17685
- const match = /^v?(\d+)/.exec(version.trim());
17686
- return match ? Number.parseInt(match[1], 10) : Number.NaN;
17687
- }
17688
- function assertNodeVersion(required) {
17689
- const major = parseNodeMajor(process.version);
17690
- if (Number.isNaN(major) || major < MIN_NODE_MAJOR) {
17691
- throw new Error(
17692
- `Node.js ${MIN_NODE_MAJOR}+ is required (current: ${process.version}).`
17693
- );
17694
- }
17695
- if (required) {
17696
- const requiredMajor = parseNodeMajor(required);
17697
- if (!Number.isNaN(requiredMajor) && major < requiredMajor) {
17698
- throw new Error(
17699
- `Node.js ${requiredMajor}+ is required by nodeVersion option (current: ${process.version}).`
17700
- );
17701
- }
17702
- }
17703
- }
17704
- function truncateBuildLog(log, success) {
17705
- if (success && log.length > BUILD_LOG_TAIL_BYTES) {
17706
- return log.slice(-BUILD_LOG_TAIL_BYTES);
17707
- }
17708
- return log;
17709
- }
17710
- async function pathExists2(filePath) {
17711
- try {
17712
- await access7(filePath);
17713
- return true;
17714
- } catch {
17715
- return false;
17716
- }
17717
- }
17718
- function runCommand(command2, args, cwd, env) {
17719
- return new Promise((resolve, reject) => {
17720
- const child = spawn2(command2, args, {
17721
- cwd,
17722
- env: env ? { ...process.env, ...env } : process.env,
17723
- shell: process.platform === "win32"
17724
- });
17725
- let output4 = "";
17726
- child.stdout.on("data", (chunk) => {
17727
- output4 += chunk.toString();
17728
- });
17729
- child.stderr.on("data", (chunk) => {
17730
- output4 += chunk.toString();
17731
- });
17732
- child.on("error", reject);
17733
- child.on("close", (exitCode) => resolve({ exitCode, output: output4 }));
17734
- });
17735
- }
17736
- async function runNpmInstall(sourceDirectory, options) {
17737
- assertNodeVersion(options?.nodeVersion);
17738
- const cwd = path57.resolve(sourceDirectory);
17739
- const packageJsonPath = path57.join(cwd, "package.json");
17740
- if (!await pathExists2(packageJsonPath)) {
17741
- throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
17742
- }
17743
- const startedAt = Date.now();
17744
- const lockPath = path57.join(cwd, "package-lock.json");
17745
- const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
17746
- const install = await runCommand("npm", installArgs, cwd);
17747
- const installLog = install.output;
17748
- if (install.exitCode !== 0) {
17749
- throw new NpmBuildError(
17750
- `npm ${installArgs.join(" ")} exited ${install.exitCode ?? "unknown"}`,
17751
- installLog,
17752
- install.exitCode
17753
- );
17754
- }
17755
- return {
17756
- durationMs: Date.now() - startedAt,
17757
- installLog: truncateBuildLog(installLog, true)
17758
- };
17759
- }
17760
- async function runNpmBuild(sourceDirectory, options) {
17761
- assertNodeVersion(options?.nodeVersion);
17762
- const cwd = path57.resolve(sourceDirectory);
17763
- const packageJsonPath = path57.join(cwd, "package.json");
17764
- if (!await pathExists2(packageJsonPath)) {
17765
- throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
17766
- }
17767
- const startedAt = Date.now();
17768
- let buildLog = "";
17769
- const install = await runNpmInstall(sourceDirectory, options);
17770
- buildLog += install.installLog;
17771
- const build2 = await runCommand("npm", ["run", "build"], cwd, options?.env);
17772
- buildLog += build2.output;
17773
- if (build2.exitCode !== 0) {
17774
- throw new NpmBuildError(
17775
- `npm run build exited ${build2.exitCode ?? "unknown"}`,
17776
- buildLog,
17777
- build2.exitCode
17778
- );
17779
- }
17780
- const distPath = path57.join(cwd, "dist");
17781
- const indexPath = path57.join(distPath, "index.html");
17782
- if (!await pathExists2(indexPath)) {
17783
- throw new NpmBuildError(
17784
- `Build completed but dist/index.html was not found at ${indexPath}`,
17785
- buildLog,
17786
- build2.exitCode
17787
- );
17788
- }
17789
- return {
17790
- distPath,
17791
- durationMs: Date.now() - startedAt,
17792
- buildLog: truncateBuildLog(buildLog, true)
17793
- };
17794
- }
17795
-
17796
17932
  // src/cli/platform/helpers/paid-gateway-platform-compat.ts
17797
17933
  function listPaidManifestPlans(plans) {
17798
17934
  return (plans ?? []).filter((plan2) => !isPlanFree(plan2)).map((plan2) => ({
@@ -18162,7 +18298,7 @@ function validateManifestForPlatformPublish(manifest) {
18162
18298
 
18163
18299
  // src/cli/platform/tools/check-publish-readiness.ts
18164
18300
  async function checkPublishReadiness(client, _config, args) {
18165
- const sourceDirectory = path58.resolve(args.sourceDirectory);
18301
+ const sourceDirectory = path60.resolve(args.sourceDirectory);
18166
18302
  const manifest = await readManifest2(sourceDirectory) ?? createScaffoldManifest();
18167
18303
  const emailOptions = await resolveEmailOptionsForPublish(
18168
18304
  client,
@@ -18240,7 +18376,7 @@ async function checkPublishReadiness(client, _config, args) {
18240
18376
 
18241
18377
  // src/cli/check/handler.ts
18242
18378
  async function check(argv) {
18243
- const sourceDirectory = path59.resolve(process.cwd(), argv.dir);
18379
+ const sourceDirectory = path61.resolve(process.cwd(), argv.dir);
18244
18380
  if (await isConfigV2(sourceDirectory)) {
18245
18381
  await checkV2(sourceDirectory, argv);
18246
18382
  return;
@@ -18304,14 +18440,14 @@ var check_default = {
18304
18440
 
18305
18441
  // src/cli/make-config/handler.ts
18306
18442
  import { constants as constants2 } from "node:fs";
18307
- import { access as access12, mkdir as mkdir17, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
18308
- import path69 from "node:path";
18443
+ import { access as access12, mkdir as mkdir17, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
18444
+ import path71 from "node:path";
18309
18445
  import { stdin as input2 } from "node:process";
18310
18446
  import { glob as glob8 } from "glob";
18311
18447
 
18312
18448
  // src/cli/platform/helpers/openapi-action-keys.ts
18313
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
18314
- import path60 from "node:path";
18449
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
18450
+ import path62 from "node:path";
18315
18451
  import YAML from "yaml";
18316
18452
  var HTTP_METHODS = [
18317
18453
  "get",
@@ -18380,7 +18516,7 @@ function extractGatewayActionKeysFromOpenApiDocument(document) {
18380
18516
  function extractGatewayActionKeysFromOpenApiFile(filePath) {
18381
18517
  try {
18382
18518
  const raw = readFileSync4(filePath, "utf8");
18383
- const ext = path60.extname(filePath).toLowerCase();
18519
+ const ext = path62.extname(filePath).toLowerCase();
18384
18520
  const parsed = ext === ".json" ? JSON.parse(raw) : YAML.parse(raw);
18385
18521
  return extractGatewayActionKeysFromOpenApiDocument(parsed);
18386
18522
  } catch {
@@ -18401,8 +18537,8 @@ function resolveConfigOpenApiFilePath(siteDirectory, config2) {
18401
18537
  }
18402
18538
  }
18403
18539
  for (const candidate of candidates) {
18404
- const resolved = path60.isAbsolute(candidate) ? candidate : path60.resolve(siteDirectory, candidate);
18405
- if (existsSync7(resolved)) {
18540
+ const resolved = path62.isAbsolute(candidate) ? candidate : path62.resolve(siteDirectory, candidate);
18541
+ if (existsSync8(resolved)) {
18406
18542
  return resolved;
18407
18543
  }
18408
18544
  }
@@ -18416,8 +18552,8 @@ function loadOpenApiActionKeysForSite(siteDirectory, config2) {
18416
18552
  return extractGatewayActionKeysFromOpenApiFile(filePath);
18417
18553
  }
18418
18554
  function loadOpenApiActionKeysFromSiteDirectory(siteDirectory) {
18419
- const configPath = path60.join(siteDirectory, "apitogo.config.json");
18420
- if (!existsSync7(configPath)) {
18555
+ const configPath = path62.join(siteDirectory, "apitogo.config.json");
18556
+ if (!existsSync8(configPath)) {
18421
18557
  return [];
18422
18558
  }
18423
18559
  try {
@@ -18444,12 +18580,12 @@ function withDefaultIncludedActionKeys(plan2, actionKeys) {
18444
18580
  }
18445
18581
 
18446
18582
  // src/cli/scaffold/dev-portal-config-pages.ts
18447
- import { access as access8, readFile as readFile18, rename as rename7, rm as rm9, writeFile as writeFile16 } from "node:fs/promises";
18448
- import path61 from "node:path";
18583
+ import { access as access8, readFile as readFile19, rename as rename7, rm as rm9, writeFile as writeFile17 } from "node:fs/promises";
18584
+ import path63 from "node:path";
18449
18585
  async function writeConfigAtomically(filePath, content) {
18450
18586
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
18451
18587
  try {
18452
- await writeFile16(temporaryPath, content, "utf8");
18588
+ await writeFile17(temporaryPath, content, "utf8");
18453
18589
  await rename7(temporaryPath, filePath);
18454
18590
  } catch (error) {
18455
18591
  await rm9(temporaryPath, { force: true });
@@ -18458,7 +18594,7 @@ async function writeConfigAtomically(filePath, content) {
18458
18594
  }
18459
18595
  async function resolveApitogoConfigPath(sourceDirectory) {
18460
18596
  for (const filename of ["apitogo.config.tsx", "apitogo.config.jsx"]) {
18461
- const configPath = path61.join(sourceDirectory, filename);
18597
+ const configPath = path63.join(sourceDirectory, filename);
18462
18598
  try {
18463
18599
  await access8(configPath);
18464
18600
  return configPath;
@@ -19209,7 +19345,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
19209
19345
  if (!configPath) {
19210
19346
  return { updated: false };
19211
19347
  }
19212
- const original = await readFile18(configPath, "utf8");
19348
+ const original = await readFile19(configPath, "utf8");
19213
19349
  const patched = patchApitogoConfigForNewPage(original, slug, label, {
19214
19350
  typescript: configPath.endsWith(".tsx")
19215
19351
  });
@@ -19221,18 +19357,18 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
19221
19357
  }
19222
19358
 
19223
19359
  // src/cli/scaffold/wire-openapi.ts
19224
- import { access as access10, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
19225
- import path66 from "node:path";
19360
+ import { access as access10, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
19361
+ import path68 from "node:path";
19226
19362
 
19227
19363
  // src/cli/platform/helpers/openapi.ts
19228
19364
  import { promises as fs6 } from "node:fs";
19229
- import path63 from "node:path";
19365
+ import path65 from "node:path";
19230
19366
  import SwaggerParser from "@apidevtools/swagger-parser";
19231
19367
  import YAML2 from "yaml";
19232
19368
 
19233
19369
  // src/cli/scaffold/discover-openapi-files.ts
19234
19370
  import { promises as fs5 } from "node:fs";
19235
- import path62 from "node:path";
19371
+ import path64 from "node:path";
19236
19372
  var OPENAPI_BASENAMES = [
19237
19373
  "openapi.yaml",
19238
19374
  "openapi.yml",
@@ -19254,13 +19390,13 @@ var SKIP_OPENAPI_SEARCH_DIRS = /* @__PURE__ */ new Set([
19254
19390
  ".apitogo"
19255
19391
  ]);
19256
19392
  async function collectFromDir(dir, searchedDirectories, candidates) {
19257
- const resolved = path62.resolve(dir);
19393
+ const resolved = path64.resolve(dir);
19258
19394
  if (searchedDirectories.includes(resolved)) {
19259
19395
  return;
19260
19396
  }
19261
19397
  searchedDirectories.push(resolved);
19262
19398
  for (const name of OPENAPI_BASENAMES) {
19263
- const candidate = path62.join(resolved, name);
19399
+ const candidate = path64.join(resolved, name);
19264
19400
  try {
19265
19401
  await fs5.access(candidate);
19266
19402
  candidates.push(candidate);
@@ -19275,8 +19411,8 @@ async function collectSiteOpenApiFiles(siteDirectory) {
19275
19411
  return { candidates: [...new Set(candidates)], searchedDirectories };
19276
19412
  }
19277
19413
  async function collectNearbyOpenApiFiles(siteDirectory) {
19278
- const site = path62.resolve(siteDirectory);
19279
- const parent = path62.dirname(site);
19414
+ const site = path64.resolve(siteDirectory);
19415
+ const parent = path64.dirname(site);
19280
19416
  const searchedDirectories = [];
19281
19417
  const candidates = [];
19282
19418
  if (parent && parent !== site) {
@@ -19287,8 +19423,8 @@ async function collectNearbyOpenApiFiles(siteDirectory) {
19287
19423
  if (!entry.isDirectory() || SKIP_OPENAPI_SEARCH_DIRS.has(entry.name)) {
19288
19424
  continue;
19289
19425
  }
19290
- const sibling = path62.join(parent, entry.name);
19291
- if (path62.resolve(sibling) === site) {
19426
+ const sibling = path64.join(parent, entry.name);
19427
+ if (path64.resolve(sibling) === site) {
19292
19428
  continue;
19293
19429
  }
19294
19430
  await collectFromDir(sibling, searchedDirectories, candidates);
@@ -19316,7 +19452,7 @@ function parseOpenApiObject(doc) {
19316
19452
  };
19317
19453
  }
19318
19454
  function liteParseOpenApi(content, filePath) {
19319
- const ext = path62.extname(filePath).toLowerCase();
19455
+ const ext = path64.extname(filePath).toLowerCase();
19320
19456
  if (ext === ".json") {
19321
19457
  try {
19322
19458
  const parsed = JSON.parse(content);
@@ -19381,9 +19517,9 @@ async function discoverNearbyOpenApi(siteDirectory) {
19381
19517
  };
19382
19518
  }
19383
19519
  async function validateOpenApiFile(filePath) {
19384
- const resolved = path63.resolve(filePath);
19520
+ const resolved = path65.resolve(filePath);
19385
19521
  const content = await fs6.readFile(resolved, "utf8");
19386
- const ext = path63.extname(resolved).toLowerCase();
19522
+ const ext = path65.extname(resolved).toLowerCase();
19387
19523
  let parsed;
19388
19524
  try {
19389
19525
  parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
@@ -19425,8 +19561,8 @@ async function validateOpenApiFile(filePath) {
19425
19561
  }
19426
19562
 
19427
19563
  // src/cli/scaffold/scaffold-dev-portal-site.ts
19428
- import { mkdir as mkdir15, readFile as readFile19, writeFile as writeFile17 } from "node:fs/promises";
19429
- import path65 from "node:path";
19564
+ import { mkdir as mkdir15, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
19565
+ import path67 from "node:path";
19430
19566
 
19431
19567
  // src/cli/scaffold/apitogo-npm-packages.ts
19432
19568
  var DEFAULT_CREATE_APITOGO_PACKAGE2 = "@lukoweb/create-apitogo@latest";
@@ -19514,7 +19650,7 @@ var DOC_TOOL_LOCAL_PACKAGE_PATHS = {
19514
19650
  // src/cli/scaffold/create-apitogo-cli.ts
19515
19651
  import { spawn as spawn3 } from "node:child_process";
19516
19652
  import { access as access9, rm as rm10 } from "node:fs/promises";
19517
- import path64 from "node:path";
19653
+ import path66 from "node:path";
19518
19654
  var SKIP_NEARBY_DISCOVERY_ENV = "APITOGO_SKIP_NEARBY_DISCOVERY";
19519
19655
  var CreateApitogoCliError = class extends Error {
19520
19656
  exitCode;
@@ -19531,9 +19667,9 @@ function resolveDocToolPath(explicit) {
19531
19667
  return value || void 0;
19532
19668
  }
19533
19669
  function splitOutputDirectory(outputDirectory) {
19534
- const resolvedOutputDirectory = path64.resolve(outputDirectory);
19535
- const projectName = path64.basename(resolvedOutputDirectory);
19536
- const parentDirectory = path64.dirname(resolvedOutputDirectory);
19670
+ const resolvedOutputDirectory = path66.resolve(outputDirectory);
19671
+ const projectName = path66.basename(resolvedOutputDirectory);
19672
+ const parentDirectory = path66.dirname(resolvedOutputDirectory);
19537
19673
  if (!projectName || projectName === "." || projectName === "..") {
19538
19674
  throw new Error(
19539
19675
  "outputDirectory must be a named folder (e.g. ./dev-portal-site), not the current directory."
@@ -19559,7 +19695,7 @@ async function directoryHasEntries(dir) {
19559
19695
  }
19560
19696
  }
19561
19697
  function resolveLocalCreateApitogoEntry(docToolPath) {
19562
- return path64.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
19698
+ return path66.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
19563
19699
  }
19564
19700
  async function resolveCreateApitogoInvocation(options) {
19565
19701
  const docToolPath = resolveDocToolPath(options.docToolPath);
@@ -19641,7 +19777,7 @@ async function runCreateApitogoDevPortal(options) {
19641
19777
  result.exitCode
19642
19778
  );
19643
19779
  }
19644
- if (!await pathExists3(path64.join(resolvedOutputDirectory, "package.json"))) {
19780
+ if (!await pathExists3(path66.join(resolvedOutputDirectory, "package.json"))) {
19645
19781
  throw new CreateApitogoCliError(
19646
19782
  `create-apitogo completed but package.json was not found at ${resolvedOutputDirectory}`,
19647
19783
  result.output,
@@ -19700,7 +19836,7 @@ function ensureRequiredApitogoModules(pkg, options) {
19700
19836
  ]
19701
19837
  ]) {
19702
19838
  if (options.docToolPath) {
19703
- deps[moduleName] = `file:${path65.join(options.docToolPath, localPath)}`;
19839
+ deps[moduleName] = `file:${path67.join(options.docToolPath, localPath)}`;
19704
19840
  continue;
19705
19841
  }
19706
19842
  deps[moduleName] = `npm:${moduleName}@${moduleAliasVersion}`;
@@ -19731,7 +19867,7 @@ function rewritePackageJson(raw, options) {
19731
19867
  DOC_TOOL_LOCAL_PACKAGE_PATHS
19732
19868
  )) {
19733
19869
  if (dep in deps) {
19734
- deps[dep] = `file:${path65.join(options.docToolPath, relativePath)}`;
19870
+ deps[dep] = `file:${path67.join(options.docToolPath, relativePath)}`;
19735
19871
  linkedWorkspacePackage = true;
19736
19872
  }
19737
19873
  }
@@ -19831,24 +19967,24 @@ function patchDashboardPageConfig(content) {
19831
19967
  );
19832
19968
  }
19833
19969
  async function ensureAccountPlansPage(outputDirectory) {
19834
- const pagePath = path65.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
19970
+ const pagePath = path67.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
19835
19971
  try {
19836
- await readFile19(pagePath, "utf8");
19972
+ await readFile20(pagePath, "utf8");
19837
19973
  return void 0;
19838
19974
  } catch {
19839
- await mkdir15(path65.dirname(pagePath), { recursive: true });
19840
- await writeFile17(pagePath, ACCOUNT_PLANS_PAGE);
19975
+ await mkdir15(path67.dirname(pagePath), { recursive: true });
19976
+ await writeFile18(pagePath, ACCOUNT_PLANS_PAGE);
19841
19977
  return ACCOUNT_PLANS_PAGE_PATH;
19842
19978
  }
19843
19979
  }
19844
19980
  async function ensureDashboardPage(outputDirectory) {
19845
- const pagePath = path65.join(outputDirectory, DASHBOARD_PAGE_PATH);
19981
+ const pagePath = path67.join(outputDirectory, DASHBOARD_PAGE_PATH);
19846
19982
  try {
19847
- await readFile19(pagePath, "utf8");
19983
+ await readFile20(pagePath, "utf8");
19848
19984
  return void 0;
19849
19985
  } catch {
19850
- await mkdir15(path65.dirname(pagePath), { recursive: true });
19851
- await writeFile17(pagePath, DASHBOARD_PAGE);
19986
+ await mkdir15(path67.dirname(pagePath), { recursive: true });
19987
+ await writeFile18(pagePath, DASHBOARD_PAGE);
19852
19988
  return DASHBOARD_PAGE_PATH;
19853
19989
  }
19854
19990
  }
@@ -19904,10 +20040,10 @@ function patchApitogoConfig(content, options) {
19904
20040
  async function patchScaffoldedSite(outputDirectory, options) {
19905
20041
  const title = options.branding?.title ?? options.siteName;
19906
20042
  const filesWritten = [];
19907
- const packageJsonPath = path65.join(outputDirectory, "package.json");
20043
+ const packageJsonPath = path67.join(outputDirectory, "package.json");
19908
20044
  if (options.patchPackageJson !== false) {
19909
- const packageJson3 = await readFile19(packageJsonPath, "utf8");
19910
- await writeFile17(
20045
+ const packageJson3 = await readFile20(packageJsonPath, "utf8");
20046
+ await writeFile18(
19911
20047
  packageJsonPath,
19912
20048
  rewritePackageJson(packageJson3, {
19913
20049
  siteName: options.siteName,
@@ -19917,9 +20053,9 @@ async function patchScaffoldedSite(outputDirectory, options) {
19917
20053
  );
19918
20054
  filesWritten.push("package.json");
19919
20055
  }
19920
- const configPath = path65.join(outputDirectory, "apitogo.config.tsx");
19921
- const configContent = await readFile19(configPath, "utf8");
19922
- await writeFile17(
20056
+ const configPath = path67.join(outputDirectory, "apitogo.config.tsx");
20057
+ const configContent = await readFile20(configPath, "utf8");
20058
+ await writeFile18(
19923
20059
  configPath,
19924
20060
  patchDashboardPageConfig(
19925
20061
  patchAccountPlansPageConfig(
@@ -20012,8 +20148,8 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
20012
20148
  return discoverNearbyOpenApi(siteDirectory);
20013
20149
  }
20014
20150
  async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
20015
- const resolvedSource = path66.resolve(sourceDirectory);
20016
- const resolvedOpenApi = path66.resolve(openApiPath);
20151
+ const resolvedSource = path68.resolve(sourceDirectory);
20152
+ const resolvedOpenApi = path68.resolve(openApiPath);
20017
20153
  const input5 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
20018
20154
  const validation = await validateOpenApiFile(resolvedOpenApi);
20019
20155
  if (!validation.valid) {
@@ -20025,24 +20161,24 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
20025
20161
  }
20026
20162
  const jsonConfigPath = manifestFilePath(resolvedSource);
20027
20163
  if (await pathExists4(jsonConfigPath)) {
20028
- const raw = await readFile20(jsonConfigPath, "utf8");
20164
+ const raw = await readFile21(jsonConfigPath, "utf8");
20029
20165
  const siteConfig = JSON.parse(raw);
20030
20166
  const updated = applyOpenApiToSiteConfig(siteConfig, {
20031
20167
  input: input5,
20032
20168
  apiPath: "api"
20033
20169
  });
20034
- await writeFile18(
20170
+ await writeFile19(
20035
20171
  jsonConfigPath,
20036
20172
  `${JSON.stringify(updated, null, 2)}
20037
20173
  `,
20038
20174
  "utf8"
20039
20175
  );
20040
20176
  } else {
20041
- const tsxConfigPath = path66.join(resolvedSource, "apitogo.config.tsx");
20042
- const configContent = await readFile20(tsxConfigPath, "utf8");
20177
+ const tsxConfigPath = path68.join(resolvedSource, "apitogo.config.tsx");
20178
+ const configContent = await readFile21(tsxConfigPath, "utf8");
20043
20179
  try {
20044
20180
  const patched = patchApitogoConfigOpenApiToFile(configContent, input5);
20045
- await writeFile18(tsxConfigPath, patched);
20181
+ await writeFile19(tsxConfigPath, patched);
20046
20182
  } catch (error) {
20047
20183
  return {
20048
20184
  status: "failed",
@@ -20124,7 +20260,7 @@ async function discoverAndWireOpenApi(siteDirectory, mode) {
20124
20260
  }
20125
20261
 
20126
20262
  // src/cli/make-config/interactive.ts
20127
- import path67 from "node:path";
20263
+ import path69 from "node:path";
20128
20264
  import { stdin as input, stdout as output } from "node:process";
20129
20265
  import { createInterface as createInterface3 } from "node:readline/promises";
20130
20266
 
@@ -20300,7 +20436,7 @@ async function promptMakeConfigInteractive(options) {
20300
20436
  continue;
20301
20437
  }
20302
20438
  const routePath = `/${slug}`;
20303
- const relativePath = path67.posix.join(options.pagesDir, `${slug}.tsx`);
20439
+ const relativePath = path69.posix.join(options.pagesDir, `${slug}.tsx`);
20304
20440
  const page = {
20305
20441
  slug,
20306
20442
  title: pageTitle.trim(),
@@ -20395,8 +20531,8 @@ export default function ${componentName}() {
20395
20531
  // src/cli/make-config/scaffold-project.ts
20396
20532
  init_package_json();
20397
20533
  import { constants } from "node:fs";
20398
- import { access as access11, mkdir as mkdir16, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
20399
- import path68 from "node:path";
20534
+ import { access as access11, mkdir as mkdir16, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
20535
+ import path70 from "node:path";
20400
20536
  import { glob as glob7 } from "glob";
20401
20537
 
20402
20538
  // src/cli/make-config/favicon-png.ts
@@ -20411,9 +20547,9 @@ var OPENAPI_GLOBS = [
20411
20547
  "openapi.yaml",
20412
20548
  "openapi.yml"
20413
20549
  ];
20414
- var toPosix2 = (p) => p.split(path68.sep).join("/");
20550
+ var toPosix2 = (p) => p.split(path70.sep).join("/");
20415
20551
  var sanitizePackageName = (dir) => {
20416
- const base = path68.basename(path68.resolve(dir));
20552
+ const base = path70.basename(path70.resolve(dir));
20417
20553
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
20418
20554
  return s || "apitogo-site";
20419
20555
  };
@@ -20423,7 +20559,7 @@ var apitogoVersionRange = () => {
20423
20559
  };
20424
20560
  async function findOpenApiSpecPath(dir) {
20425
20561
  for (const rel2 of OPENAPI_GLOBS) {
20426
- const full = path68.join(dir, rel2);
20562
+ const full = path70.join(dir, rel2);
20427
20563
  try {
20428
20564
  await access11(full, constants.R_OK);
20429
20565
  return toPosix2(rel2);
@@ -20437,8 +20573,8 @@ async function findOpenApiSpecPath(dir) {
20437
20573
  });
20438
20574
  return extra[0] ? toPosix2(extra[0]) : null;
20439
20575
  }
20440
- async function ensurePackageJson(dir) {
20441
- const pkgPath = path68.join(dir, "package.json");
20576
+ async function ensurePackageJson2(dir) {
20577
+ const pkgPath = path70.join(dir, "package.json");
20442
20578
  const apitogoVer = apitogoVersionRange();
20443
20579
  const baseDeps = {
20444
20580
  react: ">=19.0.0",
@@ -20473,11 +20609,11 @@ async function ensurePackageJson(dir) {
20473
20609
  typescript: "^5"
20474
20610
  }
20475
20611
  };
20476
- await writeFile19(pkgPath, `${JSON.stringify(pkg2, null, 2)}
20612
+ await writeFile20(pkgPath, `${JSON.stringify(pkg2, null, 2)}
20477
20613
  `, "utf8");
20478
20614
  return true;
20479
20615
  }
20480
- const raw = await readFile21(pkgPath, "utf8");
20616
+ const raw = await readFile22(pkgPath, "utf8");
20481
20617
  let pkg;
20482
20618
  try {
20483
20619
  pkg = JSON.parse(raw);
@@ -20500,12 +20636,12 @@ async function ensurePackageJson(dir) {
20500
20636
  for (const [k, v] of Object.entries(baseDeps)) {
20501
20637
  if (!deps[k]) deps[k] = v;
20502
20638
  }
20503
- await writeFile19(pkgPath, `${JSON.stringify(pkg, null, 2)}
20639
+ await writeFile20(pkgPath, `${JSON.stringify(pkg, null, 2)}
20504
20640
  `, "utf8");
20505
20641
  return false;
20506
20642
  }
20507
20643
  async function ensureTsconfigJson(dir) {
20508
- const tsPath = path68.join(dir, "tsconfig.json");
20644
+ const tsPath = path70.join(dir, "tsconfig.json");
20509
20645
  try {
20510
20646
  await access11(tsPath, constants.R_OK);
20511
20647
  return false;
@@ -20535,7 +20671,7 @@ async function ensureTsconfigJson(dir) {
20535
20671
  "user-panel"
20536
20672
  ]
20537
20673
  };
20538
- await writeFile19(tsPath, `${JSON.stringify(tsconfig, null, 2)}
20674
+ await writeFile20(tsPath, `${JSON.stringify(tsconfig, null, 2)}
20539
20675
  `, "utf8");
20540
20676
  return true;
20541
20677
  }
@@ -20554,49 +20690,49 @@ var fileExists2 = async (filePath) => {
20554
20690
  }
20555
20691
  };
20556
20692
  async function ensurePortalStubFiles(dir) {
20557
- const landingPath = path68.join(dir, "landing", "LandingPage.tsx");
20693
+ const landingPath = path70.join(dir, "landing", "LandingPage.tsx");
20558
20694
  if (!await fileExists2(landingPath)) {
20559
- await mkdir16(path68.join(dir, "landing"), { recursive: true });
20560
- await writeFile19(landingPath, LANDING_PAGE_SOURCE, "utf8");
20695
+ await mkdir16(path70.join(dir, "landing"), { recursive: true });
20696
+ await writeFile20(landingPath, LANDING_PAGE_SOURCE, "utf8");
20561
20697
  }
20562
- const plansPath = path68.join(dir, "user-panel", "AccountPlansPage.tsx");
20698
+ const plansPath = path70.join(dir, "user-panel", "AccountPlansPage.tsx");
20563
20699
  if (!await fileExists2(plansPath)) {
20564
- await mkdir16(path68.join(dir, "user-panel"), { recursive: true });
20565
- await writeFile19(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20700
+ await mkdir16(path70.join(dir, "user-panel"), { recursive: true });
20701
+ await writeFile20(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20566
20702
  }
20567
- const dashboardPath = path68.join(dir, "user-panel", "DashboardPage.tsx");
20703
+ const dashboardPath = path70.join(dir, "user-panel", "DashboardPage.tsx");
20568
20704
  if (!await fileExists2(dashboardPath)) {
20569
- await mkdir16(path68.join(dir, "user-panel"), { recursive: true });
20570
- await writeFile19(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20705
+ await mkdir16(path70.join(dir, "user-panel"), { recursive: true });
20706
+ await writeFile20(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20571
20707
  }
20572
20708
  await ensurePublicBrandingFiles(dir);
20573
20709
  }
20574
20710
  async function ensurePublicBrandingFiles(dir) {
20575
- const destDir = path68.join(dir, "public");
20711
+ const destDir = path70.join(dir, "public");
20576
20712
  await mkdir16(destDir, { recursive: true });
20577
20713
  for (const { name, content } of BRANDING_ASSETS) {
20578
- const dest = path68.join(destDir, name);
20714
+ const dest = path70.join(destDir, name);
20579
20715
  if (await fileExists2(dest)) {
20580
20716
  continue;
20581
20717
  }
20582
- await writeFile19(dest, content, "utf8");
20718
+ await writeFile20(dest, content, "utf8");
20583
20719
  }
20584
- const faviconDest = path68.join(destDir, "Icon.png");
20720
+ const faviconDest = path70.join(destDir, "Icon.png");
20585
20721
  if (!await fileExists2(faviconDest)) {
20586
- await writeFile19(faviconDest, Buffer.from(FAVICON_PNG_BASE64, "base64"));
20722
+ await writeFile20(faviconDest, Buffer.from(FAVICON_PNG_BASE64, "base64"));
20587
20723
  }
20588
20724
  }
20589
20725
  async function ensureThinConfigTsx(dir) {
20590
- const tsxPath = path68.join(dir, "apitogo.config.tsx");
20726
+ const tsxPath = path70.join(dir, "apitogo.config.tsx");
20591
20727
  if (await fileExists2(tsxPath)) {
20592
20728
  return false;
20593
20729
  }
20594
- await writeFile19(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
20730
+ await writeFile20(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
20595
20731
  return true;
20596
20732
  }
20597
20733
 
20598
20734
  // src/cli/make-config/handler.ts
20599
- var toPosixPath2 = (value) => value.split(path69.sep).join(path69.posix.sep);
20735
+ var toPosixPath2 = (value) => value.split(path71.sep).join(path71.posix.sep);
20600
20736
  var fileExists3 = async (filePath) => {
20601
20737
  try {
20602
20738
  await access12(filePath, constants2.F_OK);
@@ -20606,7 +20742,7 @@ var fileExists3 = async (filePath) => {
20606
20742
  }
20607
20743
  };
20608
20744
  var readJsonConfig = async (filePath) => {
20609
- const raw = await readFile22(filePath, "utf8");
20745
+ const raw = await readFile23(filePath, "utf8");
20610
20746
  const parsed = JSON.parse(raw);
20611
20747
  if (!isPlainObject3(parsed)) {
20612
20748
  throw new Error(`${APITOGO_JSON_FILENAME} must be a JSON object.`);
@@ -20652,13 +20788,13 @@ async function persistConfig(config2, ctx) {
20652
20788
  force: ctx.force
20653
20789
  })
20654
20790
  };
20655
- await writeFile20(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20791
+ await writeFile21(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20656
20792
  `, "utf8");
20657
- const tsxPath = path69.join(ctx.dir, "apitogo.config.tsx");
20793
+ const tsxPath = path71.join(ctx.dir, "apitogo.config.tsx");
20658
20794
  if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
20659
- const tsxSource = await readFile22(tsxPath, "utf8");
20795
+ const tsxSource = await readFile23(tsxPath, "utf8");
20660
20796
  if (isManagedConfigWrapper(tsxSource)) {
20661
- await writeFile20(
20797
+ await writeFile21(
20662
20798
  tsxPath,
20663
20799
  buildThinWrapperWithCustomPages(tsxRoutes),
20664
20800
  "utf8"
@@ -20681,7 +20817,7 @@ function mergeBackendFlag(config2, backend) {
20681
20817
  return next;
20682
20818
  }
20683
20819
  async function makeConfig(argv) {
20684
- const dir = path69.resolve(process.cwd(), argv.dir);
20820
+ const dir = path71.resolve(process.cwd(), argv.dir);
20685
20821
  const pagesDir = toPosixPath2(
20686
20822
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
20687
20823
  );
@@ -20690,7 +20826,7 @@ async function makeConfig(argv) {
20690
20826
  const changes = [];
20691
20827
  try {
20692
20828
  const discoveredOpenApi = await findOpenApiSpecPath(dir);
20693
- const createdPackageJson = await ensurePackageJson(dir);
20829
+ const createdPackageJson = await ensurePackageJson2(dir);
20694
20830
  const createdTsconfig = await ensureTsconfigJson(dir);
20695
20831
  if (createdPackageJson && !json) {
20696
20832
  printSuccessToConsole(
@@ -20701,14 +20837,14 @@ async function makeConfig(argv) {
20701
20837
  printSuccessToConsole("Created tsconfig.json.");
20702
20838
  }
20703
20839
  await ensurePortalStubFiles(dir);
20704
- const jsonPath = path69.join(dir, APITOGO_JSON_FILENAME);
20840
+ const jsonPath = path71.join(dir, APITOGO_JSON_FILENAME);
20705
20841
  let createdJson = false;
20706
20842
  let config2;
20707
20843
  if (await fileExists3(jsonPath)) {
20708
20844
  config2 = await readJsonConfig(jsonPath);
20709
20845
  } else {
20710
20846
  config2 = createDefaultApitogoJsonConfig({
20711
- title: titleFromDirectoryName(path69.basename(dir)),
20847
+ title: titleFromDirectoryName(path71.basename(dir)),
20712
20848
  pagesDir
20713
20849
  });
20714
20850
  createdJson = true;
@@ -20760,9 +20896,9 @@ async function makeConfig(argv) {
20760
20896
  return;
20761
20897
  }
20762
20898
  if (action2.kind === "page") {
20763
- const pagePath = path69.join(dir, action2.page.relativePath);
20764
- await mkdir17(path69.dirname(pagePath), { recursive: true });
20765
- await writeFile20(
20899
+ const pagePath = path71.join(dir, action2.page.relativePath);
20900
+ await mkdir17(path71.dirname(pagePath), { recursive: true });
20901
+ await writeFile21(
20766
20902
  pagePath,
20767
20903
  buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
20768
20904
  "utf8"
@@ -20828,7 +20964,7 @@ async function makeConfig(argv) {
20828
20964
  if (argv.openapi) {
20829
20965
  const wire = await wireDevPortalOpenApi(
20830
20966
  dir,
20831
- path69.resolve(dir, argv.openapi)
20967
+ path71.resolve(dir, argv.openapi)
20832
20968
  );
20833
20969
  if (wire.status !== "succeeded") {
20834
20970
  throw new Error(
@@ -20857,7 +20993,7 @@ async function makeConfig(argv) {
20857
20993
  const slug = normalizePageSlug2(argv.pageSlug);
20858
20994
  const pageTemplate = normalizePageTemplate(argv.pageTemplate);
20859
20995
  const relativePagePath = pageComponentRelativePath(slug);
20860
- const filePath = path69.join(dir, relativePagePath);
20996
+ const filePath = path71.join(dir, relativePagePath);
20861
20997
  const isUpdate = argv.pageUpdate === true;
20862
20998
  if (isUpdate) {
20863
20999
  if (!await fileExists3(filePath)) {
@@ -20871,7 +21007,7 @@ async function makeConfig(argv) {
20871
21007
  argv.pageContent,
20872
21008
  pageTemplate
20873
21009
  );
20874
- await writeFile20(filePath, tsx, "utf8");
21010
+ await writeFile21(filePath, tsx, "utf8");
20875
21011
  pageResult = {
20876
21012
  action: "updated",
20877
21013
  slug,
@@ -20890,8 +21026,8 @@ async function makeConfig(argv) {
20890
21026
  argv.pageContent,
20891
21027
  pageTemplate
20892
21028
  );
20893
- await mkdir17(path69.dirname(filePath), { recursive: true });
20894
- await writeFile20(filePath, tsx, "utf8");
21029
+ await mkdir17(path71.dirname(filePath), { recursive: true });
21030
+ await writeFile21(filePath, tsx, "utf8");
20895
21031
  const configResult = await wireNewDevPortalPageInConfig(
20896
21032
  dir,
20897
21033
  slug,
@@ -20903,7 +21039,7 @@ async function makeConfig(argv) {
20903
21039
  pagePath: relativePagePath,
20904
21040
  pageTemplate,
20905
21041
  configUpdated: configResult.updated,
20906
- configPath: configResult.configPath ? path69.relative(dir, configResult.configPath) : null
21042
+ configPath: configResult.configPath ? path71.relative(dir, configResult.configPath) : null
20907
21043
  };
20908
21044
  changes.push("page_add");
20909
21045
  }
@@ -21028,10 +21164,10 @@ var config_default = {
21028
21164
  };
21029
21165
 
21030
21166
  // src/cli/cmds/deploy.ts
21031
- import path83 from "node:path";
21167
+ import path85 from "node:path";
21032
21168
 
21033
21169
  // src/cli/apply/handler.ts
21034
- import path80 from "node:path";
21170
+ import path82 from "node:path";
21035
21171
 
21036
21172
  // src/cli/platform/helpers/gateway-plan-validation.ts
21037
21173
  init_gateway_limits();
@@ -21226,11 +21362,11 @@ init_gateway_limits();
21226
21362
  // src/cli/platform/helpers/deploy-artifact-hash.ts
21227
21363
  import { createHash as createHash3 } from "node:crypto";
21228
21364
  import { createReadStream, promises as fs8 } from "node:fs";
21229
- import path71 from "node:path";
21365
+ import path73 from "node:path";
21230
21366
 
21231
21367
  // src/cli/platform/helpers/package-files.ts
21232
21368
  import { promises as fs7 } from "node:fs";
21233
- import path70 from "node:path";
21369
+ import path72 from "node:path";
21234
21370
  import ignore from "ignore";
21235
21371
  var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
21236
21372
  "node_modules",
@@ -21243,7 +21379,7 @@ var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
21243
21379
  async function loadGitignore(rootDir) {
21244
21380
  const ig = ignore();
21245
21381
  ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
21246
- const gitignorePath = path70.join(rootDir, ".gitignore");
21382
+ const gitignorePath = path72.join(rootDir, ".gitignore");
21247
21383
  try {
21248
21384
  const content = await fs7.readFile(gitignorePath, "utf8");
21249
21385
  ig.add(content);
@@ -21252,11 +21388,11 @@ async function loadGitignore(rootDir) {
21252
21388
  return ig;
21253
21389
  }
21254
21390
  async function collectFiles(rootDir, relativeDir, ig, files) {
21255
- const absDir = path70.join(rootDir, relativeDir);
21391
+ const absDir = path72.join(rootDir, relativeDir);
21256
21392
  const entries = await fs7.readdir(absDir, { withFileTypes: true });
21257
21393
  for (const entry of entries) {
21258
- const rel2 = relativeDir ? path70.join(relativeDir, entry.name) : entry.name;
21259
- const relPosix = rel2.split(path70.sep).join("/");
21394
+ const rel2 = relativeDir ? path72.join(relativeDir, entry.name) : entry.name;
21395
+ const relPosix = rel2.split(path72.sep).join("/");
21260
21396
  if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
21261
21397
  continue;
21262
21398
  }
@@ -21271,7 +21407,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
21271
21407
  }
21272
21408
  }
21273
21409
  async function collectPackageableFiles(sourceDirectory) {
21274
- const resolved = path70.resolve(sourceDirectory);
21410
+ const resolved = path72.resolve(sourceDirectory);
21275
21411
  const stat7 = await fs7.stat(resolved).catch(() => null);
21276
21412
  if (!stat7?.isDirectory()) {
21277
21413
  throw new Error(`sourceDirectory is not a directory: ${resolved}`);
@@ -21297,7 +21433,7 @@ async function sha256File(filePath) {
21297
21433
  return hash2.digest("hex");
21298
21434
  }
21299
21435
  async function hashDirectoryContents(rootDirectory) {
21300
- const resolved = path71.resolve(rootDirectory);
21436
+ const resolved = path73.resolve(rootDirectory);
21301
21437
  const files = (await collectPackageableFiles(resolved)).sort(
21302
21438
  (a, b) => a.localeCompare(b)
21303
21439
  );
@@ -21305,13 +21441,13 @@ async function hashDirectoryContents(rootDirectory) {
21305
21441
  for (const rel2 of files) {
21306
21442
  hash2.update(rel2);
21307
21443
  hash2.update("\0");
21308
- hash2.update(await fs8.readFile(path71.join(resolved, rel2)));
21444
+ hash2.update(await fs8.readFile(path73.join(resolved, rel2)));
21309
21445
  hash2.update("\0");
21310
21446
  }
21311
21447
  return hash2.digest("hex");
21312
21448
  }
21313
21449
  async function hashDevPortalSiteSources(siteDirectory, options) {
21314
- const resolved = path71.resolve(siteDirectory);
21450
+ const resolved = path73.resolve(siteDirectory);
21315
21451
  const hash2 = createHash3("sha256");
21316
21452
  const candidates = [
21317
21453
  "apitogo.config.json",
@@ -21321,7 +21457,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
21321
21457
  "zudoku.config.tsx"
21322
21458
  ];
21323
21459
  for (const name of candidates) {
21324
- const full = path71.join(resolved, name);
21460
+ const full = path73.join(resolved, name);
21325
21461
  try {
21326
21462
  hash2.update(name);
21327
21463
  hash2.update("\0");
@@ -21331,7 +21467,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
21331
21467
  }
21332
21468
  }
21333
21469
  for (const dir of ["pages", "landing", "src"]) {
21334
- const full = path71.join(resolved, dir);
21470
+ const full = path73.join(resolved, dir);
21335
21471
  try {
21336
21472
  const st = await fs8.stat(full);
21337
21473
  if (!st.isDirectory()) continue;
@@ -21560,8 +21696,8 @@ function normalizeActionKey(actionKey2) {
21560
21696
  const trimmed = actionKey2.trim();
21561
21697
  if (trimmed.includes(":")) {
21562
21698
  const [method2, ...pathParts] = trimmed.split(":");
21563
- const path102 = pathParts.join(":").trim();
21564
- return `${method2?.toLowerCase()}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
21699
+ const path104 = pathParts.join(":").trim();
21700
+ return `${method2?.toLowerCase()}:${path104.startsWith("/") ? path104 : `/${path104}`}`;
21565
21701
  }
21566
21702
  const spaceIndex = trimmed.indexOf(" ");
21567
21703
  if (spaceIndex <= 0) {
@@ -21570,8 +21706,8 @@ function normalizeActionKey(actionKey2) {
21570
21706
  );
21571
21707
  }
21572
21708
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
21573
- const path101 = trimmed.slice(spaceIndex + 1).trim();
21574
- return `${method}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
21709
+ const path103 = trimmed.slice(spaceIndex + 1).trim();
21710
+ return `${method}:${path103.startsWith("/") ? path103 : `/${path103}`}`;
21575
21711
  }
21576
21712
  async function applyGatewayPublicRoutes(client, projectId, routes, options) {
21577
21713
  const applied = [];
@@ -22049,8 +22185,8 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
22049
22185
  }
22050
22186
 
22051
22187
  // src/cli/platform/helpers/openapi-gateway-servers.ts
22052
- import { mkdir as mkdir18, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
22053
- import path72 from "node:path";
22188
+ import { mkdir as mkdir18, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
22189
+ import path74 from "node:path";
22054
22190
  import YAML3 from "yaml";
22055
22191
  var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
22056
22192
  var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
@@ -22081,8 +22217,8 @@ async function resolveProjectGatewayUrl(client, projectId) {
22081
22217
  return null;
22082
22218
  }
22083
22219
  async function readOpenApiDocument(filePath) {
22084
- const content = await readFile23(filePath, "utf8");
22085
- const ext = path72.extname(filePath).toLowerCase();
22220
+ const content = await readFile24(filePath, "utf8");
22221
+ const ext = path74.extname(filePath).toLowerCase();
22086
22222
  const parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
22087
22223
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22088
22224
  throw new Error(`OpenAPI document must be an object: ${filePath}`);
@@ -22090,14 +22226,14 @@ async function readOpenApiDocument(filePath) {
22090
22226
  return parsed;
22091
22227
  }
22092
22228
  async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
22093
- const site = path72.resolve(siteDirectory);
22094
- const source = path72.resolve(sourceOpenApiPath);
22229
+ const site = path74.resolve(siteDirectory);
22230
+ const source = path74.resolve(sourceOpenApiPath);
22095
22231
  const relativeInput = PUBLISH_OPENAPI_RELATIVE;
22096
- const outputPath = path72.join(site, ...relativeInput.split("/"));
22232
+ const outputPath = path74.join(site, ...relativeInput.split("/"));
22097
22233
  const doc = await readOpenApiDocument(source);
22098
22234
  const rewritten = withGatewayServers(doc, gatewayUrl);
22099
- await mkdir18(path72.dirname(outputPath), { recursive: true });
22100
- await writeFile21(
22235
+ await mkdir18(path74.dirname(outputPath), { recursive: true });
22236
+ await writeFile22(
22101
22237
  outputPath,
22102
22238
  `${JSON.stringify(rewritten, null, 2)}
22103
22239
  `,
@@ -22106,11 +22242,11 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
22106
22242
  return { outputPath, relativeInput };
22107
22243
  }
22108
22244
  async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22109
- const configPath = path72.join(
22110
- path72.resolve(siteDirectory),
22245
+ const configPath = path74.join(
22246
+ path74.resolve(siteDirectory),
22111
22247
  APITOGO_CONFIG_FILENAME2
22112
22248
  );
22113
- const raw = await readFile23(configPath, "utf8");
22249
+ const raw = await readFile24(configPath, "utf8");
22114
22250
  const config2 = JSON.parse(raw);
22115
22251
  const previousApis = config2.apis;
22116
22252
  const previousBackend = config2.backend;
@@ -22123,11 +22259,11 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22123
22259
  const backend = config2.backend && typeof config2.backend === "object" ? { ...config2.backend } : {};
22124
22260
  backend.openApiPath = relativeInput;
22125
22261
  config2.backend = backend;
22126
- await writeFile21(configPath, `${JSON.stringify(config2, null, 2)}
22262
+ await writeFile22(configPath, `${JSON.stringify(config2, null, 2)}
22127
22263
  `, "utf8");
22128
22264
  return {
22129
22265
  restore: async () => {
22130
- const currentRaw = await readFile23(configPath, "utf8");
22266
+ const currentRaw = await readFile24(configPath, "utf8");
22131
22267
  const current = JSON.parse(currentRaw);
22132
22268
  if (previousApis === void 0) {
22133
22269
  delete current.apis;
@@ -22139,7 +22275,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22139
22275
  } else {
22140
22276
  current.backend = previousBackend;
22141
22277
  }
22142
- await writeFile21(
22278
+ await writeFile22(
22143
22279
  configPath,
22144
22280
  `${JSON.stringify(current, null, 2)}
22145
22281
  `,
@@ -22149,7 +22285,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22149
22285
  };
22150
22286
  }
22151
22287
  async function prepareOpenApiServersForGatewayBuild(options) {
22152
- const siteDirectory = path72.resolve(options.siteDirectory);
22288
+ const siteDirectory = path74.resolve(options.siteDirectory);
22153
22289
  let openApiPath = resolveBackendOpenApiPath(
22154
22290
  options.manifest?.backend?.openApiPath,
22155
22291
  {
@@ -22162,8 +22298,8 @@ async function prepareOpenApiServersForGatewayBuild(options) {
22162
22298
  );
22163
22299
  if (!openApiPath) {
22164
22300
  try {
22165
- const raw = await readFile23(
22166
- path72.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
22301
+ const raw = await readFile24(
22302
+ path74.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
22167
22303
  "utf8"
22168
22304
  );
22169
22305
  const config2 = JSON.parse(raw);
@@ -22192,8 +22328,8 @@ function normalizeActionKeyFormat(actionKey2) {
22192
22328
  const trimmed = actionKey2.trim();
22193
22329
  if (trimmed.includes(":")) {
22194
22330
  const [method2, ...pathParts] = trimmed.split(":");
22195
- const path102 = pathParts.join(":").trim();
22196
- return `${method2.toLowerCase()}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
22331
+ const path104 = pathParts.join(":").trim();
22332
+ return `${method2.toLowerCase()}:${path104.startsWith("/") ? path104 : `/${path104}`}`;
22197
22333
  }
22198
22334
  const spaceIndex = trimmed.indexOf(" ");
22199
22335
  if (spaceIndex <= 0) {
@@ -22202,8 +22338,8 @@ function normalizeActionKeyFormat(actionKey2) {
22202
22338
  );
22203
22339
  }
22204
22340
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
22205
- const path101 = trimmed.slice(spaceIndex + 1).trim();
22206
- return `${method}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
22341
+ const path103 = trimmed.slice(spaceIndex + 1).trim();
22342
+ return `${method}:${path103.startsWith("/") ? path103 : `/${path103}`}`;
22207
22343
  }
22208
22344
  function normalizePublicRoute(route) {
22209
22345
  const trimmed = route.trim();
@@ -22236,16 +22372,16 @@ function collectManifestPublicActionKeys(gateway) {
22236
22372
  }
22237
22373
 
22238
22374
  // src/cli/platform/helpers/publish-ledger.ts
22239
- import { mkdir as mkdir19, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
22240
- import path73 from "node:path";
22375
+ import { mkdir as mkdir19, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
22376
+ import path75 from "node:path";
22241
22377
  var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
22242
22378
  function publishLedgerPath(siteDirectory) {
22243
- return path73.join(path73.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
22379
+ return path75.join(path75.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
22244
22380
  }
22245
22381
  async function readPublishLedger(siteDirectory) {
22246
22382
  const filePath = publishLedgerPath(siteDirectory);
22247
22383
  try {
22248
- const raw = await readFile24(filePath, "utf8");
22384
+ const raw = await readFile25(filePath, "utf8");
22249
22385
  const parsed = JSON.parse(raw);
22250
22386
  if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
22251
22387
  return null;
@@ -22257,13 +22393,13 @@ async function readPublishLedger(siteDirectory) {
22257
22393
  }
22258
22394
  async function writePublishLedger(siteDirectory, ledger) {
22259
22395
  const filePath = publishLedgerPath(siteDirectory);
22260
- await mkdir19(path73.dirname(filePath), { recursive: true });
22396
+ await mkdir19(path75.dirname(filePath), { recursive: true });
22261
22397
  const next = {
22262
22398
  ...ledger,
22263
22399
  version: 1,
22264
22400
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22265
22401
  };
22266
- await writeFile22(filePath, `${JSON.stringify(next, null, 2)}
22402
+ await writeFile23(filePath, `${JSON.stringify(next, null, 2)}
22267
22403
  `, "utf8");
22268
22404
  return filePath;
22269
22405
  }
@@ -22779,9 +22915,9 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
22779
22915
  import { spawn as spawn4 } from "node:child_process";
22780
22916
  import { mkdtemp, readdir as readdir2, rm as rm11 } from "node:fs/promises";
22781
22917
  import { tmpdir } from "node:os";
22782
- import path74 from "node:path";
22918
+ import path76 from "node:path";
22783
22919
  async function directoryHasRuntimeConfig(dir) {
22784
- if (!await pathExists(dir)) {
22920
+ if (!await pathExists2(dir)) {
22785
22921
  return false;
22786
22922
  }
22787
22923
  const entries = await readdir2(dir);
@@ -22822,20 +22958,20 @@ function runDotnetPublish(projectDir, outputDir) {
22822
22958
  async function findCsproj(projectDir) {
22823
22959
  const entries = await readdir2(projectDir);
22824
22960
  const csproj = entries.find((name) => name.endsWith(".csproj"));
22825
- return csproj ? path74.join(projectDir, csproj) : null;
22961
+ return csproj ? path76.join(projectDir, csproj) : null;
22826
22962
  }
22827
22963
  async function prepareBackendPackagingDirectory(args) {
22828
- const sourceDirectory = path74.resolve(args.sourceDirectory);
22964
+ const sourceDirectory = path76.resolve(args.sourceDirectory);
22829
22965
  if (args.publishDirectory?.trim()) {
22830
22966
  return {
22831
- directory: path74.resolve(args.publishDirectory),
22967
+ directory: path76.resolve(args.publishDirectory),
22832
22968
  packagingMode: "published"
22833
22969
  };
22834
22970
  }
22835
22971
  if (await directoryHasRuntimeConfig(sourceDirectory)) {
22836
22972
  return { directory: sourceDirectory, packagingMode: "published" };
22837
22973
  }
22838
- const publishSubdir = path74.join(sourceDirectory, "publish");
22974
+ const publishSubdir = path76.join(sourceDirectory, "publish");
22839
22975
  if (await directoryHasRuntimeConfig(publishSubdir)) {
22840
22976
  return { directory: publishSubdir, packagingMode: "published" };
22841
22977
  }
@@ -22847,9 +22983,9 @@ async function prepareBackendPackagingDirectory(args) {
22847
22983
  return { directory: sourceDirectory, packagingMode: "source" };
22848
22984
  }
22849
22985
  const tempRoot = await mkdtemp(
22850
- path74.join(tmpdir(), "apitogo-dotnet-publish-")
22986
+ path76.join(tmpdir(), "apitogo-dotnet-publish-")
22851
22987
  );
22852
- const outputDir = path74.join(tempRoot, "publish");
22988
+ const outputDir = path76.join(tempRoot, "publish");
22853
22989
  const result = await runDotnetPublish(sourceDirectory, outputDir);
22854
22990
  if (result.exitCode !== 0) {
22855
22991
  await rm11(tempRoot, { recursive: true, force: true });
@@ -22895,12 +23031,12 @@ function formatJobStatusResponse(options) {
22895
23031
  // src/cli/platform/helpers/zip.ts
22896
23032
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs9 } from "node:fs";
22897
23033
  import { tmpdir as tmpdir2 } from "node:os";
22898
- import path75 from "node:path";
23034
+ import path77 from "node:path";
22899
23035
  import { ZipArchive } from "archiver";
22900
23036
  async function packageBackendDirectory(sourceDirectory) {
22901
- const resolved = path75.resolve(sourceDirectory);
23037
+ const resolved = path77.resolve(sourceDirectory);
22902
23038
  const files = await collectPackageableFiles(resolved);
22903
- const zipPath = path75.join(
23039
+ const zipPath = path77.join(
22904
23040
  tmpdir2(),
22905
23041
  `apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
22906
23042
  );
@@ -22912,8 +23048,8 @@ async function packageBackendDirectory(sourceDirectory) {
22912
23048
  output4.on("error", reject);
22913
23049
  archive.pipe(output4);
22914
23050
  for (const rel2 of files) {
22915
- archive.append(createReadStream2(path75.join(resolved, rel2)), {
22916
- name: rel2.split(path75.sep).join("/")
23051
+ archive.append(createReadStream2(path77.join(resolved, rel2)), {
23052
+ name: rel2.split(path77.sep).join("/")
22917
23053
  });
22918
23054
  }
22919
23055
  void archive.finalize();
@@ -24414,11 +24550,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
24414
24550
  }
24415
24551
 
24416
24552
  // src/cli/platform/tools/dev-portal-site-build.ts
24417
- import path79 from "node:path";
24553
+ import path81 from "node:path";
24418
24554
 
24419
24555
  // src/cli/platform/helpers/dev-portal-site-api-url.ts
24420
- import { readdir as readdir3, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
24421
- import path76 from "node:path";
24556
+ import { readdir as readdir3, readFile as readFile26, writeFile as writeFile24 } from "node:fs/promises";
24557
+ import path78 from "node:path";
24422
24558
  var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
24423
24559
  var PLACEHOLDER_HOST_MARKERS = [
24424
24560
  "dp-example.azurecontainerapps.io",
@@ -24439,10 +24575,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
24439
24575
  return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
24440
24576
  }
24441
24577
  async function readSiteApiBaseUrl(sourceDirectory) {
24442
- const resolved = path76.resolve(sourceDirectory);
24578
+ const resolved = path78.resolve(sourceDirectory);
24443
24579
  for (const envFile of [".env", ".env.production"]) {
24444
24580
  try {
24445
- const content = await readFile25(path76.join(resolved, envFile), "utf8");
24581
+ const content = await readFile26(path78.join(resolved, envFile), "utf8");
24446
24582
  const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
24447
24583
  if (lines.length === 0) {
24448
24584
  continue;
@@ -24467,25 +24603,25 @@ async function readSiteApiBaseUrl(sourceDirectory) {
24467
24603
  return null;
24468
24604
  }
24469
24605
  async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
24470
- const resolved = path76.resolve(sourceDirectory);
24606
+ const resolved = path78.resolve(sourceDirectory);
24471
24607
  const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
24472
24608
  let patchedExisting = false;
24473
24609
  for (const envFile of [".env.production", ".env"]) {
24474
- const envPath = path76.join(resolved, envFile);
24610
+ const envPath = path78.join(resolved, envFile);
24475
24611
  try {
24476
- const content = await readFile25(envPath, "utf8");
24612
+ const content = await readFile26(envPath, "utf8");
24477
24613
  const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
24478
24614
  const patched = withoutAssignments ? `${withoutAssignments}
24479
24615
  ${line2}
24480
24616
  ` : `${line2}
24481
24617
  `;
24482
- await writeFile23(envPath, patched);
24618
+ await writeFile24(envPath, patched);
24483
24619
  patchedExisting = true;
24484
24620
  } catch {
24485
24621
  }
24486
24622
  }
24487
24623
  if (!patchedExisting) {
24488
- await writeFile23(path76.join(resolved, ".env"), `${line2}
24624
+ await writeFile24(path78.join(resolved, ".env"), `${line2}
24489
24625
  `);
24490
24626
  }
24491
24627
  }
@@ -24493,7 +24629,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
24493
24629
  return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
24494
24630
  }
24495
24631
  async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
24496
- const sourceDirectory = path76.resolve(args.sourceDirectory);
24632
+ const sourceDirectory = path78.resolve(args.sourceDirectory);
24497
24633
  const explicit = args.apiBaseUrl?.trim();
24498
24634
  if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
24499
24635
  await patchSiteApiBaseUrl(sourceDirectory, explicit);
@@ -24529,7 +24665,7 @@ async function* walkFiles(root) {
24529
24665
  return;
24530
24666
  }
24531
24667
  for (const entry of entries) {
24532
- const full = path76.join(root, entry.name);
24668
+ const full = path78.join(root, entry.name);
24533
24669
  if (entry.isDirectory()) {
24534
24670
  if (entry.name === "node_modules" || entry.name === ".git") {
24535
24671
  continue;
@@ -24541,8 +24677,8 @@ async function* walkFiles(root) {
24541
24677
  }
24542
24678
  }
24543
24679
  async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
24544
- const dist = path76.resolve(distDirectory);
24545
- const siteRoot = path76.dirname(dist);
24680
+ const dist = path78.resolve(distDirectory);
24681
+ const siteRoot = path78.dirname(dist);
24546
24682
  const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
24547
24683
  if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
24548
24684
  throw new Error(
@@ -24553,7 +24689,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
24553
24689
  let found = false;
24554
24690
  let foundPlaceholder = false;
24555
24691
  for await (const file of walkFiles(dist)) {
24556
- const content = await readFile25(file, "utf8");
24692
+ const content = await readFile26(file, "utf8");
24557
24693
  if (content.includes(needle)) {
24558
24694
  found = true;
24559
24695
  }
@@ -24578,7 +24714,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
24578
24714
 
24579
24715
  // src/cli/platform/tools/dev-portal.ts
24580
24716
  import { promises as fs11 } from "node:fs";
24581
- import path78 from "node:path";
24717
+ import path80 from "node:path";
24582
24718
 
24583
24719
  // src/cli/platform/helpers/dev-portal-backend-job.ts
24584
24720
  var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
@@ -24688,7 +24824,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
24688
24824
  // src/cli/platform/helpers/tarball.ts
24689
24825
  import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs10 } from "node:fs";
24690
24826
  import { tmpdir as tmpdir3 } from "node:os";
24691
- import path77 from "node:path";
24827
+ import path79 from "node:path";
24692
24828
  import { TarArchive } from "archiver";
24693
24829
  var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
24694
24830
  function normalizeArchiveRoot(archiveRoot) {
@@ -24699,10 +24835,10 @@ function normalizeArchiveRoot(archiveRoot) {
24699
24835
  return `${trimmed}/`;
24700
24836
  }
24701
24837
  async function packageDirectoryAsTarGz(sourceDirectory, options) {
24702
- const resolved = path77.resolve(sourceDirectory);
24838
+ const resolved = path79.resolve(sourceDirectory);
24703
24839
  const files = await collectPackageableFiles(resolved);
24704
24840
  const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
24705
- const archivePath = path77.join(
24841
+ const archivePath = path79.join(
24706
24842
  tmpdir3(),
24707
24843
  `apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
24708
24844
  );
@@ -24714,8 +24850,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
24714
24850
  output4.on("error", reject);
24715
24851
  archive.pipe(output4);
24716
24852
  for (const rel2 of files) {
24717
- const entryName = entryPrefix + rel2.split(path77.sep).join("/");
24718
- archive.append(createReadStream3(path77.join(resolved, rel2)), {
24853
+ const entryName = entryPrefix + rel2.split(path79.sep).join("/");
24854
+ archive.append(createReadStream3(path79.join(resolved, rel2)), {
24719
24855
  name: entryName
24720
24856
  });
24721
24857
  }
@@ -24957,7 +25093,7 @@ function validateDeployArchiveInput(args) {
24957
25093
  async function resolveDevPortalArchive(args) {
24958
25094
  validateDeployArchiveInput(args);
24959
25095
  if (args.archivePath?.trim()) {
24960
- const archivePath = path78.resolve(args.archivePath.trim());
25096
+ const archivePath = path80.resolve(args.archivePath.trim());
24961
25097
  const stat7 = await fs11.stat(archivePath).catch(() => null);
24962
25098
  if (!stat7?.isFile()) {
24963
25099
  throw new Error(`archivePath is not a file: ${archivePath}`);
@@ -25022,7 +25158,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
25022
25158
  // src/cli/platform/tools/dev-portal-site-build.ts
25023
25159
  async function handleBuildDevPortalSite(client, config2, args, progress) {
25024
25160
  const buildProgress = progress?.child("Build dev portal site");
25025
- const sourceDirectory = path79.resolve(args.sourceDirectory);
25161
+ const sourceDirectory = path81.resolve(args.sourceDirectory);
25026
25162
  await buildProgress?.onStep("Ensuring live portal API URL");
25027
25163
  const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
25028
25164
  client,
@@ -26518,7 +26654,7 @@ function resultLooksFailed(payload) {
26518
26654
  return parsed.status === "failed" || parsed.status === "blocked";
26519
26655
  }
26520
26656
  async function apply(argv) {
26521
- const sourceDirectory = path80.resolve(process.cwd(), argv.dir);
26657
+ const sourceDirectory = path82.resolve(process.cwd(), argv.dir);
26522
26658
  let config2;
26523
26659
  try {
26524
26660
  config2 = loadConfig();
@@ -26588,7 +26724,7 @@ async function apply(argv) {
26588
26724
  if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
26589
26725
  const resolution = await resolveProjectNotFoundInteractively(
26590
26726
  parsed,
26591
- path80.basename(sourceDirectory)
26727
+ path82.basename(sourceDirectory)
26592
26728
  );
26593
26729
  if (resolution) {
26594
26730
  effectiveProjectId = void 0;
@@ -26608,7 +26744,7 @@ async function apply(argv) {
26608
26744
  while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
26609
26745
  const resolution = await resolveProjectNameExistsInteractively(
26610
26746
  parsed,
26611
- effectiveProjectName ?? path80.basename(sourceDirectory)
26747
+ effectiveProjectName ?? path82.basename(sourceDirectory)
26612
26748
  );
26613
26749
  if (!resolution) {
26614
26750
  break;
@@ -26680,7 +26816,7 @@ async function apply(argv) {
26680
26816
 
26681
26817
  // src/cli/deploy/command.ts
26682
26818
  init_invariant();
26683
- import path82 from "node:path";
26819
+ import path84 from "node:path";
26684
26820
 
26685
26821
  // src/cli/deploy/v2.ts
26686
26822
  import { rm as rm12 } from "node:fs/promises";
@@ -26688,11 +26824,11 @@ init_invariant();
26688
26824
 
26689
26825
  // src/cli/portal/report.ts
26690
26826
  import { access as access13 } from "node:fs/promises";
26691
- import path81 from "node:path";
26827
+ import path83 from "node:path";
26692
26828
 
26693
26829
  // src/cli/deploy/gateway.ts
26694
26830
  import { createHash as createHash4 } from "node:crypto";
26695
- import { readFile as readFile26 } from "node:fs/promises";
26831
+ import { readFile as readFile27 } from "node:fs/promises";
26696
26832
  init_invariant();
26697
26833
  var GatewayDeployError = class extends ApitogoError {
26698
26834
  constructor(code, message, developerHint) {
@@ -26732,7 +26868,7 @@ async function readSpec(gateway) {
26732
26868
  "Add one to gateway.specs in the config."
26733
26869
  );
26734
26870
  try {
26735
- return await readFile26(file);
26871
+ return await readFile27(file);
26736
26872
  } catch {
26737
26873
  throw new GatewayDeployError(
26738
26874
  "GATEWAY_SPEC_UNREADABLE",
@@ -26967,7 +27103,7 @@ async function planPortalService(resolved, ledger) {
26967
27103
  const hash2 = await portalBuildHash(resolved, prepared);
26968
27104
  const previous = stepOf(ledger, "portal", "build");
26969
27105
  const built = await exists4(
26970
- path81.join(resolved.state.buildDir, "index.html")
27106
+ path83.join(resolved.state.buildDir, "index.html")
26971
27107
  );
26972
27108
  if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
26973
27109
  return {
@@ -27274,7 +27410,7 @@ async function statusV2(dir, only, options = {}) {
27274
27410
  if (service === "portal") {
27275
27411
  const build2 = stepOf(ledger, "portal", "build");
27276
27412
  const built = await exists4(
27277
- path81.join(resolved.state.buildDir, "index.html")
27413
+ path83.join(resolved.state.buildDir, "index.html")
27278
27414
  );
27279
27415
  const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
27280
27416
  services.push({
@@ -27285,7 +27421,7 @@ async function statusV2(dir, only, options = {}) {
27285
27421
  ...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
27286
27422
  ...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
27287
27423
  ...state === "built" ? [
27288
- `output: ${path81.relative(resolved.configDir, resolved.state.buildDir)}`
27424
+ `output: ${path83.relative(resolved.configDir, resolved.state.buildDir)}`
27289
27425
  ] : [],
27290
27426
  ...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"]
27291
27427
  ]
@@ -27553,7 +27689,7 @@ async function deployProject(argv) {
27553
27689
  const config2 = loadConfig();
27554
27690
  const output4 = await deployV2(
27555
27691
  {
27556
- dir: path82.resolve(process.cwd(), argv.dir),
27692
+ dir: path84.resolve(process.cwd(), argv.dir),
27557
27693
  only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
27558
27694
  projectId: argv.projectId,
27559
27695
  env: argv.env,
@@ -27634,7 +27770,7 @@ var deploy_default = {
27634
27770
  }),
27635
27771
  handler: async (argv) => {
27636
27772
  await captureEvent({ argv, event: "apitogo deploy" });
27637
- if (await isConfigV2(path83.resolve(process.cwd(), argv.dir))) {
27773
+ if (await isConfigV2(path85.resolve(process.cwd(), argv.dir))) {
27638
27774
  await deployProject(argv);
27639
27775
  return;
27640
27776
  }
@@ -27643,8 +27779,8 @@ var deploy_default = {
27643
27779
  };
27644
27780
 
27645
27781
  // src/cli/export/handler.ts
27646
- import { mkdir as mkdir20, writeFile as writeFile24 } from "node:fs/promises";
27647
- import path84 from "node:path";
27782
+ import { mkdir as mkdir20, writeFile as writeFile25 } from "node:fs/promises";
27783
+ import path86 from "node:path";
27648
27784
  init_invariant();
27649
27785
  var ExportError = class extends ApitogoError {
27650
27786
  constructor(message, developerHint) {
@@ -27658,7 +27794,7 @@ async function exportOpenApi(args, deps) {
27658
27794
  `Cannot export "${args.target}".`,
27659
27795
  "Only `apitogo export openapi` exists."
27660
27796
  );
27661
- const dir = path84.resolve(process.cwd(), args.dir ?? ".");
27797
+ const dir = path86.resolve(process.cwd(), args.dir ?? ".");
27662
27798
  if (!await isConfigV2(dir))
27663
27799
  throw new ExportError(
27664
27800
  "This command needs a config version 2 project.",
@@ -27683,9 +27819,9 @@ async function exportOpenApi(args, deps) {
27683
27819
  throw error;
27684
27820
  }
27685
27821
  if (!args.out) return { text };
27686
- const file = path84.resolve(process.cwd(), args.out);
27687
- await mkdir20(path84.dirname(file), { recursive: true });
27688
- await writeFile24(file, text);
27822
+ const file = path86.resolve(process.cwd(), args.out);
27823
+ await mkdir20(path86.dirname(file), { recursive: true });
27824
+ await writeFile25(file, text);
27689
27825
  return { text, file };
27690
27826
  }
27691
27827
  async function exportCommand(args) {
@@ -27735,15 +27871,15 @@ var export_default = {
27735
27871
  };
27736
27872
 
27737
27873
  // src/cli/init/handler.ts
27738
- import path88 from "node:path";
27874
+ import path90 from "node:path";
27739
27875
 
27740
27876
  // src/cli/scaffold/run-scaffold-discovery.ts
27741
- import { access as access15, readFile as readFile29, writeFile as writeFile26 } from "node:fs/promises";
27742
- import path87 from "node:path";
27877
+ import { access as access15, readFile as readFile30, writeFile as writeFile27 } from "node:fs/promises";
27878
+ import path89 from "node:path";
27743
27879
 
27744
27880
  // src/cli/scaffold/detect-backend.ts
27745
- import { readdir as readdir4, readFile as readFile27 } from "node:fs/promises";
27746
- import path85 from "node:path";
27881
+ import { readdir as readdir4, readFile as readFile28 } from "node:fs/promises";
27882
+ import path87 from "node:path";
27747
27883
  var DEFAULT_RUNTIME_VERSION = {
27748
27884
  dotnet: "DOTNET_10",
27749
27885
  nodejs: "NODE_22_LTS",
@@ -27760,7 +27896,7 @@ async function listFiles(directory) {
27760
27896
  }
27761
27897
  async function readText(filePath) {
27762
27898
  try {
27763
- return await readFile27(filePath, "utf8");
27899
+ return await readFile28(filePath, "utf8");
27764
27900
  } catch {
27765
27901
  return void 0;
27766
27902
  }
@@ -27789,15 +27925,15 @@ function isRunnableNodePackage(pkg) {
27789
27925
  return typeof scripts.start === "string" || typeof pkg.main === "string";
27790
27926
  }
27791
27927
  async function detectParentBackend(siteDirectory) {
27792
- const site = path85.resolve(siteDirectory);
27793
- const directory = path85.dirname(site);
27928
+ const site = path87.resolve(siteDirectory);
27929
+ const directory = path87.dirname(site);
27794
27930
  if (directory === site) {
27795
27931
  return void 0;
27796
27932
  }
27797
27933
  const files = await listFiles(directory);
27798
27934
  const toResult = (runtime, runtimeVersion, marker) => ({
27799
27935
  directory,
27800
- sourceDirectory: path85.relative(site, directory).split(path85.sep).join("/") || ".",
27936
+ sourceDirectory: path87.relative(site, directory).split(path87.sep).join("/") || ".",
27801
27937
  runtime,
27802
27938
  runtimeVersion,
27803
27939
  marker
@@ -27805,7 +27941,7 @@ async function detectParentBackend(siteDirectory) {
27805
27941
  const csproj = files.find((f) => f.endsWith(".csproj"));
27806
27942
  const solution = files.find((f) => /\.slnx?$/.test(f));
27807
27943
  if (csproj || solution) {
27808
- const content = csproj ? await readText(path85.join(directory, csproj)) : void 0;
27944
+ const content = csproj ? await readText(path87.join(directory, csproj)) : void 0;
27809
27945
  return toResult(
27810
27946
  "dotnet",
27811
27947
  dotnetVersionFromCsproj(content),
@@ -27813,7 +27949,7 @@ async function detectParentBackend(siteDirectory) {
27813
27949
  );
27814
27950
  }
27815
27951
  if (files.includes("package.json")) {
27816
- const raw = await readText(path85.join(directory, "package.json"));
27952
+ const raw = await readText(path87.join(directory, "package.json"));
27817
27953
  try {
27818
27954
  const pkg = JSON.parse(raw ?? "");
27819
27955
  if (isRunnableNodePackage(pkg)) {
@@ -27828,7 +27964,7 @@ async function detectParentBackend(siteDirectory) {
27828
27964
  }
27829
27965
  const pythonMarker = PYTHON_MARKERS.find((m) => files.includes(m));
27830
27966
  if (pythonMarker) {
27831
- const versionSource = await readText(path85.join(directory, ".python-version")) ?? (pythonMarker === "pyproject.toml" ? (await readText(path85.join(directory, pythonMarker)))?.match(
27967
+ const versionSource = await readText(path87.join(directory, ".python-version")) ?? (pythonMarker === "pyproject.toml" ? (await readText(path87.join(directory, pythonMarker)))?.match(
27832
27968
  /requires-python\s*=\s*"([^"]+)"/
27833
27969
  )?.[1] : void 0);
27834
27970
  return toResult(
@@ -27846,12 +27982,12 @@ import {
27846
27982
  lstat as lstat2,
27847
27983
  mkdir as mkdir21,
27848
27984
  readdir as readdir5,
27849
- readFile as readFile28,
27985
+ readFile as readFile29,
27850
27986
  readlink,
27851
27987
  symlink as symlink2,
27852
- writeFile as writeFile25
27988
+ writeFile as writeFile26
27853
27989
  } from "node:fs/promises";
27854
- import path86 from "node:path";
27990
+ import path88 from "node:path";
27855
27991
  var DOCS_DIR_WHITELIST = [
27856
27992
  "docs",
27857
27993
  "documents",
@@ -27888,14 +28024,14 @@ async function isDirectory2(filePath) {
27888
28024
  }
27889
28025
  }
27890
28026
  function toPosix3(value) {
27891
- return value.split(path86.sep).join(path86.posix.sep);
28027
+ return value.split(path88.sep).join(path88.posix.sep);
27892
28028
  }
27893
28029
  function isWhitelistedDirName(name) {
27894
28030
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
27895
28031
  }
27896
28032
  function isInside2(parent, child) {
27897
- const relative = path86.relative(parent, child);
27898
- return relative === "" || !relative.startsWith("..") && !path86.isAbsolute(relative);
28033
+ const relative = path88.relative(parent, child);
28034
+ return relative === "" || !relative.startsWith("..") && !path88.isAbsolute(relative);
27899
28035
  }
27900
28036
  async function collectMarkdownFiles(dir, excludeDir) {
27901
28037
  const files = [];
@@ -27909,9 +28045,9 @@ async function collectMarkdownFiles(dir, excludeDir) {
27909
28045
  if (entry.name.startsWith(".")) {
27910
28046
  continue;
27911
28047
  }
27912
- const full = path86.join(dir, entry.name);
28048
+ const full = path88.join(dir, entry.name);
27913
28049
  if (entry.isDirectory()) {
27914
- if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path86.resolve(full) === excludeDir) {
28050
+ if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path88.resolve(full) === excludeDir) {
27915
28051
  continue;
27916
28052
  }
27917
28053
  files.push(...await collectMarkdownFiles(full, excludeDir));
@@ -27924,11 +28060,11 @@ async function collectMarkdownFiles(dir, excludeDir) {
27924
28060
  return files;
27925
28061
  }
27926
28062
  async function collectSearchRoots(siteDirectory) {
27927
- const site = path86.resolve(siteDirectory);
27928
- const parent = path86.dirname(site);
28063
+ const site = path88.resolve(siteDirectory);
28064
+ const parent = path88.dirname(site);
27929
28065
  const roots = [];
27930
28066
  const add = (dir) => {
27931
- const resolved = path86.resolve(dir);
28067
+ const resolved = path88.resolve(dir);
27932
28068
  if (!roots.includes(resolved)) {
27933
28069
  roots.push(resolved);
27934
28070
  }
@@ -27941,7 +28077,7 @@ async function collectSearchRoots(siteDirectory) {
27941
28077
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
27942
28078
  continue;
27943
28079
  }
27944
- add(path86.join(parent, entry.name));
28080
+ add(path88.join(parent, entry.name));
27945
28081
  }
27946
28082
  } catch {
27947
28083
  }
@@ -27950,13 +28086,13 @@ async function collectSearchRoots(siteDirectory) {
27950
28086
  return roots;
27951
28087
  }
27952
28088
  async function discoverNearbyDocsDirectories(siteDirectory) {
27953
- const site = path86.resolve(siteDirectory);
27954
- const sitePages = path86.join(site, PAGES_DIR);
28089
+ const site = path88.resolve(siteDirectory);
28090
+ const sitePages = path88.join(site, PAGES_DIR);
27955
28091
  const searchedDirectories = await collectSearchRoots(site);
27956
28092
  const directories = [];
27957
28093
  const seen = /* @__PURE__ */ new Set();
27958
28094
  const consider = async (dir) => {
27959
- const resolved = path86.resolve(dir);
28095
+ const resolved = path88.resolve(dir);
27960
28096
  if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
27961
28097
  return;
27962
28098
  }
@@ -27973,7 +28109,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
27973
28109
  directories.push({ sourceDirectory: resolved, files });
27974
28110
  };
27975
28111
  for (const root of searchedDirectories) {
27976
- if (isWhitelistedDirName(path86.basename(root))) {
28112
+ if (isWhitelistedDirName(path88.basename(root))) {
27977
28113
  await consider(root);
27978
28114
  }
27979
28115
  try {
@@ -27985,7 +28121,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
27985
28121
  if (!isWhitelistedDirName(entry.name)) {
27986
28122
  continue;
27987
28123
  }
27988
- await consider(path86.join(root, entry.name));
28124
+ await consider(path88.join(root, entry.name));
27989
28125
  }
27990
28126
  } catch {
27991
28127
  }
@@ -28004,8 +28140,8 @@ function slugifyDirName(name) {
28004
28140
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
28005
28141
  }
28006
28142
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
28007
- const base = slugifyDirName(path86.basename(sourceDirectory));
28008
- const parent = slugifyDirName(path86.basename(path86.dirname(sourceDirectory)));
28143
+ const base = slugifyDirName(path88.basename(sourceDirectory));
28144
+ const parent = slugifyDirName(path88.basename(path88.dirname(sourceDirectory)));
28009
28145
  const candidates = [base, `${parent}-${base}`];
28010
28146
  let index = 2;
28011
28147
  while (true) {
@@ -28013,7 +28149,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
28013
28149
  if (used.has(name)) {
28014
28150
  continue;
28015
28151
  }
28016
- const target = path86.join(pagesDir, name);
28152
+ const target = path88.join(pagesDir, name);
28017
28153
  if (await pathExists5(target)) {
28018
28154
  const stat7 = await lstat2(target);
28019
28155
  if (!stat7.isDirectory() || !await isManagedLinkDir(target)) {
@@ -28044,8 +28180,8 @@ async function alreadyLinked(linkPath, sourcePath) {
28044
28180
  return false;
28045
28181
  }
28046
28182
  const current = await readlink(linkPath);
28047
- const resolved = path86.resolve(path86.dirname(linkPath), current);
28048
- return resolved === path86.resolve(sourcePath);
28183
+ const resolved = path88.resolve(path88.dirname(linkPath), current);
28184
+ return resolved === path88.resolve(sourcePath);
28049
28185
  } catch {
28050
28186
  return false;
28051
28187
  }
@@ -28057,8 +28193,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
28057
28193
  if (await pathExists5(linkPath)) {
28058
28194
  return "skipped";
28059
28195
  }
28060
- await mkdir21(path86.dirname(linkPath), { recursive: true });
28061
- const relativeTarget = path86.relative(path86.dirname(linkPath), sourcePath);
28196
+ await mkdir21(path88.dirname(linkPath), { recursive: true });
28197
+ const relativeTarget = path88.relative(path88.dirname(linkPath), sourcePath);
28062
28198
  await symlink2(
28063
28199
  relativeTarget,
28064
28200
  linkPath,
@@ -28073,11 +28209,11 @@ async function applyDocsNavigation(siteDirectory, routes) {
28073
28209
  if (routes.length === 0) {
28074
28210
  return;
28075
28211
  }
28076
- const configPath = path86.join(siteDirectory, CONFIG_FILENAME);
28212
+ const configPath = path88.join(siteDirectory, CONFIG_FILENAME);
28077
28213
  if (!await pathExists5(configPath)) {
28078
28214
  return;
28079
28215
  }
28080
- const raw = await readFile28(configPath, "utf8");
28216
+ const raw = await readFile29(configPath, "utf8");
28081
28217
  const parsed = JSON.parse(raw);
28082
28218
  if (!isPlainObject5(parsed)) {
28083
28219
  return;
@@ -28086,12 +28222,12 @@ async function applyDocsNavigation(siteDirectory, routes) {
28086
28222
  force: false
28087
28223
  });
28088
28224
  const updated = ensureHeaderDocsNavigation(parsed, routes);
28089
- await writeFile25(configPath, `${JSON.stringify(updated, null, 2)}
28225
+ await writeFile26(configPath, `${JSON.stringify(updated, null, 2)}
28090
28226
  `, "utf8");
28091
28227
  }
28092
28228
  async function discoverAndWireDocs(siteDirectory) {
28093
- const site = path86.resolve(siteDirectory);
28094
- const pagesDir = path86.join(site, PAGES_DIR);
28229
+ const site = path88.resolve(siteDirectory);
28230
+ const pagesDir = path88.join(site, PAGES_DIR);
28095
28231
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
28096
28232
  if (directories.length === 0) {
28097
28233
  return {
@@ -28113,15 +28249,15 @@ async function discoverAndWireDocs(siteDirectory) {
28113
28249
  directory.sourceDirectory,
28114
28250
  usedNames
28115
28251
  );
28116
- const linkDirectory = path86.join(pagesDir, linkName);
28252
+ const linkDirectory = path88.join(pagesDir, linkName);
28117
28253
  const linked = [];
28118
28254
  const skipped = [];
28119
28255
  for (const sourcePath of directory.files) {
28120
28256
  const relativeSource = toPosix3(
28121
- path86.relative(directory.sourceDirectory, sourcePath)
28257
+ path88.relative(directory.sourceDirectory, sourcePath)
28122
28258
  );
28123
- const linkPath = path86.join(linkDirectory, relativeSource);
28124
- const relativeLink = toPosix3(path86.relative(site, linkPath));
28259
+ const linkPath = path88.join(linkDirectory, relativeSource);
28260
+ const relativeLink = toPosix3(path88.relative(site, linkPath));
28125
28261
  const route = toRoutePath(relativeLink, PAGES_DIR);
28126
28262
  if (routes.includes(route)) {
28127
28263
  skipped.push({
@@ -28169,11 +28305,11 @@ async function discoverAndWireDocs(siteDirectory) {
28169
28305
  };
28170
28306
  }
28171
28307
  function siteRelative(siteDirectory, filePath) {
28172
- const relative = toPosix3(path86.relative(siteDirectory, filePath));
28308
+ const relative = toPosix3(path88.relative(siteDirectory, filePath));
28173
28309
  if (!relative) {
28174
28310
  return ".";
28175
28311
  }
28176
- if (path86.isAbsolute(relative)) {
28312
+ if (path88.isAbsolute(relative)) {
28177
28313
  return toPosix3(filePath);
28178
28314
  }
28179
28315
  if (relative.startsWith("..")) {
@@ -28261,8 +28397,8 @@ async function pathExists6(filePath) {
28261
28397
  }
28262
28398
  async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
28263
28399
  const input5 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
28264
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28265
- const raw = await readFile29(jsonConfigPath, "utf8");
28400
+ const jsonConfigPath = path89.join(siteDirectory, "apitogo.config.json");
28401
+ const raw = await readFile30(jsonConfigPath, "utf8");
28266
28402
  const siteConfig = JSON.parse(raw);
28267
28403
  const updated = applyOpenApiToSiteConfig(siteConfig, {
28268
28404
  input: input5,
@@ -28270,7 +28406,7 @@ async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
28270
28406
  });
28271
28407
  const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
28272
28408
  updated.backend = { ...backend, openApiPath: input5 };
28273
- await writeFile26(
28409
+ await writeFile27(
28274
28410
  jsonConfigPath,
28275
28411
  `${JSON.stringify(updated, null, 2)}
28276
28412
  `,
@@ -28289,7 +28425,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
28289
28425
  const invalidCandidates = [];
28290
28426
  let selected;
28291
28427
  for (const candidate of search.candidates) {
28292
- const content = await readFile29(candidate, "utf8");
28428
+ const content = await readFile30(candidate, "utf8");
28293
28429
  const parsed = liteParseOpenApi(content, candidate);
28294
28430
  if (parsed.valid) {
28295
28431
  selected = {
@@ -28313,7 +28449,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
28313
28449
  wired: false
28314
28450
  };
28315
28451
  }
28316
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28452
+ const jsonConfigPath = path89.join(siteDirectory, "apitogo.config.json");
28317
28453
  if (!await pathExists6(jsonConfigPath)) {
28318
28454
  return {
28319
28455
  openApiDiscovery: {
@@ -28363,13 +28499,13 @@ async function discoverAndWireBackend(siteDirectory, mode) {
28363
28499
  if (mode !== "nearby") {
28364
28500
  return { status: "skipped", mode };
28365
28501
  }
28366
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28502
+ const jsonConfigPath = path89.join(siteDirectory, "apitogo.config.json");
28367
28503
  if (!await pathExists6(jsonConfigPath)) {
28368
28504
  return { status: "not_found" };
28369
28505
  }
28370
28506
  try {
28371
28507
  const siteConfig = JSON.parse(
28372
- await readFile29(jsonConfigPath, "utf8")
28508
+ await readFile30(jsonConfigPath, "utf8")
28373
28509
  );
28374
28510
  const existing = siteConfig.backend && typeof siteConfig.backend === "object" && !Array.isArray(siteConfig.backend) ? siteConfig.backend : {};
28375
28511
  if (typeof existing.sourceDirectory === "string" && existing.sourceDirectory.trim()) {
@@ -28390,7 +28526,7 @@ async function discoverAndWireBackend(siteDirectory, mode) {
28390
28526
  runtime: detected.runtime,
28391
28527
  runtimeVersion: detected.runtimeVersion
28392
28528
  };
28393
- await writeFile26(
28529
+ await writeFile27(
28394
28530
  jsonConfigPath,
28395
28531
  `${JSON.stringify(siteConfig, null, 2)}
28396
28532
  `,
@@ -28430,18 +28566,18 @@ function slugifyName2(name) {
28430
28566
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
28431
28567
  }
28432
28568
  function resolveInitOutputDirectory(dirArg, name) {
28433
- const resolved = path88.resolve(process.cwd(), dirArg);
28434
- const base = path88.basename(resolved);
28569
+ const resolved = path90.resolve(process.cwd(), dirArg);
28570
+ const base = path90.basename(resolved);
28435
28571
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
28436
28572
  if (isDot) {
28437
28573
  const fromName = name?.trim();
28438
28574
  if (!fromName) {
28439
28575
  throw new Error(
28440
- "apitogo init scaffolds into a named folder (default `dev-portal`). Pass a folder name or `--name` when using `.`."
28576
+ "apitogo init --no-v2 scaffolds into a named folder (default `dev-portal`). Pass a folder name or `--name` when using `.`."
28441
28577
  );
28442
28578
  }
28443
28579
  return {
28444
- outputDirectory: path88.resolve(process.cwd(), slugifyName2(fromName)),
28580
+ outputDirectory: path90.resolve(process.cwd(), slugifyName2(fromName)),
28445
28581
  siteName: fromName
28446
28582
  };
28447
28583
  }
@@ -28558,9 +28694,9 @@ var init_default = {
28558
28694
  command: "init [dir]",
28559
28695
  builder: (yargs2) => yargs2.positional("dir", {
28560
28696
  type: "string",
28561
- describe: "Directory to scaffold into (with --v2 the default is the current directory)",
28562
- // Shown in the help but not applied by yargs, so --v2 can default to the current directory instead.
28563
- defaultDescription: '"dev-portal"',
28697
+ describe: "Directory to scaffold into (the default is the current directory; with --no-v2 it is dev-portal)",
28698
+ // Shown in the help but not applied by yargs, so config version 2 can default to the current directory.
28699
+ defaultDescription: '"." (the current directory)',
28564
28700
  normalize: true
28565
28701
  }).option("name", {
28566
28702
  type: "string",
@@ -28584,32 +28720,32 @@ var init_default = {
28584
28720
  describe: "Auto-discover and wire OpenAPI (nearby = parent/siblings/site)"
28585
28721
  }).option("v2", {
28586
28722
  type: "boolean",
28587
- default: false,
28588
- describe: "Preview: create a config version 2 project (standalone or embedded layout). add, remove, check, run, build, plan, status, deploy and secrets read it"
28723
+ default: true,
28724
+ describe: "Create a config version 2 project (standalone or embedded layout). This is the default; use --no-v2 for the older dev-portal scaffold"
28589
28725
  }).option("layout", {
28590
28726
  type: "string",
28591
28727
  choices: ["standalone", "embedded"],
28592
- describe: "With --v2: override layout detection"
28728
+ describe: "Config version 2: override layout detection"
28593
28729
  }).option("only", {
28594
28730
  type: "string",
28595
- describe: "With --v2: services to enable (only `portal` is available for now)"
28731
+ describe: "Config version 2: services to enable (only `portal` is available for now)"
28596
28732
  }).option("docs", {
28597
28733
  type: "string",
28598
28734
  array: true,
28599
- describe: "With --v2: existing docs folder or file to include in place (repeatable); --no-docs skips docs detection"
28735
+ describe: "Config version 2: existing docs folder or file to include in place (repeatable); --no-docs skips docs detection"
28600
28736
  }).option("dry-run", {
28601
28737
  type: "boolean",
28602
28738
  default: false,
28603
- describe: "With --v2: print what would be created and exit"
28739
+ describe: "Config version 2: print what would be created and exit"
28604
28740
  }).option("yes", {
28605
28741
  alias: "y",
28606
28742
  type: "boolean",
28607
28743
  default: false,
28608
- describe: "With --v2: do not ask for confirmation; include every docs folder found"
28744
+ describe: "Config version 2: do not ask for confirmation; include every docs folder found"
28609
28745
  }).option("force", {
28610
28746
  type: "boolean",
28611
28747
  default: false,
28612
- describe: "With --v2: replace an existing apitogo.config.json"
28748
+ describe: "Config version 2: replace an existing apitogo.config.json"
28613
28749
  }),
28614
28750
  handler: async (argv) => {
28615
28751
  await captureEvent({ argv, event: "apitogo init" });
@@ -28624,8 +28760,8 @@ import open2 from "open";
28624
28760
  import colors14 from "picocolors";
28625
28761
 
28626
28762
  // src/cli/platform/device-auth.ts
28627
- function url(apiUrl, path101) {
28628
- return `${apiUrl}${path101.startsWith("/") ? path101 : `/${path101}`}`;
28763
+ function url(apiUrl, path103) {
28764
+ return `${apiUrl}${path103.startsWith("/") ? path103 : `/${path103}`}`;
28629
28765
  }
28630
28766
  async function requestDeviceCode(apiUrl) {
28631
28767
  const response = await fetchWithRetry(
@@ -28807,7 +28943,7 @@ var logout_default = {
28807
28943
  };
28808
28944
 
28809
28945
  // src/cli/portal/commands.ts
28810
- import path89 from "node:path";
28946
+ import path91 from "node:path";
28811
28947
  init_invariant();
28812
28948
  function parseOnly(value) {
28813
28949
  if (value === void 0) return void 0;
@@ -28824,11 +28960,11 @@ function parseOnly(value) {
28824
28960
  async function run2(command2, argv, compute, format) {
28825
28961
  const json = argv.json === true;
28826
28962
  try {
28827
- const dir = path89.resolve(process.cwd(), argv.dir ?? ".");
28963
+ const dir = path91.resolve(process.cwd(), argv.dir ?? ".");
28828
28964
  if (!await isConfigV2(dir)) {
28829
28965
  throw new ServiceEditError(
28830
28966
  `${command2} works with a config version 2 project, and there is none in ${dir}.`,
28831
- "Create one with `apitogo init --v2`."
28967
+ "Create one with `apitogo init`."
28832
28968
  );
28833
28969
  }
28834
28970
  const output4 = await compute(dir, parseOnly(argv.only));
@@ -28908,7 +29044,7 @@ var plan_default = {
28908
29044
 
28909
29045
  // src/cli/project/create-handler.ts
28910
29046
  init_invariant();
28911
- import path90 from "node:path";
29047
+ import path92 from "node:path";
28912
29048
 
28913
29049
  // src/cli/project/v2.ts
28914
29050
  init_invariant();
@@ -29055,7 +29191,7 @@ async function createLinkedProject(argv, dir) {
29055
29191
  }
29056
29192
  }
29057
29193
  async function createProject(argv) {
29058
- const dir = path90.resolve(process.cwd(), argv.dir ?? ".");
29194
+ const dir = path92.resolve(process.cwd(), argv.dir ?? ".");
29059
29195
  if (await isConfigV2(dir)) {
29060
29196
  await createLinkedProject(argv, dir);
29061
29197
  return;
@@ -29179,14 +29315,14 @@ var remove_default = {
29179
29315
 
29180
29316
  // src/cli/dev/handler.ts
29181
29317
  init_joinUrl();
29182
- import path93 from "node:path";
29318
+ import path95 from "node:path";
29183
29319
 
29184
29320
  // src/vite/dev-server.ts
29185
29321
  init_logger();
29186
29322
  import fs12 from "node:fs/promises";
29187
29323
  import http from "node:http";
29188
29324
  import https from "node:https";
29189
- import path92 from "node:path";
29325
+ import path94 from "node:path";
29190
29326
  import { createHttpTerminator } from "http-terminator";
29191
29327
  import {
29192
29328
  createServer as createViteServer,
@@ -29219,7 +29355,7 @@ init_loader();
29219
29355
  // src/vite/pagefind-dev-index.ts
29220
29356
  init_invariant();
29221
29357
  init_joinUrl();
29222
- import path91 from "node:path";
29358
+ import path93 from "node:path";
29223
29359
  import { createIndex as createIndex2 } from "pagefind";
29224
29360
  import { isRunnableDevEnvironment } from "vite";
29225
29361
  async function* buildPagefindDevIndex(vite, config2) {
@@ -29272,7 +29408,7 @@ async function* buildPagefindDevIndex(vite, config2) {
29272
29408
  path: urlPath
29273
29409
  };
29274
29410
  }
29275
- const outputPath = path91.join(vite.config.publicDir, "pagefind");
29411
+ const outputPath = path93.join(vite.config.publicDir, "pagefind");
29276
29412
  await pagefindIndex.writeFiles({ outputPath });
29277
29413
  yield { type: "complete", success: true, indexed };
29278
29414
  }
@@ -29291,9 +29427,9 @@ var DevServer = class {
29291
29427
  this.protocol = "https";
29292
29428
  const { dir } = this.options;
29293
29429
  const [key, cert, ca] = await Promise.all([
29294
- fs12.readFile(path92.resolve(dir, config2.https.key)),
29295
- fs12.readFile(path92.resolve(dir, config2.https.cert)),
29296
- config2.https.ca ? fs12.readFile(path92.resolve(dir, config2.https.ca)) : void 0
29430
+ fs12.readFile(path94.resolve(dir, config2.https.key)),
29431
+ fs12.readFile(path94.resolve(dir, config2.https.cert)),
29432
+ config2.https.ca ? fs12.readFile(path94.resolve(dir, config2.https.ca)) : void 0
29297
29433
  ]);
29298
29434
  return https.createServer({ key, cert, ca });
29299
29435
  }
@@ -29310,7 +29446,7 @@ var DevServer = class {
29310
29446
  );
29311
29447
  const server = await this.createNodeServer(config2);
29312
29448
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
29313
- const publicRoot = path92.resolve(
29449
+ const publicRoot = path94.resolve(
29314
29450
  this.options.dir,
29315
29451
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
29316
29452
  );
@@ -29327,7 +29463,7 @@ var DevServer = class {
29327
29463
  // built-in transform middleware which would treat the path as a static asset.
29328
29464
  name: "apitogo:entry-client",
29329
29465
  configureServer(server2) {
29330
- const entryPath = path92.posix.join(
29466
+ const entryPath = path94.posix.join(
29331
29467
  server2.config.base,
29332
29468
  "/__z/entry.client.tsx"
29333
29469
  );
@@ -29492,7 +29628,7 @@ init_package_json();
29492
29628
  async function dev(argv) {
29493
29629
  const packageJson3 = getZudokuPackageJson();
29494
29630
  process.env.NODE_ENV = "development";
29495
- let dir = path93.resolve(process.cwd(), argv.dir);
29631
+ let dir = path95.resolve(process.cwd(), argv.dir);
29496
29632
  if (await isConfigV2(dir)) {
29497
29633
  const { root, prepared } = await preparePortalWorkspace(dir, "development");
29498
29634
  dir = root;
@@ -29591,7 +29727,7 @@ var run_default = {
29591
29727
  };
29592
29728
 
29593
29729
  // src/cli/secrets/handler.ts
29594
- import path94 from "node:path";
29730
+ import path96 from "node:path";
29595
29731
  init_invariant();
29596
29732
 
29597
29733
  // src/cli/secrets/input.ts
@@ -29656,7 +29792,7 @@ var SecretsError = class extends ApitogoError {
29656
29792
  async function resolveProjectId2(argv, deps) {
29657
29793
  const explicit = argv.projectId?.trim();
29658
29794
  if (explicit) return explicit;
29659
- const dir = path94.resolve(process.cwd(), argv.dir ?? ".");
29795
+ const dir = path96.resolve(process.cwd(), argv.dir ?? ".");
29660
29796
  if (await isConfigV2(dir)) {
29661
29797
  const id = loadConfigV2(dir).resolved.project.id;
29662
29798
  if (id) return id;
@@ -29816,12 +29952,12 @@ var secrets_default = {
29816
29952
  };
29817
29953
 
29818
29954
  // src/cli/cmds/status.ts
29819
- import path96 from "node:path";
29955
+ import path98 from "node:path";
29820
29956
 
29821
29957
  // src/cli/status/handler.ts
29822
- import path95 from "node:path";
29958
+ import path97 from "node:path";
29823
29959
  async function status(argv) {
29824
- const sourceDirectory = path95.resolve(process.cwd(), argv.dir);
29960
+ const sourceDirectory = path97.resolve(process.cwd(), argv.dir);
29825
29961
  let config2;
29826
29962
  try {
29827
29963
  config2 = loadConfig();
@@ -29919,7 +30055,7 @@ var status_default = {
29919
30055
  }),
29920
30056
  handler: async (argv) => {
29921
30057
  await captureEvent({ argv, event: "apitogo status" });
29922
- if (await isConfigV2(path96.resolve(process.cwd(), argv.dir))) {
30058
+ if (await isConfigV2(path98.resolve(process.cwd(), argv.dir))) {
29923
30059
  await statusOfProject(argv);
29924
30060
  return;
29925
30061
  }
@@ -29928,11 +30064,11 @@ var status_default = {
29928
30064
  };
29929
30065
 
29930
30066
  // src/cli/cmds/teardown.ts
29931
- import path99 from "node:path";
30067
+ import path101 from "node:path";
29932
30068
 
29933
30069
  // src/cli/teardown/command.ts
29934
30070
  init_invariant();
29935
- import path97 from "node:path";
30071
+ import path99 from "node:path";
29936
30072
  import { createInterface as createInterface7 } from "node:readline/promises";
29937
30073
 
29938
30074
  // src/cli/teardown/v2.ts
@@ -30149,7 +30285,7 @@ async function teardownProject(argv) {
30149
30285
  const progress = createConsoleProgressReporter();
30150
30286
  const result = await teardownV2(
30151
30287
  {
30152
- dir: path97.resolve(process.cwd(), argv.dir),
30288
+ dir: path99.resolve(process.cwd(), argv.dir),
30153
30289
  projectId: argv.projectId,
30154
30290
  only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
30155
30291
  yes: argv.yes === true,
@@ -30208,7 +30344,7 @@ async function teardownProject(argv) {
30208
30344
  }
30209
30345
 
30210
30346
  // src/cli/teardown/handler.ts
30211
- import path98 from "node:path";
30347
+ import path100 from "node:path";
30212
30348
  function resultLooksFailed3(payload) {
30213
30349
  try {
30214
30350
  const parsed = JSON.parse(payload);
@@ -30224,7 +30360,7 @@ async function teardown(argv) {
30224
30360
  );
30225
30361
  return;
30226
30362
  }
30227
- const sourceDirectory = path98.resolve(process.cwd(), argv.dir);
30363
+ const sourceDirectory = path100.resolve(process.cwd(), argv.dir);
30228
30364
  let config2;
30229
30365
  try {
30230
30366
  config2 = loadConfig();
@@ -30302,7 +30438,7 @@ var teardown_default = {
30302
30438
  }),
30303
30439
  handler: async (argv) => {
30304
30440
  await captureEvent({ argv, event: "apitogo teardown" });
30305
- if (await isConfigV2(path99.resolve(process.cwd(), argv.dir))) {
30441
+ if (await isConfigV2(path101.resolve(process.cwd(), argv.dir))) {
30306
30442
  await teardownProject(argv);
30307
30443
  return;
30308
30444
  }
@@ -30379,37 +30515,37 @@ function createApitogoCli(argv) {
30379
30515
 
30380
30516
  // src/cli/local-handoff.ts
30381
30517
  import { spawn as spawn5 } from "node:child_process";
30382
- import { existsSync as existsSync8, realpathSync } from "node:fs";
30383
- import path100 from "node:path";
30518
+ import { existsSync as existsSync9, realpathSync as realpathSync2 } from "node:fs";
30519
+ import path102 from "node:path";
30384
30520
  var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
30385
30521
  var PACKAGE_NAME = "@lukoweb/apitogo";
30386
30522
  var resolveProjectDir = (argv, cwd) => {
30387
30523
  for (let i = 0; i < argv.length; i++) {
30388
30524
  const arg = argv[i];
30389
30525
  const next = argv[i + 1];
30390
- if (arg === "--dir" && next) return path100.resolve(cwd, next);
30526
+ if (arg === "--dir" && next) return path102.resolve(cwd, next);
30391
30527
  if (arg?.startsWith("--dir=")) {
30392
- return path100.resolve(cwd, arg.slice("--dir=".length));
30528
+ return path102.resolve(cwd, arg.slice("--dir=".length));
30393
30529
  }
30394
30530
  }
30395
30531
  return cwd;
30396
30532
  };
30397
30533
  var findLocalCli = (projectDir, runningRoot) => {
30398
- let dir = path100.resolve(projectDir);
30534
+ let dir = path102.resolve(projectDir);
30399
30535
  let localPackageRoot;
30400
30536
  while (!localPackageRoot) {
30401
- const candidate = path100.join(dir, "node_modules", PACKAGE_NAME);
30402
- if (existsSync8(path100.join(candidate, "package.json"))) {
30537
+ const candidate = path102.join(dir, "node_modules", PACKAGE_NAME);
30538
+ if (existsSync9(path102.join(candidate, "package.json"))) {
30403
30539
  localPackageRoot = candidate;
30404
- } else if (dir === path100.dirname(dir)) {
30540
+ } else if (dir === path102.dirname(dir)) {
30405
30541
  return void 0;
30406
30542
  } else {
30407
- dir = path100.dirname(dir);
30543
+ dir = path102.dirname(dir);
30408
30544
  }
30409
30545
  }
30410
- const localRoot = realpathSync(localPackageRoot);
30411
- if (localRoot === realpathSync(runningRoot)) return void 0;
30412
- return path100.join(localRoot, "cli.js");
30546
+ const localRoot = realpathSync2(localPackageRoot);
30547
+ if (localRoot === realpathSync2(runningRoot)) return void 0;
30548
+ return path102.join(localRoot, "cli.js");
30413
30549
  };
30414
30550
  var handoffToLocalCli = async (argv, runningRoot) => {
30415
30551
  if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
@@ -30421,7 +30557,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
30421
30557
  );
30422
30558
  if (!localCli) return void 0;
30423
30559
  printDiagnosticsToConsole(
30424
- `Using the project's local ${PACKAGE_NAME} (${path100.dirname(localCli)})`
30560
+ `Using the project's local ${PACKAGE_NAME} (${path102.dirname(localCli)})`
30425
30561
  );
30426
30562
  const child = spawn5(process.execPath, [localCli, ...argv], {
30427
30563
  stdio: "inherit",