@lukoweb/apitogo 0.2.16 → 0.2.18

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 = (path102) => stat4(path102).then(() => true).catch(() => false);
840
840
  }
841
841
  });
842
842
 
@@ -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 path52 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(path102) {
6193
+ return path102.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(path102) {
6214
6214
  let current = ConfigV2Schema;
6215
- for (const segment of path101) {
6215
+ for (const segment of path102) {
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 path102 = 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: path102,
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: path102, 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: path102, message: "is required." } : { code: "CONFIG_INVALID_VALUE", path: path102, 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: path102, 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, path102, message, hint) => ({ code, path: path102, 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, path102) {
7508
+ const trimmed = path102.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
+ ([path102, item]) => isObject(item) ? METHODS.filter((method) => isObject(item[method])).map(
7546
+ (method) => [path102, 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 [path102, item, method] of operationsOf(paths))
7562
+ if (options.deniedOperations.has(actionKey(method, path102)))
7563
7563
  delete item[method];
7564
- for (const [path101, item] of Object.entries(paths))
7564
+ for (const [path102, 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[path102];
7567
+ for (const [path102, item, method] of operationsOf(paths))
7568
+ if (options.publicOperations.has(actionKey(method, path102)))
7569
7569
  item[method].security = [];
7570
7570
  doc.servers = [{ url: options.gatewayBaseUrl.replace(/\/+$/, "") }];
7571
7571
  for (const item of Object.values(paths)) {
@@ -7699,15 +7699,84 @@ function stableJson(value) {
7699
7699
  }
7700
7700
 
7701
7701
  // src/config/v2/wrapper.ts
7702
- import { mkdir as mkdir4, readFile as readFile5, rename as rename2, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
7702
+ import { mkdir as mkdir4, readFile as readFile6, rename as rename2, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
7703
7703
  import path12 from "node:path";
7704
7704
 
7705
+ // src/config/v2/docs-navigation.ts
7706
+ var DOCS_NAVIGATION_LABEL = "Documentation";
7707
+ var emptyBranch = () => ({ pages: /* @__PURE__ */ new Set(), folders: /* @__PURE__ */ new Map() });
7708
+ function folderLabel(name) {
7709
+ const words = name.replace(/[-_]+/g, " ").trim();
7710
+ return words.charAt(0).toUpperCase() + words.slice(1);
7711
+ }
7712
+ var byName = (a, b) => a.localeCompare(b);
7713
+ var toItems = (branch, prefix) => {
7714
+ const pages = [...branch.pages].sort(
7715
+ (a, b) => a === "index" ? -1 : b === "index" ? 1 : byName(a, b)
7716
+ );
7717
+ const folders = [...branch.folders.keys()].sort(byName);
7718
+ return [
7719
+ // The index page of a folder is the folder's own address, so the sidebar also shows on `/`.
7720
+ ...pages.map(
7721
+ (page) => page === "index" ? {
7722
+ type: "doc",
7723
+ file: `${prefix}${page}`,
7724
+ path: prefix === "" ? "/" : `/${prefix.slice(0, -1)}`
7725
+ } : `${prefix}${page}`
7726
+ ),
7727
+ ...folders.map(
7728
+ (folder) => ({
7729
+ type: "category",
7730
+ label: folderLabel(folder),
7731
+ collapsible: true,
7732
+ collapsed: false,
7733
+ items: toItems(
7734
+ branch.folders.get(folder) ?? emptyBranch(),
7735
+ `${prefix}${folder}/`
7736
+ )
7737
+ })
7738
+ )
7739
+ ];
7740
+ };
7741
+ function docsNavigation(routes) {
7742
+ const root = emptyBranch();
7743
+ for (const route of routes) {
7744
+ const parts = route.split("/").filter(Boolean);
7745
+ const page = parts.pop();
7746
+ if (!page) continue;
7747
+ const branch = parts.reduce((current, folder) => {
7748
+ const next = current.folders.get(folder) ?? emptyBranch();
7749
+ current.folders.set(folder, next);
7750
+ return next;
7751
+ }, root);
7752
+ branch.pages.add(page);
7753
+ }
7754
+ const items = toItems(root, "");
7755
+ return items.length === 0 ? [] : [{ type: "category", label: DOCS_NAVIGATION_LABEL, items }];
7756
+ }
7757
+
7705
7758
  // src/config/v2/home-redirect.ts
7706
7759
  import path11 from "node:path";
7707
7760
  import { glob as glob2 } from "glob";
7708
7761
  import globParent from "glob-parent";
7762
+
7763
+ // src/lib/util/readFrontmatter.ts
7764
+ import { readFile as readFile5 } from "node:fs/promises";
7765
+ import matter from "gray-matter";
7766
+ import { parse as parse2, stringify } from "yaml";
7767
+ var yaml = {
7768
+ parse: (input5) => parse2(input5) ?? {},
7769
+ stringify: (obj) => stringify(obj)
7770
+ };
7771
+ var readFrontmatter = async (filePath) => {
7772
+ const content = await readFile5(filePath, "utf-8");
7773
+ const normalizedContent = content.replace(/\r\n/g, "\n");
7774
+ return matter(normalizedContent, { engines: { yaml } });
7775
+ };
7776
+
7777
+ // src/config/v2/home-redirect.ts
7709
7778
  var IGNORED = ["**/node_modules/**", "**/dist/**", "**/.git/**"];
7710
- async function docRoutes(patterns) {
7779
+ async function docRoutes(patterns, options = {}) {
7711
7780
  const excluded = patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
7712
7781
  const included = patterns.filter((pattern) => !pattern.startsWith("!"));
7713
7782
  const routes = await Promise.all(
@@ -7718,7 +7787,13 @@ async function docRoutes(patterns) {
7718
7787
  ignore: [...IGNORED, ...excluded]
7719
7788
  });
7720
7789
  const parent = globParent(pattern);
7721
- return files.map(
7790
+ const published = options.includeDrafts ? files : (await Promise.all(
7791
+ files.map(async (file) => ({
7792
+ file,
7793
+ draft: (await readFrontmatter(file)).data.draft === true
7794
+ }))
7795
+ )).filter(({ draft }) => !draft).map(({ file }) => file);
7796
+ return published.map(
7722
7797
  (file) => `/${path11.posix.relative(parent, file).replace(/\.mdx?$/, "")}`
7723
7798
  );
7724
7799
  })
@@ -7875,8 +7950,19 @@ function planPortal(profile, manifest) {
7875
7950
  var SITE_CONFIG_FILE = "apitogo.config.json";
7876
7951
  var REFERENCE_SPEC_FILE = "openapi/gateway.json";
7877
7952
  var API_REFERENCE_PATH = "api";
7878
- function buildSiteConfig(resolved, plan2, theme, redirects = []) {
7953
+ function buildSiteConfig(resolved, plan2, theme, extras = {}) {
7879
7954
  const portal = resolved.portal;
7955
+ const redirects = extras.redirects ?? [];
7956
+ const navigation = [
7957
+ ...extras.docsNavigation ?? [],
7958
+ ...plan2.apiReference ? [
7959
+ {
7960
+ type: "link",
7961
+ to: `/${API_REFERENCE_PATH}`,
7962
+ label: "API Reference"
7963
+ }
7964
+ ] : []
7965
+ ];
7880
7966
  return {
7881
7967
  site: {
7882
7968
  title: portal?.name ?? resolved.project.name,
@@ -7900,15 +7986,9 @@ function buildSiteConfig(resolved, plan2, theme, redirects = []) {
7900
7986
  input: `./${REFERENCE_SPEC_FILE}`,
7901
7987
  path: API_REFERENCE_PATH
7902
7988
  }
7903
- ],
7904
- navigation: [
7905
- {
7906
- type: "link",
7907
- to: `/${API_REFERENCE_PATH}`,
7908
- label: "API Reference"
7909
- }
7910
7989
  ]
7911
7990
  } : {},
7991
+ ...navigation.length > 0 ? { navigation } : {},
7912
7992
  ...redirects.length > 0 ? { redirects } : {},
7913
7993
  ...theme !== void 0 ? { theme } : {},
7914
7994
  ...plan2.auth ? { authentication: { type: "openid", ...plan2.auth } } : {},
@@ -7943,7 +8023,7 @@ async function readTheme(resolved) {
7943
8023
  const file = resolved.portal?.theme;
7944
8024
  if (!file) return void 0;
7945
8025
  try {
7946
- return JSON.parse(await readFile5(file, "utf8"));
8026
+ return JSON.parse(await readFile6(file, "utf8"));
7947
8027
  } catch {
7948
8028
  return void 0;
7949
8029
  }
@@ -8001,9 +8081,12 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
8001
8081
  });
8002
8082
  }
8003
8083
  }
8084
+ const hostedDocRoutes = plan2.docs ? await docRoutes(profile.docs.content, {
8085
+ includeDrafts: mode === "development"
8086
+ }) : [];
8004
8087
  const home = homeRedirect({
8005
8088
  hostsDocs: plan2.docs,
8006
- docRoutes: plan2.docs ? await docRoutes(profile.docs.content) : [],
8089
+ docRoutes: hostedDocRoutes,
8007
8090
  externalDocsUrl: profile.docs.url,
8008
8091
  apiReferencePath: plan2.apiReference ? `/${API_REFERENCE_PATH}` : void 0,
8009
8092
  userPanel: plan2.userPanel
@@ -8012,7 +8095,10 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
8012
8095
  resolved,
8013
8096
  plan2,
8014
8097
  await readTheme(resolved),
8015
- home ? [home] : []
8098
+ {
8099
+ redirects: home ? [home] : [],
8100
+ docsNavigation: docsNavigation(hostedDocRoutes)
8101
+ }
8016
8102
  );
8017
8103
  const wrapper = renderWrapper(plan2);
8018
8104
  const wrapperPath = path12.join(resolved.state.generatedDir, WRAPPER_FILE);
@@ -8057,7 +8143,7 @@ async function preparePortal(resolved, manifest, mode, options = {}) {
8057
8143
 
8058
8144
  // src/config/v2/workspace.ts
8059
8145
  import { createHash as createHash2 } from "node:crypto";
8060
- import { access as access2, lstat, readFile as readFile6, rm as rm3, symlink } from "node:fs/promises";
8146
+ import { access as access2, lstat, readFile as readFile7, rm as rm3, symlink } from "node:fs/promises";
8061
8147
  import path13 from "node:path";
8062
8148
  import { glob as glob3 } from "glob";
8063
8149
  var exists2 = (file) => access2(file).then(
@@ -8086,7 +8172,7 @@ async function materializeWorkspace(resolved, prepared) {
8086
8172
  return root;
8087
8173
  }
8088
8174
  async function configFingerprint(configPath) {
8089
- const text = await readFile6(configPath, "utf8");
8175
+ const text = await readFile7(configPath, "utf8");
8090
8176
  try {
8091
8177
  const raw = JSON.parse(text);
8092
8178
  if (raw.project) {
@@ -8135,7 +8221,7 @@ async function portalArtifactHash(resolved, manifestText, cliVersion, wrapper =
8135
8221
  for (const file of files) {
8136
8222
  hash2.update(`file:${path13.relative(resolved.configDir, file)}
8137
8223
  `);
8138
- hash2.update(await readFile6(file));
8224
+ hash2.update(await readFile7(file));
8139
8225
  }
8140
8226
  return hash2.digest("hex");
8141
8227
  }
@@ -8602,7 +8688,7 @@ async function clearProjectId(dir, projectId) {
8602
8688
 
8603
8689
  // src/config/v2/ledger.ts
8604
8690
  init_invariant();
8605
- import { mkdir as mkdir6, readFile as readFile7, rename as rename4, rm as rm5, writeFile as writeFile7 } from "node:fs/promises";
8691
+ import { mkdir as mkdir6, readFile as readFile8, rename as rename4, rm as rm5, writeFile as writeFile7 } from "node:fs/promises";
8606
8692
  import path15 from "node:path";
8607
8693
  var LEDGER_VERSION = 1;
8608
8694
  var LedgerError = class extends ApitogoError {
@@ -8619,7 +8705,7 @@ var emptyLedger = () => ({
8619
8705
  async function readLedger(state) {
8620
8706
  let text;
8621
8707
  try {
8622
- text = await readFile7(state.file, "utf8");
8708
+ text = await readFile8(state.file, "utf8");
8623
8709
  } catch (error) {
8624
8710
  if (error.code === "ENOENT")
8625
8711
  return emptyLedger();
@@ -8750,8 +8836,8 @@ init_invariant();
8750
8836
 
8751
8837
  // src/cli/check/v2.ts
8752
8838
  init_apitogo_config_core();
8753
- import { readFile as readFile13 } from "node:fs/promises";
8754
- import path47 from "node:path";
8839
+ import { readFile as readFile14 } from "node:fs/promises";
8840
+ import path48 from "node:path";
8755
8841
 
8756
8842
  // src/cli/platform/client/platform-api.ts
8757
8843
  import { basename } from "node:path";
@@ -8864,8 +8950,8 @@ var PlatformApiClient = class {
8864
8950
  constructor(config2) {
8865
8951
  this.config = config2;
8866
8952
  }
8867
- url(path101) {
8868
- return `${this.config.apiUrl}${path101.startsWith("/") ? path101 : `/${path101}`}`;
8953
+ url(path102) {
8954
+ return `${this.config.apiUrl}${path102.startsWith("/") ? path102 : `/${path102}`}`;
8869
8955
  }
8870
8956
  headers(extra) {
8871
8957
  return {
@@ -8875,9 +8961,9 @@ var PlatformApiClient = class {
8875
8961
  ...extra
8876
8962
  };
8877
8963
  }
8878
- async request(method, path101, init4) {
8964
+ async request(method, path102, init4) {
8879
8965
  const response = await fetchWithRetry(
8880
- this.url(path101),
8966
+ this.url(path102),
8881
8967
  {
8882
8968
  method,
8883
8969
  ...init4,
@@ -9240,15 +9326,15 @@ var PlatformApiClient = class {
9240
9326
  }
9241
9327
  );
9242
9328
  }
9243
- deleteDevPortalPage(projectId, path101) {
9244
- const query = new URLSearchParams({ path: path101 });
9329
+ deleteDevPortalPage(projectId, path102) {
9330
+ const query = new URLSearchParams({ path: path102 });
9245
9331
  return this.request(
9246
9332
  "DELETE",
9247
9333
  `/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
9248
9334
  );
9249
9335
  }
9250
- renameDevPortalPage(projectId, path101, newName) {
9251
- const query = new URLSearchParams({ path: path101 });
9336
+ renameDevPortalPage(projectId, path102, newName) {
9337
+ const query = new URLSearchParams({ path: path102 });
9252
9338
  return this.request(
9253
9339
  "POST",
9254
9340
  `/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
@@ -9364,8 +9450,8 @@ var PlatformApiClient = class {
9364
9450
  * the project-less endpoint is used; `planTier` overrides the tier used for paid-plan checks.
9365
9451
  */
9366
9452
  validateGatewayPlans(plans, options = {}) {
9367
- const path101 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
9368
- return this.request("POST", path101, {
9453
+ const path102 = options.projectId ? `/api/v1/projects/${options.projectId}/gateway/plans/validate` : "/api/v1/gateway/plans/validate";
9454
+ return this.request("POST", path102, {
9369
9455
  headers: { "Content-Type": "application/json" },
9370
9456
  body: JSON.stringify({ plans, planTier: options.planTier })
9371
9457
  });
@@ -9466,8 +9552,8 @@ var PlatformApiClient = class {
9466
9552
  }
9467
9553
  };
9468
9554
  async function readFileBytes(filePath) {
9469
- const { readFile: readFile30 } = await import("node:fs/promises");
9470
- const buffer = await readFile30(filePath);
9555
+ const { readFile: readFile31 } = await import("node:fs/promises");
9556
+ const buffer = await readFile31(filePath);
9471
9557
  const arrayBuffer = new ArrayBuffer(buffer.byteLength);
9472
9558
  new Uint8Array(arrayBuffer).set(buffer);
9473
9559
  return arrayBuffer;
@@ -9564,13 +9650,13 @@ function resolveProjectId(explicit, config2) {
9564
9650
  import {
9565
9651
  access as access4,
9566
9652
  mkdir as mkdir12,
9567
- readFile as readFile11,
9653
+ readFile as readFile12,
9568
9654
  rename as rename6,
9569
9655
  rm as rm8,
9570
- writeFile as writeFile13
9656
+ writeFile as writeFile14
9571
9657
  } from "node:fs/promises";
9572
9658
  import { createRequire as createRequire2 } from "node:module";
9573
- import path46 from "node:path";
9659
+ import path47 from "node:path";
9574
9660
 
9575
9661
  // src/vite/build.ts
9576
9662
  import { mkdir as mkdir11, readFile as readFile10, rename as rename5, rm as rm7, writeFile as writeFile12 } from "node:fs/promises";
@@ -9721,7 +9807,7 @@ import {
9721
9807
  // package.json
9722
9808
  var package_default = {
9723
9809
  name: "@lukoweb/apitogo",
9724
- version: "0.2.16",
9810
+ version: "0.2.18",
9725
9811
  type: "module",
9726
9812
  sideEffects: [
9727
9813
  "**/*.css",
@@ -10503,14 +10589,14 @@ var flattenAllOf = (schema2) => {
10503
10589
  };
10504
10590
 
10505
10591
  // src/lib/util/traverse.ts
10506
- var traverse = (specification, transform, path101 = []) => {
10507
- const transformed = transform(specification, path101);
10592
+ var traverse = (specification, transform, path102 = []) => {
10593
+ const transformed = transform(specification, path102);
10508
10594
  if (typeof transformed !== "object" || transformed === null) {
10509
10595
  return transformed;
10510
10596
  }
10511
10597
  const result = Array.isArray(transformed) ? [] : {};
10512
10598
  for (const [key, value] of Object.entries(transformed)) {
10513
- const currentPath = [...path101, key];
10599
+ const currentPath = [...path102, key];
10514
10600
  if (Array.isArray(value)) {
10515
10601
  result[key] = value.map(
10516
10602
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -10538,9 +10624,9 @@ var resolveLocalRef = (schema2, ref) => {
10538
10624
  if (schemaCache?.has(ref)) {
10539
10625
  return schemaCache.get(ref);
10540
10626
  }
10541
- const path101 = ref.split("/").slice(1);
10627
+ const path102 = ref.split("/").slice(1);
10542
10628
  let current = schema2;
10543
- for (const segment of path101) {
10629
+ for (const segment of path102) {
10544
10630
  if (!current || typeof current !== "object") {
10545
10631
  current = null;
10546
10632
  }
@@ -10559,7 +10645,7 @@ var dereference = async (schema2, resolvers = []) => {
10559
10645
  }
10560
10646
  const cloned = structuredClone(schema2);
10561
10647
  const visited = /* @__PURE__ */ new Set();
10562
- const resolve = async (current, path101) => {
10648
+ const resolve = async (current, path102) => {
10563
10649
  if (isIndexableObject(current)) {
10564
10650
  if (visited.has(current)) {
10565
10651
  return CIRCULAR_REF;
@@ -10567,7 +10653,7 @@ var dereference = async (schema2, resolvers = []) => {
10567
10653
  visited.add(current);
10568
10654
  if (Array.isArray(current)) {
10569
10655
  for (let index = 0; index < current.length; index++) {
10570
- current[index] = await resolve(current[index], `${path101}/${index}`);
10656
+ current[index] = await resolve(current[index], `${path102}/${index}`);
10571
10657
  }
10572
10658
  } else {
10573
10659
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -10578,13 +10664,13 @@ var dereference = async (schema2, resolvers = []) => {
10578
10664
  for (const resolver of resolvers) {
10579
10665
  const resolved = await resolver($ref);
10580
10666
  if (resolved) {
10581
- result2 = await resolve(resolved, path101);
10667
+ result2 = await resolve(resolved, path102);
10582
10668
  break;
10583
10669
  }
10584
10670
  }
10585
10671
  if (result2 === void 0) {
10586
10672
  const resolved = await resolveLocalRef(cloned, $ref);
10587
- result2 = await resolve(resolved, path101);
10673
+ result2 = await resolve(resolved, path102);
10588
10674
  }
10589
10675
  if (hasSiblings) {
10590
10676
  if (result2 === CIRCULAR_REF) {
@@ -10597,7 +10683,7 @@ var dereference = async (schema2, resolvers = []) => {
10597
10683
  return result2;
10598
10684
  }
10599
10685
  for (const key in current) {
10600
- current[key] = await resolve(current[key], `${path101}/${key}`);
10686
+ current[key] = await resolve(current[key], `${path102}/${key}`);
10601
10687
  }
10602
10688
  }
10603
10689
  visited.delete(current);
@@ -10636,9 +10722,9 @@ var upgradeSchema = (schema2) => {
10636
10722
  }
10637
10723
  return sub;
10638
10724
  });
10639
- schema2 = traverse(schema2, (sub, path101) => {
10725
+ schema2 = traverse(schema2, (sub, path102) => {
10640
10726
  if (sub.example !== void 0) {
10641
- if (isSchemaPath(path101 ?? [])) {
10727
+ if (isSchemaPath(path102 ?? [])) {
10642
10728
  sub.examples = [sub.example];
10643
10729
  } else {
10644
10730
  sub.examples = {
@@ -10651,11 +10737,11 @@ var upgradeSchema = (schema2) => {
10651
10737
  }
10652
10738
  return sub;
10653
10739
  });
10654
- schema2 = traverse(schema2, (schema3, path101) => {
10740
+ schema2 = traverse(schema2, (schema3, path102) => {
10655
10741
  if (schema3.type === "object" && schema3.properties !== void 0) {
10656
- const parentPath = path101?.slice(0, -1);
10742
+ const parentPath = path102?.slice(0, -1);
10657
10743
  const isMultipart = parentPath?.some((segment, index) => {
10658
- return segment === "content" && path101?.[index + 1] === "multipart/form-data";
10744
+ return segment === "content" && path102?.[index + 1] === "multipart/form-data";
10659
10745
  });
10660
10746
  if (isMultipart) {
10661
10747
  const entries = Object.entries(schema3.properties);
@@ -10669,8 +10755,8 @@ var upgradeSchema = (schema2) => {
10669
10755
  }
10670
10756
  return schema3;
10671
10757
  });
10672
- schema2 = traverse(schema2, (schema3, path101) => {
10673
- if (path101?.includes("content") && path101.includes("application/octet-stream")) {
10758
+ schema2 = traverse(schema2, (schema3, path102) => {
10759
+ if (path102?.includes("content") && path102.includes("application/octet-stream")) {
10674
10760
  return {};
10675
10761
  }
10676
10762
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -10696,11 +10782,11 @@ var upgradeSchema = (schema2) => {
10696
10782
  }
10697
10783
  return sub;
10698
10784
  });
10699
- schema2 = traverse(schema2, (schema3, path101) => {
10785
+ schema2 = traverse(schema2, (schema3, path102) => {
10700
10786
  if (schema3.type === "string" && schema3.format === "byte") {
10701
- const parentPath = path101?.slice(0, -1);
10787
+ const parentPath = path102?.slice(0, -1);
10702
10788
  const contentMediaType = parentPath?.find(
10703
- (_, index) => path101?.[index - 1] === "content"
10789
+ (_, index) => path102?.[index - 1] === "content"
10704
10790
  );
10705
10791
  return {
10706
10792
  type: "string",
@@ -10712,7 +10798,7 @@ var upgradeSchema = (schema2) => {
10712
10798
  });
10713
10799
  return schema2;
10714
10800
  };
10715
- function isSchemaPath(path101) {
10801
+ function isSchemaPath(path102) {
10716
10802
  const schemaLocations = [
10717
10803
  ["components", "schemas"],
10718
10804
  "properties",
@@ -10725,10 +10811,10 @@ function isSchemaPath(path101) {
10725
10811
  ];
10726
10812
  return schemaLocations.some((location) => {
10727
10813
  if (Array.isArray(location)) {
10728
- return location.every((segment, index) => path101[index] === segment);
10814
+ return location.every((segment, index) => path102[index] === segment);
10729
10815
  }
10730
- return path101.includes(location);
10731
- }) || path101.includes("schema") || path101.some((segment) => segment.endsWith("Schema"));
10816
+ return path102.includes(location);
10817
+ }) || path102.includes("schema") || path102.some((segment) => segment.endsWith("Schema"));
10732
10818
  }
10733
10819
 
10734
10820
  // src/lib/oas/parser/index.ts
@@ -10810,13 +10896,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
10810
10896
  "anyOf",
10811
10897
  "oneOf"
10812
10898
  ]);
10813
- 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(), path102 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
10814
10900
  if (obj === null || typeof obj !== "object") return obj;
10815
10901
  const refPath = obj.__$ref;
10816
10902
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
10817
10903
  if (isCircular) {
10818
10904
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
10819
- const circularProp = path101.find((p) => !OPENAPI_PROPS.has(p)) || path101[0];
10905
+ const circularProp = path102.find((p) => !OPENAPI_PROPS.has(p)) || path102[0];
10820
10906
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
10821
10907
  }
10822
10908
  if (refs.has(obj)) return refs.get(obj);
@@ -10826,7 +10912,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
10826
10912
  value,
10827
10913
  currentPath,
10828
10914
  refs,
10829
- [...path101, key],
10915
+ [...path102, key],
10830
10916
  currentRefPaths
10831
10917
  );
10832
10918
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -10861,7 +10947,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
10861
10947
  var getAllTags = (schema2) => {
10862
10948
  const rootTags = schema2.tags ?? [];
10863
10949
  const operations = Object.values(schema2.paths ?? {}).flatMap(
10864
- (path101) => HttpMethods.map((k) => path101?.[k]).filter((op) => op != null)
10950
+ (path102) => HttpMethods.map((k) => path102?.[k]).filter((op) => op != null)
10865
10951
  );
10866
10952
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
10867
10953
  const hasUntaggedOperations = operations.some(
@@ -10916,7 +11002,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
10916
11002
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
10917
11003
  var getAllOperations = (paths) => {
10918
11004
  const operations = Object.entries(paths ?? {}).flatMap(
10919
- ([path101, value]) => HttpMethods.flatMap((method) => {
11005
+ ([path102, value]) => HttpMethods.flatMap((method) => {
10920
11006
  if (!value?.[method]) return [];
10921
11007
  const operation = value[method];
10922
11008
  const pathParameters = value.parameters ?? [];
@@ -10936,7 +11022,7 @@ var getAllOperations = (paths) => {
10936
11022
  return {
10937
11023
  ...operation,
10938
11024
  method,
10939
- path: path101,
11025
+ path: path102,
10940
11026
  parameters,
10941
11027
  servers,
10942
11028
  tags: operation.tags ?? []
@@ -11294,8 +11380,8 @@ var Schema = builder.objectRef("Schema").implement({
11294
11380
  }),
11295
11381
  paths: t.field({
11296
11382
  type: [PathItem],
11297
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path101, value]) => ({
11298
- path: path101,
11383
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path102, value]) => ({
11384
+ path: path102,
11299
11385
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
11300
11386
  methods: Object.keys(value)
11301
11387
  }))
@@ -11460,7 +11546,7 @@ init_joinUrl();
11460
11546
 
11461
11547
  // src/vite/api/schema-codegen.ts
11462
11548
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
11463
- var getSegmentsFromPath = (path101) => path101.split("/").slice(1).map(unescapeJsonPointer);
11549
+ var getSegmentsFromPath = (path102) => path102.split("/").slice(1).map(unescapeJsonPointer);
11464
11550
  var createLocalRefMap = (obj) => {
11465
11551
  const refMap = /* @__PURE__ */ new Map();
11466
11552
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -11491,23 +11577,23 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
11491
11577
  /"__refMap\+Siblings:(.*?)"/g,
11492
11578
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
11493
11579
  );
11494
- var lookup = (schema2, path101, filePath) => {
11495
- const parts = getSegmentsFromPath(path101);
11580
+ var lookup = (schema2, path102, filePath) => {
11581
+ const parts = getSegmentsFromPath(path102);
11496
11582
  let val = schema2;
11497
11583
  for (const part of parts) {
11498
11584
  while (val.$ref?.startsWith("#/")) {
11499
- val = val.$ref === path101 ? val : lookup(schema2, val.$ref, filePath);
11585
+ val = val.$ref === path102 ? val : lookup(schema2, val.$ref, filePath);
11500
11586
  }
11501
11587
  if (val[part] === void 0) {
11502
11588
  throw new Error(
11503
- `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: ${path102}`
11504
11590
  );
11505
11591
  }
11506
11592
  val = val[part];
11507
11593
  }
11508
11594
  return val;
11509
11595
  };
11510
- var stringify = (obj, indent = 2) => JSON.stringify(obj, null, indent);
11596
+ var stringify2 = (obj, indent = 2) => JSON.stringify(obj, null, indent);
11511
11597
  var generateCode = (schema2, filePath) => {
11512
11598
  const { refMap, siblingsMap } = createLocalRefMap(schema2);
11513
11599
  const lines = [];
@@ -11524,7 +11610,7 @@ var generateCode = (schema2, filePath) => {
11524
11610
  mergedRefs.set(uniqueKey, varName);
11525
11611
  lines.push(`const ${varName} = {};`);
11526
11612
  }
11527
- const toCode = (obj) => replaceMarkers(stringify(setRefMarkers(obj, refMap)), mergedRefs);
11613
+ const toCode = (obj) => replaceMarkers(stringify2(setRefMarkers(obj, refMap)), mergedRefs);
11528
11614
  const deferred = [];
11529
11615
  for (const [refPath, index] of refMap) {
11530
11616
  const value = lookup(schema2, refPath, filePath);
@@ -11535,7 +11621,7 @@ var generateCode = (schema2, filePath) => {
11535
11621
  const siblingEntry = value.__uniqueRefKey && siblingsMap.get(value.__uniqueRefKey);
11536
11622
  const target = siblingEntry ? deferred : lines;
11537
11623
  target.push(
11538
- siblingEntry ? `Object.assign(__refs[${index}], __refMap["${siblingEntry.refPath}"], ${stringify(siblingEntry.siblings)});` : `Object.assign(__refs[${index}], ${toCode(value)});`,
11624
+ siblingEntry ? `Object.assign(__refs[${index}], __refMap["${siblingEntry.refPath}"], ${stringify2(siblingEntry.siblings)});` : `Object.assign(__refs[${index}], ${toCode(value)});`,
11539
11625
  `Object.defineProperty(__refs[${index}], "__$ref", { value: __refMapPaths[${index}], enumerable: false });`
11540
11626
  );
11541
11627
  }
@@ -11544,7 +11630,7 @@ var generateCode = (schema2, filePath) => {
11544
11630
  const varName = mergedRefs.get(uniqueKey);
11545
11631
  const refIndex = refMap.get(refPath);
11546
11632
  lines.push(
11547
- `Object.assign(${varName}, __refMap["${refPath}"], ${stringify(siblings)});`,
11633
+ `Object.assign(${varName}, __refMap["${refPath}"], ${stringify2(siblings)});`,
11548
11634
  `Object.defineProperty(${varName}, "__$ref", { value: __refMapPaths[${refIndex}], enumerable: false });`
11549
11635
  );
11550
11636
  }
@@ -11745,8 +11831,8 @@ var SchemaManager = class {
11745
11831
  }
11746
11832
  }
11747
11833
  };
11748
- getLatestSchema = (path101) => this.processedSchemas[path101]?.at(0);
11749
- getSchemasForPath = (path101) => this.processedSchemas[path101];
11834
+ getLatestSchema = (path102) => this.processedSchemas[path102]?.at(0);
11835
+ getSchemasForPath = (path102) => this.processedSchemas[path102];
11750
11836
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
11751
11837
  getUrlToFilePathMap = () => {
11752
11838
  const map = /* @__PURE__ */ new Map();
@@ -11806,22 +11892,6 @@ import { glob as glob4 } from "glob";
11806
11892
  import { fromMarkdown } from "mdast-util-from-markdown";
11807
11893
  import { mdxFromMarkdown } from "mdast-util-mdx";
11808
11894
  import { mdxjs } from "micromark-extension-mdxjs";
11809
-
11810
- // src/lib/util/readFrontmatter.ts
11811
- import { readFile as readFile8 } from "node:fs/promises";
11812
- import matter from "gray-matter";
11813
- import { parse as parse2, stringify as stringify2 } from "yaml";
11814
- var yaml = {
11815
- parse: (input5) => parse2(input5) ?? {},
11816
- stringify: (obj) => stringify2(obj)
11817
- };
11818
- var readFrontmatter = async (filePath) => {
11819
- const content = await readFile8(filePath, "utf-8");
11820
- const normalizedContent = content.replace(/\r\n/g, "\n");
11821
- return matter(normalizedContent, { engines: { yaml } });
11822
- };
11823
-
11824
- // src/config/validators/NavigationSchema.ts
11825
11895
  init_ZudokuConfig();
11826
11896
  var extractTitleFromContent = (content) => content.match(/^\s*#\s(.*)$/m)?.at(1);
11827
11897
  var isMdxJsxElement = (node) => node.type === "mdxJsxTextElement";
@@ -14182,14 +14252,14 @@ async function generateSitemap({
14182
14252
 
14183
14253
  // src/vite/prerender/utils.ts
14184
14254
  init_joinUrl();
14185
- var resolveRoutePath = (path101) => {
14186
- const segments = path101.split("/");
14255
+ var resolveRoutePath = (path102) => {
14256
+ const segments = path102.split("/");
14187
14257
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
14188
14258
  return void 0;
14189
14259
  }
14190
14260
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
14191
14261
  };
14192
- var isSkipped = (path101) => path101.includes("*") || /^\d+$/.test(path101);
14262
+ var isSkipped = (path102) => path102.includes("*") || /^\d+$/.test(path102);
14193
14263
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
14194
14264
  if (route.path && isSkipped(route.path)) return [];
14195
14265
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -14545,8 +14615,60 @@ var bundleSSREntry = async (options) => {
14545
14615
 
14546
14616
  // src/cli/portal/v2.ts
14547
14617
  init_package_json();
14618
+
14619
+ // src/cli/init/v2-packages.ts
14620
+ import { existsSync as existsSync5 } from "node:fs";
14621
+ import { readFile as readFile11, writeFile as writeFile13 } from "node:fs/promises";
14622
+ import path46 from "node:path";
14623
+ var CORE_PACKAGES = [
14624
+ "@lukoweb/apitogo",
14625
+ "react",
14626
+ "react-dom"
14627
+ ];
14628
+ var portalPackageSpecs = (version) => [
14629
+ `@lukoweb/apitogo@${version}`,
14630
+ "react@19",
14631
+ "react-dom@19"
14632
+ ];
14633
+ var installCommand = (version) => `npm install --save-dev ${portalPackageSpecs(version).join(" ")}`;
14634
+ function packageNameFrom(name) {
14635
+ const slug = name.trim().toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
14636
+ return slug || "portal";
14637
+ }
14638
+ async function ensurePackageJson(dir, name) {
14639
+ const file = path46.join(dir, "package.json");
14640
+ if (existsSync5(file)) return false;
14641
+ await writeFile13(
14642
+ file,
14643
+ `${JSON.stringify(
14644
+ {
14645
+ name: packageNameFrom(name),
14646
+ version: "0.0.1",
14647
+ private: true,
14648
+ type: "module"
14649
+ },
14650
+ null,
14651
+ 2
14652
+ )}
14653
+ `
14654
+ );
14655
+ return true;
14656
+ }
14657
+ function isPackageInstalled(startDir, name) {
14658
+ let dir = path46.resolve(startDir);
14659
+ for (; ; ) {
14660
+ if (existsSync5(path46.join(dir, "node_modules", name, "package.json")))
14661
+ return true;
14662
+ const parent = path46.dirname(dir);
14663
+ if (parent === dir) return false;
14664
+ dir = parent;
14665
+ }
14666
+ }
14667
+ var missingCorePackages = (dir) => CORE_PACKAGES.filter((name) => !isPackageInstalled(dir, name));
14668
+
14669
+ // src/cli/portal/v2.ts
14548
14670
  function assertPackagesInstalled(resolved, prepared) {
14549
- const require2 = createRequire2(path46.join(resolved.configDir, "package.json"));
14671
+ const require2 = createRequire2(path47.join(resolved.configDir, "package.json"));
14550
14672
  const missing = requiredPackages(prepared.plan).filter((name) => {
14551
14673
  try {
14552
14674
  require2.resolve(name);
@@ -14555,16 +14677,22 @@ function assertPackagesInstalled(resolved, prepared) {
14555
14677
  return true;
14556
14678
  }
14557
14679
  });
14558
- if (missing.length === 0) return;
14559
- throw new ConfigError(
14560
- resolved.configPath,
14561
- missing.map((name) => ({
14680
+ const missingCore = missingCorePackages(resolved.configDir);
14681
+ if (missing.length === 0 && missingCore.length === 0) return;
14682
+ throw new ConfigError(resolved.configPath, [
14683
+ ...missingCore.map((name) => ({
14684
+ code: "PORTAL_PACKAGE_MISSING",
14685
+ path: "",
14686
+ message: `the portal is built with ${name}, which is not installed in this project.`,
14687
+ hint: `Run \`${installCommand(getZudokuPackageJson().version)}\` in ${resolved.configDir}.`
14688
+ })),
14689
+ ...missing.map((name) => ({
14562
14690
  code: "PORTAL_PACKAGE_MISSING",
14563
14691
  path: "",
14564
14692
  message: `the portal registers a feature that needs ${name}, which is not installed.`,
14565
14693
  hint: `Run \`npm install ${name}\` in ${resolved.configDir}.`
14566
14694
  }))
14567
- );
14695
+ ]);
14568
14696
  }
14569
14697
  async function preparePortalWorkspace(dir, mode) {
14570
14698
  const { resolved } = loadConfigV2(dir);
@@ -14593,7 +14721,7 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
14593
14721
  return {
14594
14722
  name: "build",
14595
14723
  hash: () => hash2,
14596
- stillValid: () => access4(path46.join(buildDir, "index.html")).then(
14724
+ stillValid: () => access4(path47.join(buildDir, "index.html")).then(
14597
14725
  () => true,
14598
14726
  () => false
14599
14727
  ),
@@ -14606,11 +14734,11 @@ function portalBuildStep(context, options = {}, build2 = runBuild) {
14606
14734
  process.chdir(originalCwd);
14607
14735
  }
14608
14736
  await rm8(buildDir, { recursive: true, force: true });
14609
- await mkdir12(path46.dirname(buildDir), { recursive: true });
14610
- await rename6(path46.join(root, "dist"), buildDir);
14737
+ await mkdir12(path47.dirname(buildDir), { recursive: true });
14738
+ await rename6(path47.join(root, "dist"), buildDir);
14611
14739
  if (prepared.publishedManifest) {
14612
- await writeFile13(
14613
- path46.join(buildDir, MANIFEST_FILE),
14740
+ await writeFile14(
14741
+ path47.join(buildDir, MANIFEST_FILE),
14614
14742
  `${JSON.stringify(prepared.publishedManifest, null, 2)}
14615
14743
  `
14616
14744
  );
@@ -14639,17 +14767,17 @@ async function buildV2(options) {
14639
14767
  }
14640
14768
 
14641
14769
  // src/cli/check/gateway-online.ts
14642
- import { readFile as readFile12 } from "node:fs/promises";
14770
+ import { readFile as readFile13 } from "node:fs/promises";
14643
14771
  var SPEC_SEND_LIMIT = 5 * 1024 * 1024 + 64 * 1024;
14644
- var issue2 = (code, path101, message, hint) => ({ code, path: path101, message, hint });
14772
+ var issue2 = (code, path102, message, hint) => ({ code, path: path102, message, hint });
14645
14773
  function capabilityIssues(gateway, answer) {
14646
14774
  const can = answer.capabilities;
14647
14775
  const plan2 = `your ${answer.tier} plan`;
14648
14776
  const found = [];
14649
- const unsupported = (path101, what, hint) => found.push(
14777
+ const unsupported = (path102, what, hint) => found.push(
14650
14778
  issue2(
14651
14779
  "GATEWAY_CAPABILITY_UNSUPPORTED",
14652
- path101,
14780
+ path102,
14653
14781
  `${what} is not available on ${plan2}.`,
14654
14782
  hint
14655
14783
  )
@@ -14695,7 +14823,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
14695
14823
  const specFile = gateway.specs[0];
14696
14824
  if (specFile) {
14697
14825
  try {
14698
- const text = await readFile12(specFile, "utf8");
14826
+ const text = await readFile13(specFile, "utf8");
14699
14827
  if (text.length <= SPEC_SEND_LIMIT) spec = text;
14700
14828
  } catch {
14701
14829
  }
@@ -14725,7 +14853,7 @@ async function onlineGatewayRules(gateway, projectId, api, derivedCors = []) {
14725
14853
  async function isConfigV2(dir) {
14726
14854
  try {
14727
14855
  return /"version"\s*:\s*2\b/.test(
14728
- await readFile13(path47.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
14856
+ await readFile14(path48.join(dir, APITOGO_CONFIG_FILENAME), "utf8")
14729
14857
  );
14730
14858
  } catch {
14731
14859
  return false;
@@ -14819,7 +14947,7 @@ async function validatePortalBuild(dir) {
14819
14947
  }
14820
14948
  }
14821
14949
  async function runCheckV2(dir, args = {}, deps = {}) {
14822
- const configPath = path47.join(dir, APITOGO_CONFIG_FILENAME);
14950
+ const configPath = path48.join(dir, APITOGO_CONFIG_FILENAME);
14823
14951
  let report;
14824
14952
  let layout;
14825
14953
  try {
@@ -14908,8 +15036,155 @@ async function checkV2(dir, args, deps = platformDependencies(args)) {
14908
15036
  init_package_json();
14909
15037
 
14910
15038
  // src/cli/init/v2-handler.ts
14911
- import path48 from "node:path";
15039
+ import path50 from "node:path";
14912
15040
  import { createInterface } from "node:readline/promises";
15041
+ init_package_json();
15042
+
15043
+ // src/cli/platform/helpers/npm-build.ts
15044
+ import { spawn } from "node:child_process";
15045
+ import { access as access5, readFile as readFile15 } from "node:fs/promises";
15046
+ import path49 from "node:path";
15047
+ var BUILD_LOG_TAIL_BYTES = 8192;
15048
+ var MIN_NODE_MAJOR = 20;
15049
+ var NpmBuildError = class extends Error {
15050
+ buildLog;
15051
+ exitCode;
15052
+ constructor(message, buildLog, exitCode) {
15053
+ super(message);
15054
+ this.name = "NpmBuildError";
15055
+ this.buildLog = buildLog;
15056
+ this.exitCode = exitCode;
15057
+ }
15058
+ };
15059
+ function parseNodeMajor(version) {
15060
+ const match = /^v?(\d+)/.exec(version.trim());
15061
+ return match ? Number.parseInt(match[1], 10) : Number.NaN;
15062
+ }
15063
+ function assertNodeVersion(required) {
15064
+ const major = parseNodeMajor(process.version);
15065
+ if (Number.isNaN(major) || major < MIN_NODE_MAJOR) {
15066
+ throw new Error(
15067
+ `Node.js ${MIN_NODE_MAJOR}+ is required (current: ${process.version}).`
15068
+ );
15069
+ }
15070
+ if (required) {
15071
+ const requiredMajor = parseNodeMajor(required);
15072
+ if (!Number.isNaN(requiredMajor) && major < requiredMajor) {
15073
+ throw new Error(
15074
+ `Node.js ${requiredMajor}+ is required by nodeVersion option (current: ${process.version}).`
15075
+ );
15076
+ }
15077
+ }
15078
+ }
15079
+ function truncateBuildLog(log, success) {
15080
+ if (success && log.length > BUILD_LOG_TAIL_BYTES) {
15081
+ return log.slice(-BUILD_LOG_TAIL_BYTES);
15082
+ }
15083
+ return log;
15084
+ }
15085
+ async function pathExists(filePath) {
15086
+ try {
15087
+ await access5(filePath);
15088
+ return true;
15089
+ } catch {
15090
+ return false;
15091
+ }
15092
+ }
15093
+ function runCommand(command2, args, cwd, env) {
15094
+ return new Promise((resolve, reject) => {
15095
+ const child = spawn(command2, args, {
15096
+ cwd,
15097
+ env: env ? { ...process.env, ...env } : process.env,
15098
+ shell: process.platform === "win32"
15099
+ });
15100
+ let output4 = "";
15101
+ child.stdout.on("data", (chunk) => {
15102
+ output4 += chunk.toString();
15103
+ });
15104
+ child.stderr.on("data", (chunk) => {
15105
+ output4 += chunk.toString();
15106
+ });
15107
+ child.on("error", reject);
15108
+ child.on("close", (exitCode) => resolve({ exitCode, output: output4 }));
15109
+ });
15110
+ }
15111
+ async function runNpmCommand(args, cwd) {
15112
+ assertNodeVersion();
15113
+ const startedAt = Date.now();
15114
+ const result = await runCommand("npm", args, path49.resolve(cwd));
15115
+ if (result.exitCode !== 0) {
15116
+ throw new NpmBuildError(
15117
+ `npm ${args.join(" ")} exited ${result.exitCode ?? "unknown"}`,
15118
+ result.output,
15119
+ result.exitCode
15120
+ );
15121
+ }
15122
+ return {
15123
+ durationMs: Date.now() - startedAt,
15124
+ log: truncateBuildLog(result.output, true)
15125
+ };
15126
+ }
15127
+ async function runNpmInstall(sourceDirectory, options) {
15128
+ assertNodeVersion(options?.nodeVersion);
15129
+ const cwd = path49.resolve(sourceDirectory);
15130
+ const packageJsonPath = path49.join(cwd, "package.json");
15131
+ if (!await pathExists(packageJsonPath)) {
15132
+ throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
15133
+ }
15134
+ const startedAt = Date.now();
15135
+ const lockPath = path49.join(cwd, "package-lock.json");
15136
+ const installArgs = await pathExists(lockPath) ? ["ci"] : ["install"];
15137
+ const install = await runCommand("npm", installArgs, cwd);
15138
+ const installLog = install.output;
15139
+ if (install.exitCode !== 0) {
15140
+ throw new NpmBuildError(
15141
+ `npm ${installArgs.join(" ")} exited ${install.exitCode ?? "unknown"}`,
15142
+ installLog,
15143
+ install.exitCode
15144
+ );
15145
+ }
15146
+ return {
15147
+ durationMs: Date.now() - startedAt,
15148
+ installLog: truncateBuildLog(installLog, true)
15149
+ };
15150
+ }
15151
+ async function runNpmBuild(sourceDirectory, options) {
15152
+ assertNodeVersion(options?.nodeVersion);
15153
+ const cwd = path49.resolve(sourceDirectory);
15154
+ const packageJsonPath = path49.join(cwd, "package.json");
15155
+ if (!await pathExists(packageJsonPath)) {
15156
+ throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
15157
+ }
15158
+ const startedAt = Date.now();
15159
+ let buildLog = "";
15160
+ const install = await runNpmInstall(sourceDirectory, options);
15161
+ buildLog += install.installLog;
15162
+ const build2 = await runCommand("npm", ["run", "build"], cwd, options?.env);
15163
+ buildLog += build2.output;
15164
+ if (build2.exitCode !== 0) {
15165
+ throw new NpmBuildError(
15166
+ `npm run build exited ${build2.exitCode ?? "unknown"}`,
15167
+ buildLog,
15168
+ build2.exitCode
15169
+ );
15170
+ }
15171
+ const distPath = path49.join(cwd, "dist");
15172
+ const indexPath = path49.join(distPath, "index.html");
15173
+ if (!await pathExists(indexPath)) {
15174
+ throw new NpmBuildError(
15175
+ `Build completed but dist/index.html was not found at ${indexPath}`,
15176
+ buildLog,
15177
+ build2.exitCode
15178
+ );
15179
+ }
15180
+ return {
15181
+ distPath,
15182
+ durationMs: Date.now() - startedAt,
15183
+ buildLog: truncateBuildLog(buildLog, true)
15184
+ };
15185
+ }
15186
+
15187
+ // src/cli/init/v2-handler.ts
14913
15188
  function parseOnlyFlag(value) {
14914
15189
  const services = (value ?? "portal").split(",").map((name) => name.trim()).filter(Boolean);
14915
15190
  const unsupported = services.filter((name) => name !== "portal");
@@ -14961,17 +15236,34 @@ function describePlan(plan2) {
14961
15236
  layoutReason: plan2.layoutReason,
14962
15237
  docsIncluded: plan2.docsIncluded,
14963
15238
  willCreate: plan2.entries.map(
14964
- (entry) => path48.relative(plan2.dir, entry.path)
15239
+ (entry) => path50.relative(plan2.dir, entry.path)
14965
15240
  ),
14966
- willKeep: plan2.keep.map((target) => path48.relative(plan2.dir, target)),
15241
+ willKeep: plan2.keep.map((target) => path50.relative(plan2.dir, target)),
14967
15242
  replacesConfig: plan2.replacesConfig
14968
15243
  };
14969
15244
  }
15245
+ async function setUpPackages(options) {
15246
+ const version = getZudokuPackageJson().version;
15247
+ const command2 = installCommand(version);
15248
+ if (options.layout !== "standalone" || !options.install) {
15249
+ return { packageJsonCreated: false, installed: false, command: command2 };
15250
+ }
15251
+ const packageJsonCreated = await ensurePackageJson(options.dir, options.name);
15252
+ await withSpinner(
15253
+ "Installing @lukoweb/apitogo, react and react-dom\u2026",
15254
+ () => runNpmCommand(
15255
+ ["install", "--save-dev", ...portalPackageSpecs(version)],
15256
+ options.dir
15257
+ ),
15258
+ { silent: options.quiet }
15259
+ );
15260
+ return { packageJsonCreated, installed: true, command: command2 };
15261
+ }
14970
15262
  async function initV2(argv) {
14971
15263
  const json = argv.json === true;
14972
15264
  try {
14973
15265
  parseOnlyFlag(argv.only);
14974
- const dir = path48.resolve(process.cwd(), argv.dir ?? ".");
15266
+ const dir = path50.resolve(process.cwd(), argv.dir ?? ".");
14975
15267
  const options = {
14976
15268
  dir,
14977
15269
  layout: argv.layout,
@@ -15021,6 +15313,13 @@ async function initV2(argv) {
15021
15313
  }
15022
15314
  }
15023
15315
  const result = await applyInitPlan(plan2);
15316
+ const packages = await setUpPackages({
15317
+ dir,
15318
+ layout: plan2.layout,
15319
+ name: argv.name ?? path50.basename(dir),
15320
+ install: argv.install === true,
15321
+ quiet: json
15322
+ });
15024
15323
  if (json) {
15025
15324
  console.log(
15026
15325
  JSON.stringify(
@@ -15028,8 +15327,9 @@ async function initV2(argv) {
15028
15327
  status: "created",
15029
15328
  dir,
15030
15329
  ...describePlan(plan2),
15031
- created: result.created.map((p) => path48.relative(dir, p)),
15032
- kept: result.kept.map((p) => path48.relative(dir, p))
15330
+ created: result.created.map((p) => path50.relative(dir, p)),
15331
+ kept: result.kept.map((p) => path50.relative(dir, p)),
15332
+ packages
15033
15333
  },
15034
15334
  null,
15035
15335
  2
@@ -15038,8 +15338,16 @@ async function initV2(argv) {
15038
15338
  return;
15039
15339
  }
15040
15340
  printResultToConsole(
15041
- `Created ${path48.basename(plan2.configPath)} (config version 2, ${plan2.layout} layout) in ${dir}.`
15341
+ `Created ${path50.basename(plan2.configPath)} (config version 2, ${plan2.layout} layout) in ${dir}.`
15042
15342
  );
15343
+ if (packages.installed)
15344
+ printResultToConsole(
15345
+ "Installed @lukoweb/apitogo, react and react-dom (package.json was created for them)."
15346
+ );
15347
+ else
15348
+ printHintToConsole(
15349
+ `The portal needs @lukoweb/apitogo, react and react-dom in this project. Run: ${packages.command}`
15350
+ );
15043
15351
  printHintToConsole(
15044
15352
  "Config version 2 is a preview: add, remove, check, run, build, plan, status, deploy and secrets read it."
15045
15353
  );
@@ -15064,9 +15372,9 @@ async function initV2(argv) {
15064
15372
  }
15065
15373
 
15066
15374
  // src/cli/services/packages.ts
15067
- import { spawn } from "node:child_process";
15068
- import { existsSync as existsSync5 } from "node:fs";
15069
- import path49 from "node:path";
15375
+ import { spawn as spawn2 } from "node:child_process";
15376
+ import { existsSync as existsSync6 } from "node:fs";
15377
+ import path51 from "node:path";
15070
15378
  var USER_PANEL_PACKAGE = "@lukoweb/apitogo-module-user-panel";
15071
15379
  var BILLING_PLUGIN_PACKAGE = "@lukoweb/apitogo-plugin-dev-portal-billing";
15072
15380
  function packagesForConfig(config2) {
@@ -15081,26 +15389,26 @@ function packagesForConfig(config2) {
15081
15389
  ];
15082
15390
  }
15083
15391
  function isInstalled(dir, name) {
15084
- for (let current = path49.resolve(dir); ; current = path49.dirname(current)) {
15085
- if (existsSync5(path49.join(current, "node_modules", name, "package.json")))
15392
+ for (let current = path51.resolve(dir); ; current = path51.dirname(current)) {
15393
+ if (existsSync6(path51.join(current, "node_modules", name, "package.json")))
15086
15394
  return true;
15087
- if (path49.dirname(current) === current) return false;
15395
+ if (path51.dirname(current) === current) return false;
15088
15396
  }
15089
15397
  }
15090
15398
  function missingPackages(dir, names) {
15091
15399
  return names.filter((name) => !isInstalled(dir, name));
15092
15400
  }
15093
15401
  function detectPackageManager(dir) {
15094
- if (existsSync5(path49.join(dir, "pnpm-lock.yaml"))) return "pnpm";
15095
- if (existsSync5(path49.join(dir, "yarn.lock"))) return "yarn";
15402
+ if (existsSync6(path51.join(dir, "pnpm-lock.yaml"))) return "pnpm";
15403
+ if (existsSync6(path51.join(dir, "yarn.lock"))) return "yarn";
15096
15404
  return "npm";
15097
15405
  }
15098
- function installCommand(manager, names, version) {
15406
+ function installCommand2(manager, names, version) {
15099
15407
  const specs = names.map((name) => `${name}@${version}`);
15100
15408
  return manager === "npm" ? { command: "npm", args: ["install", ...specs] } : { command: manager, args: ["add", ...specs] };
15101
15409
  }
15102
15410
  var runInstaller = (dir, { command: command2, args }) => new Promise((resolve, reject) => {
15103
- const child = spawn(command2, args, {
15411
+ const child = spawn2(command2, args, {
15104
15412
  cwd: dir,
15105
15413
  stdio: "inherit",
15106
15414
  shell: process.platform === "win32"
@@ -15118,7 +15426,7 @@ var runInstaller = (dir, { command: command2, args }) => new Promise((resolve, r
15118
15426
  async function installMissingPackages(dir, config2, version, options) {
15119
15427
  const missing = missingPackages(dir, packagesForConfig(config2));
15120
15428
  if (missing.length === 0) return void 0;
15121
- const command2 = installCommand(detectPackageManager(dir), missing, version);
15429
+ const command2 = installCommand2(detectPackageManager(dir), missing, version);
15122
15430
  const shown = `${command2.command} ${command2.args.join(" ")}`;
15123
15431
  if (!options.install)
15124
15432
  return {
@@ -15127,7 +15435,7 @@ async function installMissingPackages(dir, config2, version, options) {
15127
15435
  reason: "--no-install was given",
15128
15436
  command: shown
15129
15437
  };
15130
- if (!existsSync5(path49.join(dir, "package.json")))
15438
+ if (!existsSync6(path51.join(dir, "package.json")))
15131
15439
  return {
15132
15440
  status: "skipped",
15133
15441
  packages: missing,
@@ -15146,7 +15454,7 @@ var list = (value) => {
15146
15454
  return items.length > 0 ? items : void 0;
15147
15455
  };
15148
15456
  function addOptionsFromArguments(service, argv) {
15149
- const dir = path50.resolve(process.cwd(), argv.dir ?? ".");
15457
+ const dir = path52.resolve(process.cwd(), argv.dir ?? ".");
15150
15458
  const issuers = list(argv.issuer);
15151
15459
  return {
15152
15460
  dir,
@@ -15205,8 +15513,8 @@ function describe(edit, dir) {
15205
15513
  return {
15206
15514
  service: edit.service,
15207
15515
  action: edit.action,
15208
- willCreate: edit.files.map((file) => path50.relative(dir, file.path)),
15209
- keep: edit.keep.map((file) => path50.relative(dir, file)),
15516
+ willCreate: edit.files.map((file) => path52.relative(dir, file.path)),
15517
+ keep: edit.keep.map((file) => path52.relative(dir, file)),
15210
15518
  notes: edit.notes
15211
15519
  };
15212
15520
  }
@@ -15219,7 +15527,7 @@ async function run(action, argv, plan2, deps = {}) {
15219
15527
  `Choose one of ${SERVICES.join(", ")}.`
15220
15528
  );
15221
15529
  }
15222
- const dir = path50.resolve(process.cwd(), argv.dir ?? ".");
15530
+ const dir = path52.resolve(process.cwd(), argv.dir ?? ".");
15223
15531
  if (!await isConfigV2(dir)) {
15224
15532
  throw new ServiceEditError(
15225
15533
  `${action} works with a config version 2 project, and there is none in ${dir}.`,
@@ -15266,7 +15574,7 @@ async function run(action, argv, plan2, deps = {}) {
15266
15574
  {
15267
15575
  status: action === "add" ? "added" : "removed",
15268
15576
  ...describe(edit, dir),
15269
- created: created.map((file) => path50.relative(dir, file)),
15577
+ created: created.map((file) => path52.relative(dir, file)),
15270
15578
  ...install ? { packages: install } : {}
15271
15579
  },
15272
15580
  null,
@@ -15276,7 +15584,7 @@ async function run(action, argv, plan2, deps = {}) {
15276
15584
  return;
15277
15585
  }
15278
15586
  printResultToConsole(
15279
- `${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path50.basename(edit.configPath)}.`
15587
+ `${action === "add" ? "Added" : "Removed"} ${edit.service} in ${path52.basename(edit.configPath)}.`
15280
15588
  );
15281
15589
  } catch (error) {
15282
15590
  const message = error instanceof Error ? error.message : String(error);
@@ -15334,7 +15642,7 @@ var removeService = (argv) => run(
15334
15642
  "remove",
15335
15643
  argv,
15336
15644
  (service) => planRemoveService(service, {
15337
- dir: path50.resolve(process.cwd(), argv.dir ?? ".")
15645
+ dir: path52.resolve(process.cwd(), argv.dir ?? ".")
15338
15646
  })
15339
15647
  );
15340
15648
 
@@ -15482,16 +15790,16 @@ var add_default = {
15482
15790
  };
15483
15791
 
15484
15792
  // src/cli/build/handler.ts
15485
- import path52 from "node:path";
15793
+ import path54 from "node:path";
15486
15794
  init_logger();
15487
15795
  init_package_json();
15488
15796
 
15489
15797
  // src/cli/preview/handler.ts
15490
- import path51 from "node:path";
15798
+ import path53 from "node:path";
15491
15799
  import { preview as vitePreview } from "vite";
15492
15800
  var DEFAULT_PREVIEW_PORT = 4e3;
15493
15801
  async function preview(argv) {
15494
- const dir = path51.resolve(process.cwd(), argv.dir);
15802
+ const dir = path53.resolve(process.cwd(), argv.dir);
15495
15803
  const viteConfig = await getViteConfig(dir, {
15496
15804
  command: "serve",
15497
15805
  mode: "production",
@@ -15534,7 +15842,7 @@ async function build(argv) {
15534
15842
  printDiagnosticsToConsole("");
15535
15843
  printDiagnosticsToConsole("");
15536
15844
  }
15537
- const dir = path52.resolve(process.cwd(), argv.dir);
15845
+ const dir = path54.resolve(process.cwd(), argv.dir);
15538
15846
  try {
15539
15847
  if (await isConfigV2(dir)) {
15540
15848
  const result = await buildV2({ dir, jsonOnly });
@@ -15599,10 +15907,10 @@ var build_default = {
15599
15907
  };
15600
15908
 
15601
15909
  // src/cli/check/handler.ts
15602
- import path59 from "node:path";
15910
+ import path60 from "node:path";
15603
15911
 
15604
15912
  // src/cli/platform/tools/check-publish-readiness.ts
15605
- import path58 from "node:path";
15913
+ import path59 from "node:path";
15606
15914
 
15607
15915
  // src/cli/platform/helpers/dev-portal-backend.ts
15608
15916
  function deriveProvisioningState(backend) {
@@ -15685,12 +15993,12 @@ function formatDevPortalBackendResponse(projectId, backend) {
15685
15993
 
15686
15994
  // src/cli/platform/helpers/dev-portal-manifest.ts
15687
15995
  init_gateway_limits();
15688
- import { existsSync as existsSync6 } from "node:fs";
15689
- import { access as access5, mkdir as mkdir13, readFile as readFile14, writeFile as writeFile14 } from "node:fs/promises";
15690
- import path54 from "node:path";
15996
+ import { existsSync as existsSync7 } from "node:fs";
15997
+ import { access as access6, mkdir as mkdir13, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
15998
+ import path56 from "node:path";
15691
15999
 
15692
16000
  // src/cli/make-config/json-config.ts
15693
- import path53 from "node:path";
16001
+ import path55 from "node:path";
15694
16002
 
15695
16003
  // src/cli/make-config/branding-assets.ts
15696
16004
  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';
@@ -16160,9 +16468,9 @@ function openapiInputForConfig(specRelativePosix) {
16160
16468
  return `./${specRelativePosix}`;
16161
16469
  }
16162
16470
  function toRelativeOpenApiInput(projectDir, inputPath) {
16163
- const resolved = path53.isAbsolute(inputPath) ? inputPath : path53.resolve(projectDir, inputPath);
16164
- const relative = path53.relative(projectDir, resolved);
16165
- const posix = relative.split(path53.sep).join(path53.posix.sep);
16471
+ const resolved = path55.isAbsolute(inputPath) ? inputPath : path55.resolve(projectDir, inputPath);
16472
+ const relative = path55.relative(projectDir, resolved);
16473
+ const posix = relative.split(path55.sep).join(path55.posix.sep);
16166
16474
  if (!posix) {
16167
16475
  throw new Error("OpenAPI path must point to a file.");
16168
16476
  }
@@ -16442,7 +16750,7 @@ function isPlanFree(plan2) {
16442
16750
  return (plan2.priceAmount ?? 0) <= 0;
16443
16751
  }
16444
16752
  function manifestFilePath(siteDirectory) {
16445
- return path54.join(path54.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
16753
+ return path56.join(path56.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
16446
16754
  }
16447
16755
  var STORED_MANIFEST_KEYS = [
16448
16756
  "authentication",
@@ -16667,9 +16975,9 @@ function applyManifestToConfig(config2, manifest) {
16667
16975
  async function readLegacyManifest(_siteDirectory) {
16668
16976
  return null;
16669
16977
  }
16670
- async function pathExists(filePath) {
16978
+ async function pathExists2(filePath) {
16671
16979
  try {
16672
- await access5(filePath);
16980
+ await access6(filePath);
16673
16981
  return true;
16674
16982
  } catch {
16675
16983
  return false;
@@ -16915,39 +17223,39 @@ function resolveBackendSourceDirectory(siteDirectory, sourceDirectory) {
16915
17223
  if (!trimmed) {
16916
17224
  return void 0;
16917
17225
  }
16918
- return path54.resolve(siteDirectory, trimmed);
17226
+ return path56.resolve(siteDirectory, trimmed);
16919
17227
  }
16920
17228
  function resolveBackendOpenApiPath(openApiPath, options) {
16921
17229
  const trimmed = openApiPath?.trim();
16922
17230
  if (!trimmed) {
16923
17231
  return void 0;
16924
17232
  }
16925
- if (path54.isAbsolute(trimmed)) {
17233
+ if (path56.isAbsolute(trimmed)) {
16926
17234
  return trimmed;
16927
17235
  }
16928
- const siteResolved = path54.resolve(options.siteDirectory, trimmed);
16929
- if (existsSync6(siteResolved)) {
17236
+ const siteResolved = path56.resolve(options.siteDirectory, trimmed);
17237
+ if (existsSync7(siteResolved)) {
16930
17238
  return siteResolved;
16931
17239
  }
16932
17240
  const backendDir = options.backendSourceDirectory?.trim();
16933
17241
  if (backendDir) {
16934
- const backendResolved = path54.resolve(backendDir, trimmed);
16935
- if (existsSync6(backendResolved)) {
17242
+ const backendResolved = path56.resolve(backendDir, trimmed);
17243
+ if (existsSync7(backendResolved)) {
16936
17244
  return backendResolved;
16937
17245
  }
16938
17246
  }
16939
17247
  return siteResolved;
16940
17248
  }
16941
17249
  function toSiteRelativeOpenApiInput(siteDirectory, openApiAbsolutePath) {
16942
- const relative = path54.relative(
16943
- path54.resolve(siteDirectory),
16944
- path54.resolve(openApiAbsolutePath)
17250
+ const relative = path56.relative(
17251
+ path56.resolve(siteDirectory),
17252
+ path56.resolve(openApiAbsolutePath)
16945
17253
  );
16946
- const posix = relative.split(path54.sep).join("/");
17254
+ const posix = relative.split(path56.sep).join("/");
16947
17255
  if (!posix || posix === ".") {
16948
17256
  return "./";
16949
17257
  }
16950
- if (path54.isAbsolute(posix) || posix.startsWith("..")) {
17258
+ if (path56.isAbsolute(posix) || posix.startsWith("..")) {
16951
17259
  return posix;
16952
17260
  }
16953
17261
  return posix.startsWith("./") ? posix : `./${posix}`;
@@ -16985,8 +17293,8 @@ function applyOpenApiToSiteConfig(config2, options) {
16985
17293
  }
16986
17294
  async function readManifest2(siteDirectory) {
16987
17295
  const filePath = manifestFilePath(siteDirectory);
16988
- if (await pathExists(filePath)) {
16989
- const raw = await readFile14(filePath, "utf8");
17296
+ if (await pathExists2(filePath)) {
17297
+ const raw = await readFile16(filePath, "utf8");
16990
17298
  const config2 = JSON.parse(raw);
16991
17299
  return extractManifestFromConfig(config2);
16992
17300
  }
@@ -16994,10 +17302,10 @@ async function readManifest2(siteDirectory) {
16994
17302
  }
16995
17303
  async function writeManifest2(siteDirectory, manifest) {
16996
17304
  const filePath = manifestFilePath(siteDirectory);
16997
- await mkdir13(path54.dirname(filePath), { recursive: true });
17305
+ await mkdir13(path56.dirname(filePath), { recursive: true });
16998
17306
  let config2 = {};
16999
- if (await pathExists(filePath)) {
17000
- const raw = await readFile14(filePath, "utf8");
17307
+ if (await pathExists2(filePath)) {
17308
+ const raw = await readFile16(filePath, "utf8");
17001
17309
  config2 = JSON.parse(raw);
17002
17310
  }
17003
17311
  const {
@@ -17006,21 +17314,21 @@ async function writeManifest2(siteDirectory, manifest) {
17006
17314
  ...safeManifest
17007
17315
  } = manifest;
17008
17316
  config2 = applyManifestToConfig(config2, safeManifest);
17009
- await writeFile14(filePath, `${JSON.stringify(config2, null, 2)}
17317
+ await writeFile15(filePath, `${JSON.stringify(config2, null, 2)}
17010
17318
  `, "utf8");
17011
17319
  return filePath;
17012
17320
  }
17013
17321
 
17014
17322
  // src/cli/platform/helpers/dev-portal-secrets.ts
17015
17323
  import {
17016
- access as access6,
17324
+ access as access7,
17017
17325
  appendFile,
17018
17326
  mkdir as mkdir14,
17019
- readFile as readFile15,
17327
+ readFile as readFile17,
17020
17328
  unlink,
17021
- writeFile as writeFile15
17329
+ writeFile as writeFile16
17022
17330
  } from "node:fs/promises";
17023
- import path55 from "node:path";
17331
+ import path57 from "node:path";
17024
17332
  var ENV_FILENAME = ".env";
17025
17333
  var COLLAPSED_UPPERCASE_ALIASES2 = {
17026
17334
  SECRETKEY: "secretKey",
@@ -17122,7 +17430,7 @@ function applyEnvOverrides2(config2, env) {
17122
17430
  }
17123
17431
  async function readEnvFile(filePath) {
17124
17432
  try {
17125
- const raw = await readFile15(filePath, "utf8");
17433
+ const raw = await readFile17(filePath, "utf8");
17126
17434
  const env = {};
17127
17435
  for (const line2 of raw.split("\n")) {
17128
17436
  const trimmed = line2.trim();
@@ -17139,12 +17447,12 @@ async function readEnvFile(filePath) {
17139
17447
  }
17140
17448
  }
17141
17449
  async function loadSiteEnv(siteDirectory) {
17142
- const resolvedDirectory = path55.resolve(siteDirectory);
17450
+ const resolvedDirectory = path57.resolve(siteDirectory);
17143
17451
  const merged = { ...process.env };
17144
17452
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
17145
17453
  Object.assign(
17146
17454
  merged,
17147
- await readEnvFile(path55.join(resolvedDirectory, fileName))
17455
+ await readEnvFile(path57.join(resolvedDirectory, fileName))
17148
17456
  );
17149
17457
  }
17150
17458
  return merged;
@@ -17181,7 +17489,7 @@ function buildAuthSecretsJson(secrets2, options) {
17181
17489
  return payload;
17182
17490
  }
17183
17491
  function envFilePath(siteDirectory) {
17184
- return path55.join(path55.resolve(siteDirectory), ENV_FILENAME);
17492
+ return path57.join(path57.resolve(siteDirectory), ENV_FILENAME);
17185
17493
  }
17186
17494
  function createEnvContent() {
17187
17495
  return [
@@ -17245,7 +17553,7 @@ function validateSecretsForPublish(manifest, secrets2, emailOptions) {
17245
17553
  }
17246
17554
  async function siteEnvFileHasEntries(siteDirectory) {
17247
17555
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
17248
- const loaded = await readEnvFile(path55.join(siteDirectory, fileName));
17556
+ const loaded = await readEnvFile(path57.join(siteDirectory, fileName));
17249
17557
  if (Object.keys(loaded).length > 0) {
17250
17558
  return true;
17251
17559
  }
@@ -17253,7 +17561,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
17253
17561
  return false;
17254
17562
  }
17255
17563
  async function resolvePublishConfig(siteDirectory, emailOptions) {
17256
- const resolvedDirectory = path55.resolve(siteDirectory);
17564
+ const resolvedDirectory = path57.resolve(siteDirectory);
17257
17565
  const manifestRaw = await readManifest2(resolvedDirectory);
17258
17566
  if (!manifestRaw) {
17259
17567
  throw new Error("apitogo.config.json not found in sourceDirectory.");
@@ -17286,20 +17594,20 @@ function envFileHasActiveAssignments(content) {
17286
17594
  });
17287
17595
  }
17288
17596
  async function writeScaffoldEnv(siteDirectory) {
17289
- const resolvedDirectory = path55.resolve(siteDirectory);
17597
+ const resolvedDirectory = path57.resolve(siteDirectory);
17290
17598
  const filesWritten = [];
17291
17599
  const envPath = envFilePath(resolvedDirectory);
17292
17600
  try {
17293
- await access6(envPath);
17601
+ await access7(envPath);
17294
17602
  } catch {
17295
17603
  await mkdir14(resolvedDirectory, { recursive: true });
17296
- await writeFile15(envPath, createEnvContent(), "utf8");
17604
+ await writeFile16(envPath, createEnvContent(), "utf8");
17297
17605
  filesWritten.push(ENV_FILENAME);
17298
17606
  }
17299
17607
  for (const legacyName of [".env.example"]) {
17300
- const legacyPath = path55.join(resolvedDirectory, legacyName);
17608
+ const legacyPath = path57.join(resolvedDirectory, legacyName);
17301
17609
  try {
17302
- const legacy = await readFile15(legacyPath, "utf8");
17610
+ const legacy = await readFile17(legacyPath, "utf8");
17303
17611
  if (!envFileHasActiveAssignments(legacy)) {
17304
17612
  await unlink(legacyPath);
17305
17613
  filesWritten.push(`removed:${legacyName}`);
@@ -17307,10 +17615,10 @@ async function writeScaffoldEnv(siteDirectory) {
17307
17615
  } catch {
17308
17616
  }
17309
17617
  }
17310
- const gitignorePath = path55.join(resolvedDirectory, ".gitignore");
17618
+ const gitignorePath = path57.join(resolvedDirectory, ".gitignore");
17311
17619
  let gitignore = "";
17312
17620
  try {
17313
- gitignore = await readFile15(gitignorePath, "utf8");
17621
+ gitignore = await readFile17(gitignorePath, "utf8");
17314
17622
  } catch {
17315
17623
  gitignore = "";
17316
17624
  }
@@ -17322,7 +17630,7 @@ async function writeScaffoldEnv(siteDirectory) {
17322
17630
  if (!hasEntry) {
17323
17631
  const suffix = gitignore.length === 0 ? "" : gitignore.endsWith("\n") ? "" : "\n";
17324
17632
  if (gitignore.length === 0) {
17325
- await writeFile15(gitignorePath, `${entry}
17633
+ await writeFile16(gitignorePath, `${entry}
17326
17634
  `, "utf8");
17327
17635
  } else {
17328
17636
  await appendFile(gitignorePath, `${suffix}${entry}
@@ -17342,13 +17650,13 @@ var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apit
17342
17650
 
17343
17651
  // src/cli/platform/helpers/dev-portal-site-validation.ts
17344
17652
  init_gateway_limits();
17345
- import { readFile as readFile16 } from "node:fs/promises";
17653
+ import { readFile as readFile18 } from "node:fs/promises";
17346
17654
  import { createRequire as createRequire3 } from "node:module";
17347
- import path56 from "node:path";
17655
+ import path58 from "node:path";
17348
17656
  var cachedFallbackTs;
17349
17657
  async function loadTypeScriptForSite(sourceDirectory) {
17350
17658
  const require2 = createRequire3(
17351
- path56.join(path56.resolve(sourceDirectory), "package.json")
17659
+ path58.join(path58.resolve(sourceDirectory), "package.json")
17352
17660
  );
17353
17661
  try {
17354
17662
  return require2("typescript");
@@ -17394,8 +17702,8 @@ async function referencedFileExists(sourceDirectory, reference) {
17394
17702
  if (/^https?:\/\//i.test(reference)) {
17395
17703
  return true;
17396
17704
  }
17397
- return pathExists(
17398
- path56.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
17705
+ return pathExists2(
17706
+ path58.resolve(sourceDirectory, reference.replace(/^\.\//, ""))
17399
17707
  );
17400
17708
  }
17401
17709
  async function validateSiteConfigStructure(config2, sourceDirectory) {
@@ -17510,17 +17818,17 @@ var DEFAULT_TSX_CANDIDATES = [
17510
17818
  "landing/LandingPage.tsx"
17511
17819
  ];
17512
17820
  async function validateDevPortalSiteConfig(sourceDirectory, options) {
17513
- const resolvedDir = path56.resolve(sourceDirectory);
17821
+ const resolvedDir = path58.resolve(sourceDirectory);
17514
17822
  const issues = [];
17515
17823
  const checkedFiles = [];
17516
17824
  const skippedChecks = [];
17517
- const jsonPath = path56.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
17518
- if (await pathExists(jsonPath)) {
17825
+ const jsonPath = path58.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
17826
+ if (await pathExists2(jsonPath)) {
17519
17827
  checkedFiles.push(APITOGO_CONFIG_FILENAME2);
17520
17828
  let parsed;
17521
17829
  let parseFailed = false;
17522
17830
  try {
17523
- parsed = JSON.parse(await readFile16(jsonPath, "utf8"));
17831
+ parsed = JSON.parse(await readFile18(jsonPath, "utf8"));
17524
17832
  } catch (error) {
17525
17833
  parseFailed = true;
17526
17834
  issues.push({
@@ -17546,7 +17854,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
17546
17854
  );
17547
17855
  const existingTsxFiles = [];
17548
17856
  for (const relativeFile of tsxFiles) {
17549
- if (await pathExists(path56.join(resolvedDir, relativeFile))) {
17857
+ if (await pathExists2(path58.join(resolvedDir, relativeFile))) {
17550
17858
  existingTsxFiles.push(relativeFile);
17551
17859
  }
17552
17860
  }
@@ -17559,8 +17867,8 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
17559
17867
  } else {
17560
17868
  for (const relativeFile of existingTsxFiles) {
17561
17869
  checkedFiles.push(relativeFile);
17562
- const content = await readFile16(
17563
- path56.join(resolvedDir, relativeFile),
17870
+ const content = await readFile18(
17871
+ path58.join(resolvedDir, relativeFile),
17564
17872
  "utf8"
17565
17873
  );
17566
17874
  issues.push(
@@ -17595,134 +17903,6 @@ function buildSiteValidationResponseFields(result) {
17595
17903
  };
17596
17904
  }
17597
17905
 
17598
- // src/cli/platform/helpers/npm-build.ts
17599
- import { spawn as spawn2 } from "node:child_process";
17600
- import { access as access7, readFile as readFile17 } from "node:fs/promises";
17601
- import path57 from "node:path";
17602
- var BUILD_LOG_TAIL_BYTES = 8192;
17603
- var MIN_NODE_MAJOR = 20;
17604
- var NpmBuildError = class extends Error {
17605
- buildLog;
17606
- exitCode;
17607
- constructor(message, buildLog, exitCode) {
17608
- super(message);
17609
- this.name = "NpmBuildError";
17610
- this.buildLog = buildLog;
17611
- this.exitCode = exitCode;
17612
- }
17613
- };
17614
- function parseNodeMajor(version) {
17615
- const match = /^v?(\d+)/.exec(version.trim());
17616
- return match ? Number.parseInt(match[1], 10) : Number.NaN;
17617
- }
17618
- function assertNodeVersion(required) {
17619
- const major = parseNodeMajor(process.version);
17620
- if (Number.isNaN(major) || major < MIN_NODE_MAJOR) {
17621
- throw new Error(
17622
- `Node.js ${MIN_NODE_MAJOR}+ is required (current: ${process.version}).`
17623
- );
17624
- }
17625
- if (required) {
17626
- const requiredMajor = parseNodeMajor(required);
17627
- if (!Number.isNaN(requiredMajor) && major < requiredMajor) {
17628
- throw new Error(
17629
- `Node.js ${requiredMajor}+ is required by nodeVersion option (current: ${process.version}).`
17630
- );
17631
- }
17632
- }
17633
- }
17634
- function truncateBuildLog(log, success) {
17635
- if (success && log.length > BUILD_LOG_TAIL_BYTES) {
17636
- return log.slice(-BUILD_LOG_TAIL_BYTES);
17637
- }
17638
- return log;
17639
- }
17640
- async function pathExists2(filePath) {
17641
- try {
17642
- await access7(filePath);
17643
- return true;
17644
- } catch {
17645
- return false;
17646
- }
17647
- }
17648
- function runCommand(command2, args, cwd, env) {
17649
- return new Promise((resolve, reject) => {
17650
- const child = spawn2(command2, args, {
17651
- cwd,
17652
- env: env ? { ...process.env, ...env } : process.env,
17653
- shell: process.platform === "win32"
17654
- });
17655
- let output4 = "";
17656
- child.stdout.on("data", (chunk) => {
17657
- output4 += chunk.toString();
17658
- });
17659
- child.stderr.on("data", (chunk) => {
17660
- output4 += chunk.toString();
17661
- });
17662
- child.on("error", reject);
17663
- child.on("close", (exitCode) => resolve({ exitCode, output: output4 }));
17664
- });
17665
- }
17666
- async function runNpmInstall(sourceDirectory, options) {
17667
- assertNodeVersion(options?.nodeVersion);
17668
- const cwd = path57.resolve(sourceDirectory);
17669
- const packageJsonPath = path57.join(cwd, "package.json");
17670
- if (!await pathExists2(packageJsonPath)) {
17671
- throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
17672
- }
17673
- const startedAt = Date.now();
17674
- const lockPath = path57.join(cwd, "package-lock.json");
17675
- const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
17676
- const install = await runCommand("npm", installArgs, cwd);
17677
- const installLog = install.output;
17678
- if (install.exitCode !== 0) {
17679
- throw new NpmBuildError(
17680
- `npm ${installArgs.join(" ")} exited ${install.exitCode ?? "unknown"}`,
17681
- installLog,
17682
- install.exitCode
17683
- );
17684
- }
17685
- return {
17686
- durationMs: Date.now() - startedAt,
17687
- installLog: truncateBuildLog(installLog, true)
17688
- };
17689
- }
17690
- async function runNpmBuild(sourceDirectory, options) {
17691
- assertNodeVersion(options?.nodeVersion);
17692
- const cwd = path57.resolve(sourceDirectory);
17693
- const packageJsonPath = path57.join(cwd, "package.json");
17694
- if (!await pathExists2(packageJsonPath)) {
17695
- throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
17696
- }
17697
- const startedAt = Date.now();
17698
- let buildLog = "";
17699
- const install = await runNpmInstall(sourceDirectory, options);
17700
- buildLog += install.installLog;
17701
- const build2 = await runCommand("npm", ["run", "build"], cwd, options?.env);
17702
- buildLog += build2.output;
17703
- if (build2.exitCode !== 0) {
17704
- throw new NpmBuildError(
17705
- `npm run build exited ${build2.exitCode ?? "unknown"}`,
17706
- buildLog,
17707
- build2.exitCode
17708
- );
17709
- }
17710
- const distPath = path57.join(cwd, "dist");
17711
- const indexPath = path57.join(distPath, "index.html");
17712
- if (!await pathExists2(indexPath)) {
17713
- throw new NpmBuildError(
17714
- `Build completed but dist/index.html was not found at ${indexPath}`,
17715
- buildLog,
17716
- build2.exitCode
17717
- );
17718
- }
17719
- return {
17720
- distPath,
17721
- durationMs: Date.now() - startedAt,
17722
- buildLog: truncateBuildLog(buildLog, true)
17723
- };
17724
- }
17725
-
17726
17906
  // src/cli/platform/helpers/paid-gateway-platform-compat.ts
17727
17907
  function listPaidManifestPlans(plans) {
17728
17908
  return (plans ?? []).filter((plan2) => !isPlanFree(plan2)).map((plan2) => ({
@@ -18092,7 +18272,7 @@ function validateManifestForPlatformPublish(manifest) {
18092
18272
 
18093
18273
  // src/cli/platform/tools/check-publish-readiness.ts
18094
18274
  async function checkPublishReadiness(client, _config, args) {
18095
- const sourceDirectory = path58.resolve(args.sourceDirectory);
18275
+ const sourceDirectory = path59.resolve(args.sourceDirectory);
18096
18276
  const manifest = await readManifest2(sourceDirectory) ?? createScaffoldManifest();
18097
18277
  const emailOptions = await resolveEmailOptionsForPublish(
18098
18278
  client,
@@ -18170,7 +18350,7 @@ async function checkPublishReadiness(client, _config, args) {
18170
18350
 
18171
18351
  // src/cli/check/handler.ts
18172
18352
  async function check(argv) {
18173
- const sourceDirectory = path59.resolve(process.cwd(), argv.dir);
18353
+ const sourceDirectory = path60.resolve(process.cwd(), argv.dir);
18174
18354
  if (await isConfigV2(sourceDirectory)) {
18175
18355
  await checkV2(sourceDirectory, argv);
18176
18356
  return;
@@ -18234,14 +18414,14 @@ var check_default = {
18234
18414
 
18235
18415
  // src/cli/make-config/handler.ts
18236
18416
  import { constants as constants2 } from "node:fs";
18237
- import { access as access12, mkdir as mkdir17, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
18238
- import path69 from "node:path";
18417
+ import { access as access12, mkdir as mkdir17, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
18418
+ import path70 from "node:path";
18239
18419
  import { stdin as input2 } from "node:process";
18240
18420
  import { glob as glob8 } from "glob";
18241
18421
 
18242
18422
  // src/cli/platform/helpers/openapi-action-keys.ts
18243
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "node:fs";
18244
- import path60 from "node:path";
18423
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
18424
+ import path61 from "node:path";
18245
18425
  import YAML from "yaml";
18246
18426
  var HTTP_METHODS = [
18247
18427
  "get",
@@ -18310,7 +18490,7 @@ function extractGatewayActionKeysFromOpenApiDocument(document) {
18310
18490
  function extractGatewayActionKeysFromOpenApiFile(filePath) {
18311
18491
  try {
18312
18492
  const raw = readFileSync4(filePath, "utf8");
18313
- const ext = path60.extname(filePath).toLowerCase();
18493
+ const ext = path61.extname(filePath).toLowerCase();
18314
18494
  const parsed = ext === ".json" ? JSON.parse(raw) : YAML.parse(raw);
18315
18495
  return extractGatewayActionKeysFromOpenApiDocument(parsed);
18316
18496
  } catch {
@@ -18331,8 +18511,8 @@ function resolveConfigOpenApiFilePath(siteDirectory, config2) {
18331
18511
  }
18332
18512
  }
18333
18513
  for (const candidate of candidates) {
18334
- const resolved = path60.isAbsolute(candidate) ? candidate : path60.resolve(siteDirectory, candidate);
18335
- if (existsSync7(resolved)) {
18514
+ const resolved = path61.isAbsolute(candidate) ? candidate : path61.resolve(siteDirectory, candidate);
18515
+ if (existsSync8(resolved)) {
18336
18516
  return resolved;
18337
18517
  }
18338
18518
  }
@@ -18346,8 +18526,8 @@ function loadOpenApiActionKeysForSite(siteDirectory, config2) {
18346
18526
  return extractGatewayActionKeysFromOpenApiFile(filePath);
18347
18527
  }
18348
18528
  function loadOpenApiActionKeysFromSiteDirectory(siteDirectory) {
18349
- const configPath = path60.join(siteDirectory, "apitogo.config.json");
18350
- if (!existsSync7(configPath)) {
18529
+ const configPath = path61.join(siteDirectory, "apitogo.config.json");
18530
+ if (!existsSync8(configPath)) {
18351
18531
  return [];
18352
18532
  }
18353
18533
  try {
@@ -18374,12 +18554,12 @@ function withDefaultIncludedActionKeys(plan2, actionKeys) {
18374
18554
  }
18375
18555
 
18376
18556
  // src/cli/scaffold/dev-portal-config-pages.ts
18377
- import { access as access8, readFile as readFile18, rename as rename7, rm as rm9, writeFile as writeFile16 } from "node:fs/promises";
18378
- import path61 from "node:path";
18557
+ import { access as access8, readFile as readFile19, rename as rename7, rm as rm9, writeFile as writeFile17 } from "node:fs/promises";
18558
+ import path62 from "node:path";
18379
18559
  async function writeConfigAtomically(filePath, content) {
18380
18560
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
18381
18561
  try {
18382
- await writeFile16(temporaryPath, content, "utf8");
18562
+ await writeFile17(temporaryPath, content, "utf8");
18383
18563
  await rename7(temporaryPath, filePath);
18384
18564
  } catch (error) {
18385
18565
  await rm9(temporaryPath, { force: true });
@@ -18388,7 +18568,7 @@ async function writeConfigAtomically(filePath, content) {
18388
18568
  }
18389
18569
  async function resolveApitogoConfigPath(sourceDirectory) {
18390
18570
  for (const filename of ["apitogo.config.tsx", "apitogo.config.jsx"]) {
18391
- const configPath = path61.join(sourceDirectory, filename);
18571
+ const configPath = path62.join(sourceDirectory, filename);
18392
18572
  try {
18393
18573
  await access8(configPath);
18394
18574
  return configPath;
@@ -19139,7 +19319,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
19139
19319
  if (!configPath) {
19140
19320
  return { updated: false };
19141
19321
  }
19142
- const original = await readFile18(configPath, "utf8");
19322
+ const original = await readFile19(configPath, "utf8");
19143
19323
  const patched = patchApitogoConfigForNewPage(original, slug, label, {
19144
19324
  typescript: configPath.endsWith(".tsx")
19145
19325
  });
@@ -19151,18 +19331,18 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
19151
19331
  }
19152
19332
 
19153
19333
  // src/cli/scaffold/wire-openapi.ts
19154
- import { access as access10, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
19155
- import path66 from "node:path";
19334
+ import { access as access10, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
19335
+ import path67 from "node:path";
19156
19336
 
19157
19337
  // src/cli/platform/helpers/openapi.ts
19158
19338
  import { promises as fs6 } from "node:fs";
19159
- import path63 from "node:path";
19339
+ import path64 from "node:path";
19160
19340
  import SwaggerParser from "@apidevtools/swagger-parser";
19161
19341
  import YAML2 from "yaml";
19162
19342
 
19163
19343
  // src/cli/scaffold/discover-openapi-files.ts
19164
19344
  import { promises as fs5 } from "node:fs";
19165
- import path62 from "node:path";
19345
+ import path63 from "node:path";
19166
19346
  var OPENAPI_BASENAMES = [
19167
19347
  "openapi.yaml",
19168
19348
  "openapi.yml",
@@ -19184,13 +19364,13 @@ var SKIP_OPENAPI_SEARCH_DIRS = /* @__PURE__ */ new Set([
19184
19364
  ".apitogo"
19185
19365
  ]);
19186
19366
  async function collectFromDir(dir, searchedDirectories, candidates) {
19187
- const resolved = path62.resolve(dir);
19367
+ const resolved = path63.resolve(dir);
19188
19368
  if (searchedDirectories.includes(resolved)) {
19189
19369
  return;
19190
19370
  }
19191
19371
  searchedDirectories.push(resolved);
19192
19372
  for (const name of OPENAPI_BASENAMES) {
19193
- const candidate = path62.join(resolved, name);
19373
+ const candidate = path63.join(resolved, name);
19194
19374
  try {
19195
19375
  await fs5.access(candidate);
19196
19376
  candidates.push(candidate);
@@ -19205,8 +19385,8 @@ async function collectSiteOpenApiFiles(siteDirectory) {
19205
19385
  return { candidates: [...new Set(candidates)], searchedDirectories };
19206
19386
  }
19207
19387
  async function collectNearbyOpenApiFiles(siteDirectory) {
19208
- const site = path62.resolve(siteDirectory);
19209
- const parent = path62.dirname(site);
19388
+ const site = path63.resolve(siteDirectory);
19389
+ const parent = path63.dirname(site);
19210
19390
  const searchedDirectories = [];
19211
19391
  const candidates = [];
19212
19392
  if (parent && parent !== site) {
@@ -19217,8 +19397,8 @@ async function collectNearbyOpenApiFiles(siteDirectory) {
19217
19397
  if (!entry.isDirectory() || SKIP_OPENAPI_SEARCH_DIRS.has(entry.name)) {
19218
19398
  continue;
19219
19399
  }
19220
- const sibling = path62.join(parent, entry.name);
19221
- if (path62.resolve(sibling) === site) {
19400
+ const sibling = path63.join(parent, entry.name);
19401
+ if (path63.resolve(sibling) === site) {
19222
19402
  continue;
19223
19403
  }
19224
19404
  await collectFromDir(sibling, searchedDirectories, candidates);
@@ -19246,7 +19426,7 @@ function parseOpenApiObject(doc) {
19246
19426
  };
19247
19427
  }
19248
19428
  function liteParseOpenApi(content, filePath) {
19249
- const ext = path62.extname(filePath).toLowerCase();
19429
+ const ext = path63.extname(filePath).toLowerCase();
19250
19430
  if (ext === ".json") {
19251
19431
  try {
19252
19432
  const parsed = JSON.parse(content);
@@ -19311,9 +19491,9 @@ async function discoverNearbyOpenApi(siteDirectory) {
19311
19491
  };
19312
19492
  }
19313
19493
  async function validateOpenApiFile(filePath) {
19314
- const resolved = path63.resolve(filePath);
19494
+ const resolved = path64.resolve(filePath);
19315
19495
  const content = await fs6.readFile(resolved, "utf8");
19316
- const ext = path63.extname(resolved).toLowerCase();
19496
+ const ext = path64.extname(resolved).toLowerCase();
19317
19497
  let parsed;
19318
19498
  try {
19319
19499
  parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
@@ -19355,8 +19535,8 @@ async function validateOpenApiFile(filePath) {
19355
19535
  }
19356
19536
 
19357
19537
  // src/cli/scaffold/scaffold-dev-portal-site.ts
19358
- import { mkdir as mkdir15, readFile as readFile19, writeFile as writeFile17 } from "node:fs/promises";
19359
- import path65 from "node:path";
19538
+ import { mkdir as mkdir15, readFile as readFile20, writeFile as writeFile18 } from "node:fs/promises";
19539
+ import path66 from "node:path";
19360
19540
 
19361
19541
  // src/cli/scaffold/apitogo-npm-packages.ts
19362
19542
  var DEFAULT_CREATE_APITOGO_PACKAGE2 = "@lukoweb/create-apitogo@latest";
@@ -19444,7 +19624,7 @@ var DOC_TOOL_LOCAL_PACKAGE_PATHS = {
19444
19624
  // src/cli/scaffold/create-apitogo-cli.ts
19445
19625
  import { spawn as spawn3 } from "node:child_process";
19446
19626
  import { access as access9, rm as rm10 } from "node:fs/promises";
19447
- import path64 from "node:path";
19627
+ import path65 from "node:path";
19448
19628
  var SKIP_NEARBY_DISCOVERY_ENV = "APITOGO_SKIP_NEARBY_DISCOVERY";
19449
19629
  var CreateApitogoCliError = class extends Error {
19450
19630
  exitCode;
@@ -19461,9 +19641,9 @@ function resolveDocToolPath(explicit) {
19461
19641
  return value || void 0;
19462
19642
  }
19463
19643
  function splitOutputDirectory(outputDirectory) {
19464
- const resolvedOutputDirectory = path64.resolve(outputDirectory);
19465
- const projectName = path64.basename(resolvedOutputDirectory);
19466
- const parentDirectory = path64.dirname(resolvedOutputDirectory);
19644
+ const resolvedOutputDirectory = path65.resolve(outputDirectory);
19645
+ const projectName = path65.basename(resolvedOutputDirectory);
19646
+ const parentDirectory = path65.dirname(resolvedOutputDirectory);
19467
19647
  if (!projectName || projectName === "." || projectName === "..") {
19468
19648
  throw new Error(
19469
19649
  "outputDirectory must be a named folder (e.g. ./dev-portal-site), not the current directory."
@@ -19489,7 +19669,7 @@ async function directoryHasEntries(dir) {
19489
19669
  }
19490
19670
  }
19491
19671
  function resolveLocalCreateApitogoEntry(docToolPath) {
19492
- return path64.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
19672
+ return path65.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
19493
19673
  }
19494
19674
  async function resolveCreateApitogoInvocation(options) {
19495
19675
  const docToolPath = resolveDocToolPath(options.docToolPath);
@@ -19571,7 +19751,7 @@ async function runCreateApitogoDevPortal(options) {
19571
19751
  result.exitCode
19572
19752
  );
19573
19753
  }
19574
- if (!await pathExists3(path64.join(resolvedOutputDirectory, "package.json"))) {
19754
+ if (!await pathExists3(path65.join(resolvedOutputDirectory, "package.json"))) {
19575
19755
  throw new CreateApitogoCliError(
19576
19756
  `create-apitogo completed but package.json was not found at ${resolvedOutputDirectory}`,
19577
19757
  result.output,
@@ -19630,7 +19810,7 @@ function ensureRequiredApitogoModules(pkg, options) {
19630
19810
  ]
19631
19811
  ]) {
19632
19812
  if (options.docToolPath) {
19633
- deps[moduleName] = `file:${path65.join(options.docToolPath, localPath)}`;
19813
+ deps[moduleName] = `file:${path66.join(options.docToolPath, localPath)}`;
19634
19814
  continue;
19635
19815
  }
19636
19816
  deps[moduleName] = `npm:${moduleName}@${moduleAliasVersion}`;
@@ -19661,7 +19841,7 @@ function rewritePackageJson(raw, options) {
19661
19841
  DOC_TOOL_LOCAL_PACKAGE_PATHS
19662
19842
  )) {
19663
19843
  if (dep in deps) {
19664
- deps[dep] = `file:${path65.join(options.docToolPath, relativePath)}`;
19844
+ deps[dep] = `file:${path66.join(options.docToolPath, relativePath)}`;
19665
19845
  linkedWorkspacePackage = true;
19666
19846
  }
19667
19847
  }
@@ -19761,24 +19941,24 @@ function patchDashboardPageConfig(content) {
19761
19941
  );
19762
19942
  }
19763
19943
  async function ensureAccountPlansPage(outputDirectory) {
19764
- const pagePath = path65.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
19944
+ const pagePath = path66.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
19765
19945
  try {
19766
- await readFile19(pagePath, "utf8");
19946
+ await readFile20(pagePath, "utf8");
19767
19947
  return void 0;
19768
19948
  } catch {
19769
- await mkdir15(path65.dirname(pagePath), { recursive: true });
19770
- await writeFile17(pagePath, ACCOUNT_PLANS_PAGE);
19949
+ await mkdir15(path66.dirname(pagePath), { recursive: true });
19950
+ await writeFile18(pagePath, ACCOUNT_PLANS_PAGE);
19771
19951
  return ACCOUNT_PLANS_PAGE_PATH;
19772
19952
  }
19773
19953
  }
19774
19954
  async function ensureDashboardPage(outputDirectory) {
19775
- const pagePath = path65.join(outputDirectory, DASHBOARD_PAGE_PATH);
19955
+ const pagePath = path66.join(outputDirectory, DASHBOARD_PAGE_PATH);
19776
19956
  try {
19777
- await readFile19(pagePath, "utf8");
19957
+ await readFile20(pagePath, "utf8");
19778
19958
  return void 0;
19779
19959
  } catch {
19780
- await mkdir15(path65.dirname(pagePath), { recursive: true });
19781
- await writeFile17(pagePath, DASHBOARD_PAGE);
19960
+ await mkdir15(path66.dirname(pagePath), { recursive: true });
19961
+ await writeFile18(pagePath, DASHBOARD_PAGE);
19782
19962
  return DASHBOARD_PAGE_PATH;
19783
19963
  }
19784
19964
  }
@@ -19834,10 +20014,10 @@ function patchApitogoConfig(content, options) {
19834
20014
  async function patchScaffoldedSite(outputDirectory, options) {
19835
20015
  const title = options.branding?.title ?? options.siteName;
19836
20016
  const filesWritten = [];
19837
- const packageJsonPath = path65.join(outputDirectory, "package.json");
20017
+ const packageJsonPath = path66.join(outputDirectory, "package.json");
19838
20018
  if (options.patchPackageJson !== false) {
19839
- const packageJson3 = await readFile19(packageJsonPath, "utf8");
19840
- await writeFile17(
20019
+ const packageJson3 = await readFile20(packageJsonPath, "utf8");
20020
+ await writeFile18(
19841
20021
  packageJsonPath,
19842
20022
  rewritePackageJson(packageJson3, {
19843
20023
  siteName: options.siteName,
@@ -19847,9 +20027,9 @@ async function patchScaffoldedSite(outputDirectory, options) {
19847
20027
  );
19848
20028
  filesWritten.push("package.json");
19849
20029
  }
19850
- const configPath = path65.join(outputDirectory, "apitogo.config.tsx");
19851
- const configContent = await readFile19(configPath, "utf8");
19852
- await writeFile17(
20030
+ const configPath = path66.join(outputDirectory, "apitogo.config.tsx");
20031
+ const configContent = await readFile20(configPath, "utf8");
20032
+ await writeFile18(
19853
20033
  configPath,
19854
20034
  patchDashboardPageConfig(
19855
20035
  patchAccountPlansPageConfig(
@@ -19942,8 +20122,8 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
19942
20122
  return discoverNearbyOpenApi(siteDirectory);
19943
20123
  }
19944
20124
  async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
19945
- const resolvedSource = path66.resolve(sourceDirectory);
19946
- const resolvedOpenApi = path66.resolve(openApiPath);
20125
+ const resolvedSource = path67.resolve(sourceDirectory);
20126
+ const resolvedOpenApi = path67.resolve(openApiPath);
19947
20127
  const input5 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
19948
20128
  const validation = await validateOpenApiFile(resolvedOpenApi);
19949
20129
  if (!validation.valid) {
@@ -19955,24 +20135,24 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
19955
20135
  }
19956
20136
  const jsonConfigPath = manifestFilePath(resolvedSource);
19957
20137
  if (await pathExists4(jsonConfigPath)) {
19958
- const raw = await readFile20(jsonConfigPath, "utf8");
20138
+ const raw = await readFile21(jsonConfigPath, "utf8");
19959
20139
  const siteConfig = JSON.parse(raw);
19960
20140
  const updated = applyOpenApiToSiteConfig(siteConfig, {
19961
20141
  input: input5,
19962
20142
  apiPath: "api"
19963
20143
  });
19964
- await writeFile18(
20144
+ await writeFile19(
19965
20145
  jsonConfigPath,
19966
20146
  `${JSON.stringify(updated, null, 2)}
19967
20147
  `,
19968
20148
  "utf8"
19969
20149
  );
19970
20150
  } else {
19971
- const tsxConfigPath = path66.join(resolvedSource, "apitogo.config.tsx");
19972
- const configContent = await readFile20(tsxConfigPath, "utf8");
20151
+ const tsxConfigPath = path67.join(resolvedSource, "apitogo.config.tsx");
20152
+ const configContent = await readFile21(tsxConfigPath, "utf8");
19973
20153
  try {
19974
20154
  const patched = patchApitogoConfigOpenApiToFile(configContent, input5);
19975
- await writeFile18(tsxConfigPath, patched);
20155
+ await writeFile19(tsxConfigPath, patched);
19976
20156
  } catch (error) {
19977
20157
  return {
19978
20158
  status: "failed",
@@ -20054,7 +20234,7 @@ async function discoverAndWireOpenApi(siteDirectory, mode) {
20054
20234
  }
20055
20235
 
20056
20236
  // src/cli/make-config/interactive.ts
20057
- import path67 from "node:path";
20237
+ import path68 from "node:path";
20058
20238
  import { stdin as input, stdout as output } from "node:process";
20059
20239
  import { createInterface as createInterface3 } from "node:readline/promises";
20060
20240
 
@@ -20230,7 +20410,7 @@ async function promptMakeConfigInteractive(options) {
20230
20410
  continue;
20231
20411
  }
20232
20412
  const routePath = `/${slug}`;
20233
- const relativePath = path67.posix.join(options.pagesDir, `${slug}.tsx`);
20413
+ const relativePath = path68.posix.join(options.pagesDir, `${slug}.tsx`);
20234
20414
  const page = {
20235
20415
  slug,
20236
20416
  title: pageTitle.trim(),
@@ -20325,8 +20505,8 @@ export default function ${componentName}() {
20325
20505
  // src/cli/make-config/scaffold-project.ts
20326
20506
  init_package_json();
20327
20507
  import { constants } from "node:fs";
20328
- import { access as access11, mkdir as mkdir16, readFile as readFile21, writeFile as writeFile19 } from "node:fs/promises";
20329
- import path68 from "node:path";
20508
+ import { access as access11, mkdir as mkdir16, readFile as readFile22, writeFile as writeFile20 } from "node:fs/promises";
20509
+ import path69 from "node:path";
20330
20510
  import { glob as glob7 } from "glob";
20331
20511
 
20332
20512
  // src/cli/make-config/favicon-png.ts
@@ -20341,9 +20521,9 @@ var OPENAPI_GLOBS = [
20341
20521
  "openapi.yaml",
20342
20522
  "openapi.yml"
20343
20523
  ];
20344
- var toPosix2 = (p) => p.split(path68.sep).join("/");
20524
+ var toPosix2 = (p) => p.split(path69.sep).join("/");
20345
20525
  var sanitizePackageName = (dir) => {
20346
- const base = path68.basename(path68.resolve(dir));
20526
+ const base = path69.basename(path69.resolve(dir));
20347
20527
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
20348
20528
  return s || "apitogo-site";
20349
20529
  };
@@ -20353,7 +20533,7 @@ var apitogoVersionRange = () => {
20353
20533
  };
20354
20534
  async function findOpenApiSpecPath(dir) {
20355
20535
  for (const rel2 of OPENAPI_GLOBS) {
20356
- const full = path68.join(dir, rel2);
20536
+ const full = path69.join(dir, rel2);
20357
20537
  try {
20358
20538
  await access11(full, constants.R_OK);
20359
20539
  return toPosix2(rel2);
@@ -20367,8 +20547,8 @@ async function findOpenApiSpecPath(dir) {
20367
20547
  });
20368
20548
  return extra[0] ? toPosix2(extra[0]) : null;
20369
20549
  }
20370
- async function ensurePackageJson(dir) {
20371
- const pkgPath = path68.join(dir, "package.json");
20550
+ async function ensurePackageJson2(dir) {
20551
+ const pkgPath = path69.join(dir, "package.json");
20372
20552
  const apitogoVer = apitogoVersionRange();
20373
20553
  const baseDeps = {
20374
20554
  react: ">=19.0.0",
@@ -20403,11 +20583,11 @@ async function ensurePackageJson(dir) {
20403
20583
  typescript: "^5"
20404
20584
  }
20405
20585
  };
20406
- await writeFile19(pkgPath, `${JSON.stringify(pkg2, null, 2)}
20586
+ await writeFile20(pkgPath, `${JSON.stringify(pkg2, null, 2)}
20407
20587
  `, "utf8");
20408
20588
  return true;
20409
20589
  }
20410
- const raw = await readFile21(pkgPath, "utf8");
20590
+ const raw = await readFile22(pkgPath, "utf8");
20411
20591
  let pkg;
20412
20592
  try {
20413
20593
  pkg = JSON.parse(raw);
@@ -20430,12 +20610,12 @@ async function ensurePackageJson(dir) {
20430
20610
  for (const [k, v] of Object.entries(baseDeps)) {
20431
20611
  if (!deps[k]) deps[k] = v;
20432
20612
  }
20433
- await writeFile19(pkgPath, `${JSON.stringify(pkg, null, 2)}
20613
+ await writeFile20(pkgPath, `${JSON.stringify(pkg, null, 2)}
20434
20614
  `, "utf8");
20435
20615
  return false;
20436
20616
  }
20437
20617
  async function ensureTsconfigJson(dir) {
20438
- const tsPath = path68.join(dir, "tsconfig.json");
20618
+ const tsPath = path69.join(dir, "tsconfig.json");
20439
20619
  try {
20440
20620
  await access11(tsPath, constants.R_OK);
20441
20621
  return false;
@@ -20465,7 +20645,7 @@ async function ensureTsconfigJson(dir) {
20465
20645
  "user-panel"
20466
20646
  ]
20467
20647
  };
20468
- await writeFile19(tsPath, `${JSON.stringify(tsconfig, null, 2)}
20648
+ await writeFile20(tsPath, `${JSON.stringify(tsconfig, null, 2)}
20469
20649
  `, "utf8");
20470
20650
  return true;
20471
20651
  }
@@ -20484,49 +20664,49 @@ var fileExists2 = async (filePath) => {
20484
20664
  }
20485
20665
  };
20486
20666
  async function ensurePortalStubFiles(dir) {
20487
- const landingPath = path68.join(dir, "landing", "LandingPage.tsx");
20667
+ const landingPath = path69.join(dir, "landing", "LandingPage.tsx");
20488
20668
  if (!await fileExists2(landingPath)) {
20489
- await mkdir16(path68.join(dir, "landing"), { recursive: true });
20490
- await writeFile19(landingPath, LANDING_PAGE_SOURCE, "utf8");
20669
+ await mkdir16(path69.join(dir, "landing"), { recursive: true });
20670
+ await writeFile20(landingPath, LANDING_PAGE_SOURCE, "utf8");
20491
20671
  }
20492
- const plansPath = path68.join(dir, "user-panel", "AccountPlansPage.tsx");
20672
+ const plansPath = path69.join(dir, "user-panel", "AccountPlansPage.tsx");
20493
20673
  if (!await fileExists2(plansPath)) {
20494
- await mkdir16(path68.join(dir, "user-panel"), { recursive: true });
20495
- await writeFile19(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20674
+ await mkdir16(path69.join(dir, "user-panel"), { recursive: true });
20675
+ await writeFile20(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20496
20676
  }
20497
- const dashboardPath = path68.join(dir, "user-panel", "DashboardPage.tsx");
20677
+ const dashboardPath = path69.join(dir, "user-panel", "DashboardPage.tsx");
20498
20678
  if (!await fileExists2(dashboardPath)) {
20499
- await mkdir16(path68.join(dir, "user-panel"), { recursive: true });
20500
- await writeFile19(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20679
+ await mkdir16(path69.join(dir, "user-panel"), { recursive: true });
20680
+ await writeFile20(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20501
20681
  }
20502
20682
  await ensurePublicBrandingFiles(dir);
20503
20683
  }
20504
20684
  async function ensurePublicBrandingFiles(dir) {
20505
- const destDir = path68.join(dir, "public");
20685
+ const destDir = path69.join(dir, "public");
20506
20686
  await mkdir16(destDir, { recursive: true });
20507
20687
  for (const { name, content } of BRANDING_ASSETS) {
20508
- const dest = path68.join(destDir, name);
20688
+ const dest = path69.join(destDir, name);
20509
20689
  if (await fileExists2(dest)) {
20510
20690
  continue;
20511
20691
  }
20512
- await writeFile19(dest, content, "utf8");
20692
+ await writeFile20(dest, content, "utf8");
20513
20693
  }
20514
- const faviconDest = path68.join(destDir, "Icon.png");
20694
+ const faviconDest = path69.join(destDir, "Icon.png");
20515
20695
  if (!await fileExists2(faviconDest)) {
20516
- await writeFile19(faviconDest, Buffer.from(FAVICON_PNG_BASE64, "base64"));
20696
+ await writeFile20(faviconDest, Buffer.from(FAVICON_PNG_BASE64, "base64"));
20517
20697
  }
20518
20698
  }
20519
20699
  async function ensureThinConfigTsx(dir) {
20520
- const tsxPath = path68.join(dir, "apitogo.config.tsx");
20700
+ const tsxPath = path69.join(dir, "apitogo.config.tsx");
20521
20701
  if (await fileExists2(tsxPath)) {
20522
20702
  return false;
20523
20703
  }
20524
- await writeFile19(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
20704
+ await writeFile20(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
20525
20705
  return true;
20526
20706
  }
20527
20707
 
20528
20708
  // src/cli/make-config/handler.ts
20529
- var toPosixPath2 = (value) => value.split(path69.sep).join(path69.posix.sep);
20709
+ var toPosixPath2 = (value) => value.split(path70.sep).join(path70.posix.sep);
20530
20710
  var fileExists3 = async (filePath) => {
20531
20711
  try {
20532
20712
  await access12(filePath, constants2.F_OK);
@@ -20536,7 +20716,7 @@ var fileExists3 = async (filePath) => {
20536
20716
  }
20537
20717
  };
20538
20718
  var readJsonConfig = async (filePath) => {
20539
- const raw = await readFile22(filePath, "utf8");
20719
+ const raw = await readFile23(filePath, "utf8");
20540
20720
  const parsed = JSON.parse(raw);
20541
20721
  if (!isPlainObject3(parsed)) {
20542
20722
  throw new Error(`${APITOGO_JSON_FILENAME} must be a JSON object.`);
@@ -20582,13 +20762,13 @@ async function persistConfig(config2, ctx) {
20582
20762
  force: ctx.force
20583
20763
  })
20584
20764
  };
20585
- await writeFile20(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20765
+ await writeFile21(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20586
20766
  `, "utf8");
20587
- const tsxPath = path69.join(ctx.dir, "apitogo.config.tsx");
20767
+ const tsxPath = path70.join(ctx.dir, "apitogo.config.tsx");
20588
20768
  if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
20589
- const tsxSource = await readFile22(tsxPath, "utf8");
20769
+ const tsxSource = await readFile23(tsxPath, "utf8");
20590
20770
  if (isManagedConfigWrapper(tsxSource)) {
20591
- await writeFile20(
20771
+ await writeFile21(
20592
20772
  tsxPath,
20593
20773
  buildThinWrapperWithCustomPages(tsxRoutes),
20594
20774
  "utf8"
@@ -20611,7 +20791,7 @@ function mergeBackendFlag(config2, backend) {
20611
20791
  return next;
20612
20792
  }
20613
20793
  async function makeConfig(argv) {
20614
- const dir = path69.resolve(process.cwd(), argv.dir);
20794
+ const dir = path70.resolve(process.cwd(), argv.dir);
20615
20795
  const pagesDir = toPosixPath2(
20616
20796
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
20617
20797
  );
@@ -20620,7 +20800,7 @@ async function makeConfig(argv) {
20620
20800
  const changes = [];
20621
20801
  try {
20622
20802
  const discoveredOpenApi = await findOpenApiSpecPath(dir);
20623
- const createdPackageJson = await ensurePackageJson(dir);
20803
+ const createdPackageJson = await ensurePackageJson2(dir);
20624
20804
  const createdTsconfig = await ensureTsconfigJson(dir);
20625
20805
  if (createdPackageJson && !json) {
20626
20806
  printSuccessToConsole(
@@ -20631,14 +20811,14 @@ async function makeConfig(argv) {
20631
20811
  printSuccessToConsole("Created tsconfig.json.");
20632
20812
  }
20633
20813
  await ensurePortalStubFiles(dir);
20634
- const jsonPath = path69.join(dir, APITOGO_JSON_FILENAME);
20814
+ const jsonPath = path70.join(dir, APITOGO_JSON_FILENAME);
20635
20815
  let createdJson = false;
20636
20816
  let config2;
20637
20817
  if (await fileExists3(jsonPath)) {
20638
20818
  config2 = await readJsonConfig(jsonPath);
20639
20819
  } else {
20640
20820
  config2 = createDefaultApitogoJsonConfig({
20641
- title: titleFromDirectoryName(path69.basename(dir)),
20821
+ title: titleFromDirectoryName(path70.basename(dir)),
20642
20822
  pagesDir
20643
20823
  });
20644
20824
  createdJson = true;
@@ -20690,9 +20870,9 @@ async function makeConfig(argv) {
20690
20870
  return;
20691
20871
  }
20692
20872
  if (action2.kind === "page") {
20693
- const pagePath = path69.join(dir, action2.page.relativePath);
20694
- await mkdir17(path69.dirname(pagePath), { recursive: true });
20695
- await writeFile20(
20873
+ const pagePath = path70.join(dir, action2.page.relativePath);
20874
+ await mkdir17(path70.dirname(pagePath), { recursive: true });
20875
+ await writeFile21(
20696
20876
  pagePath,
20697
20877
  buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
20698
20878
  "utf8"
@@ -20758,7 +20938,7 @@ async function makeConfig(argv) {
20758
20938
  if (argv.openapi) {
20759
20939
  const wire = await wireDevPortalOpenApi(
20760
20940
  dir,
20761
- path69.resolve(dir, argv.openapi)
20941
+ path70.resolve(dir, argv.openapi)
20762
20942
  );
20763
20943
  if (wire.status !== "succeeded") {
20764
20944
  throw new Error(
@@ -20787,7 +20967,7 @@ async function makeConfig(argv) {
20787
20967
  const slug = normalizePageSlug2(argv.pageSlug);
20788
20968
  const pageTemplate = normalizePageTemplate(argv.pageTemplate);
20789
20969
  const relativePagePath = pageComponentRelativePath(slug);
20790
- const filePath = path69.join(dir, relativePagePath);
20970
+ const filePath = path70.join(dir, relativePagePath);
20791
20971
  const isUpdate = argv.pageUpdate === true;
20792
20972
  if (isUpdate) {
20793
20973
  if (!await fileExists3(filePath)) {
@@ -20801,7 +20981,7 @@ async function makeConfig(argv) {
20801
20981
  argv.pageContent,
20802
20982
  pageTemplate
20803
20983
  );
20804
- await writeFile20(filePath, tsx, "utf8");
20984
+ await writeFile21(filePath, tsx, "utf8");
20805
20985
  pageResult = {
20806
20986
  action: "updated",
20807
20987
  slug,
@@ -20820,8 +21000,8 @@ async function makeConfig(argv) {
20820
21000
  argv.pageContent,
20821
21001
  pageTemplate
20822
21002
  );
20823
- await mkdir17(path69.dirname(filePath), { recursive: true });
20824
- await writeFile20(filePath, tsx, "utf8");
21003
+ await mkdir17(path70.dirname(filePath), { recursive: true });
21004
+ await writeFile21(filePath, tsx, "utf8");
20825
21005
  const configResult = await wireNewDevPortalPageInConfig(
20826
21006
  dir,
20827
21007
  slug,
@@ -20833,7 +21013,7 @@ async function makeConfig(argv) {
20833
21013
  pagePath: relativePagePath,
20834
21014
  pageTemplate,
20835
21015
  configUpdated: configResult.updated,
20836
- configPath: configResult.configPath ? path69.relative(dir, configResult.configPath) : null
21016
+ configPath: configResult.configPath ? path70.relative(dir, configResult.configPath) : null
20837
21017
  };
20838
21018
  changes.push("page_add");
20839
21019
  }
@@ -20958,10 +21138,10 @@ var config_default = {
20958
21138
  };
20959
21139
 
20960
21140
  // src/cli/cmds/deploy.ts
20961
- import path83 from "node:path";
21141
+ import path84 from "node:path";
20962
21142
 
20963
21143
  // src/cli/apply/handler.ts
20964
- import path80 from "node:path";
21144
+ import path81 from "node:path";
20965
21145
 
20966
21146
  // src/cli/platform/helpers/gateway-plan-validation.ts
20967
21147
  init_gateway_limits();
@@ -21156,11 +21336,11 @@ init_gateway_limits();
21156
21336
  // src/cli/platform/helpers/deploy-artifact-hash.ts
21157
21337
  import { createHash as createHash3 } from "node:crypto";
21158
21338
  import { createReadStream, promises as fs8 } from "node:fs";
21159
- import path71 from "node:path";
21339
+ import path72 from "node:path";
21160
21340
 
21161
21341
  // src/cli/platform/helpers/package-files.ts
21162
21342
  import { promises as fs7 } from "node:fs";
21163
- import path70 from "node:path";
21343
+ import path71 from "node:path";
21164
21344
  import ignore from "ignore";
21165
21345
  var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
21166
21346
  "node_modules",
@@ -21173,7 +21353,7 @@ var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
21173
21353
  async function loadGitignore(rootDir) {
21174
21354
  const ig = ignore();
21175
21355
  ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
21176
- const gitignorePath = path70.join(rootDir, ".gitignore");
21356
+ const gitignorePath = path71.join(rootDir, ".gitignore");
21177
21357
  try {
21178
21358
  const content = await fs7.readFile(gitignorePath, "utf8");
21179
21359
  ig.add(content);
@@ -21182,11 +21362,11 @@ async function loadGitignore(rootDir) {
21182
21362
  return ig;
21183
21363
  }
21184
21364
  async function collectFiles(rootDir, relativeDir, ig, files) {
21185
- const absDir = path70.join(rootDir, relativeDir);
21365
+ const absDir = path71.join(rootDir, relativeDir);
21186
21366
  const entries = await fs7.readdir(absDir, { withFileTypes: true });
21187
21367
  for (const entry of entries) {
21188
- const rel2 = relativeDir ? path70.join(relativeDir, entry.name) : entry.name;
21189
- const relPosix = rel2.split(path70.sep).join("/");
21368
+ const rel2 = relativeDir ? path71.join(relativeDir, entry.name) : entry.name;
21369
+ const relPosix = rel2.split(path71.sep).join("/");
21190
21370
  if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
21191
21371
  continue;
21192
21372
  }
@@ -21201,7 +21381,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
21201
21381
  }
21202
21382
  }
21203
21383
  async function collectPackageableFiles(sourceDirectory) {
21204
- const resolved = path70.resolve(sourceDirectory);
21384
+ const resolved = path71.resolve(sourceDirectory);
21205
21385
  const stat7 = await fs7.stat(resolved).catch(() => null);
21206
21386
  if (!stat7?.isDirectory()) {
21207
21387
  throw new Error(`sourceDirectory is not a directory: ${resolved}`);
@@ -21227,7 +21407,7 @@ async function sha256File(filePath) {
21227
21407
  return hash2.digest("hex");
21228
21408
  }
21229
21409
  async function hashDirectoryContents(rootDirectory) {
21230
- const resolved = path71.resolve(rootDirectory);
21410
+ const resolved = path72.resolve(rootDirectory);
21231
21411
  const files = (await collectPackageableFiles(resolved)).sort(
21232
21412
  (a, b) => a.localeCompare(b)
21233
21413
  );
@@ -21235,13 +21415,13 @@ async function hashDirectoryContents(rootDirectory) {
21235
21415
  for (const rel2 of files) {
21236
21416
  hash2.update(rel2);
21237
21417
  hash2.update("\0");
21238
- hash2.update(await fs8.readFile(path71.join(resolved, rel2)));
21418
+ hash2.update(await fs8.readFile(path72.join(resolved, rel2)));
21239
21419
  hash2.update("\0");
21240
21420
  }
21241
21421
  return hash2.digest("hex");
21242
21422
  }
21243
21423
  async function hashDevPortalSiteSources(siteDirectory, options) {
21244
- const resolved = path71.resolve(siteDirectory);
21424
+ const resolved = path72.resolve(siteDirectory);
21245
21425
  const hash2 = createHash3("sha256");
21246
21426
  const candidates = [
21247
21427
  "apitogo.config.json",
@@ -21251,7 +21431,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
21251
21431
  "zudoku.config.tsx"
21252
21432
  ];
21253
21433
  for (const name of candidates) {
21254
- const full = path71.join(resolved, name);
21434
+ const full = path72.join(resolved, name);
21255
21435
  try {
21256
21436
  hash2.update(name);
21257
21437
  hash2.update("\0");
@@ -21261,7 +21441,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
21261
21441
  }
21262
21442
  }
21263
21443
  for (const dir of ["pages", "landing", "src"]) {
21264
- const full = path71.join(resolved, dir);
21444
+ const full = path72.join(resolved, dir);
21265
21445
  try {
21266
21446
  const st = await fs8.stat(full);
21267
21447
  if (!st.isDirectory()) continue;
@@ -21490,8 +21670,8 @@ function normalizeActionKey(actionKey2) {
21490
21670
  const trimmed = actionKey2.trim();
21491
21671
  if (trimmed.includes(":")) {
21492
21672
  const [method2, ...pathParts] = trimmed.split(":");
21493
- const path102 = pathParts.join(":").trim();
21494
- return `${method2?.toLowerCase()}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
21673
+ const path103 = pathParts.join(":").trim();
21674
+ return `${method2?.toLowerCase()}:${path103.startsWith("/") ? path103 : `/${path103}`}`;
21495
21675
  }
21496
21676
  const spaceIndex = trimmed.indexOf(" ");
21497
21677
  if (spaceIndex <= 0) {
@@ -21500,8 +21680,8 @@ function normalizeActionKey(actionKey2) {
21500
21680
  );
21501
21681
  }
21502
21682
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
21503
- const path101 = trimmed.slice(spaceIndex + 1).trim();
21504
- return `${method}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
21683
+ const path102 = trimmed.slice(spaceIndex + 1).trim();
21684
+ return `${method}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
21505
21685
  }
21506
21686
  async function applyGatewayPublicRoutes(client, projectId, routes, options) {
21507
21687
  const applied = [];
@@ -21979,8 +22159,8 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
21979
22159
  }
21980
22160
 
21981
22161
  // src/cli/platform/helpers/openapi-gateway-servers.ts
21982
- import { mkdir as mkdir18, readFile as readFile23, writeFile as writeFile21 } from "node:fs/promises";
21983
- import path72 from "node:path";
22162
+ import { mkdir as mkdir18, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
22163
+ import path73 from "node:path";
21984
22164
  import YAML3 from "yaml";
21985
22165
  var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
21986
22166
  var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
@@ -22011,8 +22191,8 @@ async function resolveProjectGatewayUrl(client, projectId) {
22011
22191
  return null;
22012
22192
  }
22013
22193
  async function readOpenApiDocument(filePath) {
22014
- const content = await readFile23(filePath, "utf8");
22015
- const ext = path72.extname(filePath).toLowerCase();
22194
+ const content = await readFile24(filePath, "utf8");
22195
+ const ext = path73.extname(filePath).toLowerCase();
22016
22196
  const parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
22017
22197
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22018
22198
  throw new Error(`OpenAPI document must be an object: ${filePath}`);
@@ -22020,14 +22200,14 @@ async function readOpenApiDocument(filePath) {
22020
22200
  return parsed;
22021
22201
  }
22022
22202
  async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
22023
- const site = path72.resolve(siteDirectory);
22024
- const source = path72.resolve(sourceOpenApiPath);
22203
+ const site = path73.resolve(siteDirectory);
22204
+ const source = path73.resolve(sourceOpenApiPath);
22025
22205
  const relativeInput = PUBLISH_OPENAPI_RELATIVE;
22026
- const outputPath = path72.join(site, ...relativeInput.split("/"));
22206
+ const outputPath = path73.join(site, ...relativeInput.split("/"));
22027
22207
  const doc = await readOpenApiDocument(source);
22028
22208
  const rewritten = withGatewayServers(doc, gatewayUrl);
22029
- await mkdir18(path72.dirname(outputPath), { recursive: true });
22030
- await writeFile21(
22209
+ await mkdir18(path73.dirname(outputPath), { recursive: true });
22210
+ await writeFile22(
22031
22211
  outputPath,
22032
22212
  `${JSON.stringify(rewritten, null, 2)}
22033
22213
  `,
@@ -22036,11 +22216,11 @@ async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApi
22036
22216
  return { outputPath, relativeInput };
22037
22217
  }
22038
22218
  async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22039
- const configPath = path72.join(
22040
- path72.resolve(siteDirectory),
22219
+ const configPath = path73.join(
22220
+ path73.resolve(siteDirectory),
22041
22221
  APITOGO_CONFIG_FILENAME2
22042
22222
  );
22043
- const raw = await readFile23(configPath, "utf8");
22223
+ const raw = await readFile24(configPath, "utf8");
22044
22224
  const config2 = JSON.parse(raw);
22045
22225
  const previousApis = config2.apis;
22046
22226
  const previousBackend = config2.backend;
@@ -22053,11 +22233,11 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22053
22233
  const backend = config2.backend && typeof config2.backend === "object" ? { ...config2.backend } : {};
22054
22234
  backend.openApiPath = relativeInput;
22055
22235
  config2.backend = backend;
22056
- await writeFile21(configPath, `${JSON.stringify(config2, null, 2)}
22236
+ await writeFile22(configPath, `${JSON.stringify(config2, null, 2)}
22057
22237
  `, "utf8");
22058
22238
  return {
22059
22239
  restore: async () => {
22060
- const currentRaw = await readFile23(configPath, "utf8");
22240
+ const currentRaw = await readFile24(configPath, "utf8");
22061
22241
  const current = JSON.parse(currentRaw);
22062
22242
  if (previousApis === void 0) {
22063
22243
  delete current.apis;
@@ -22069,7 +22249,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22069
22249
  } else {
22070
22250
  current.backend = previousBackend;
22071
22251
  }
22072
- await writeFile21(
22252
+ await writeFile22(
22073
22253
  configPath,
22074
22254
  `${JSON.stringify(current, null, 2)}
22075
22255
  `,
@@ -22079,7 +22259,7 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
22079
22259
  };
22080
22260
  }
22081
22261
  async function prepareOpenApiServersForGatewayBuild(options) {
22082
- const siteDirectory = path72.resolve(options.siteDirectory);
22262
+ const siteDirectory = path73.resolve(options.siteDirectory);
22083
22263
  let openApiPath = resolveBackendOpenApiPath(
22084
22264
  options.manifest?.backend?.openApiPath,
22085
22265
  {
@@ -22092,8 +22272,8 @@ async function prepareOpenApiServersForGatewayBuild(options) {
22092
22272
  );
22093
22273
  if (!openApiPath) {
22094
22274
  try {
22095
- const raw = await readFile23(
22096
- path72.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
22275
+ const raw = await readFile24(
22276
+ path73.join(siteDirectory, APITOGO_CONFIG_FILENAME2),
22097
22277
  "utf8"
22098
22278
  );
22099
22279
  const config2 = JSON.parse(raw);
@@ -22122,8 +22302,8 @@ function normalizeActionKeyFormat(actionKey2) {
22122
22302
  const trimmed = actionKey2.trim();
22123
22303
  if (trimmed.includes(":")) {
22124
22304
  const [method2, ...pathParts] = trimmed.split(":");
22125
- const path102 = pathParts.join(":").trim();
22126
- return `${method2.toLowerCase()}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
22305
+ const path103 = pathParts.join(":").trim();
22306
+ return `${method2.toLowerCase()}:${path103.startsWith("/") ? path103 : `/${path103}`}`;
22127
22307
  }
22128
22308
  const spaceIndex = trimmed.indexOf(" ");
22129
22309
  if (spaceIndex <= 0) {
@@ -22132,8 +22312,8 @@ function normalizeActionKeyFormat(actionKey2) {
22132
22312
  );
22133
22313
  }
22134
22314
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
22135
- const path101 = trimmed.slice(spaceIndex + 1).trim();
22136
- return `${method}:${path101.startsWith("/") ? path101 : `/${path101}`}`;
22315
+ const path102 = trimmed.slice(spaceIndex + 1).trim();
22316
+ return `${method}:${path102.startsWith("/") ? path102 : `/${path102}`}`;
22137
22317
  }
22138
22318
  function normalizePublicRoute(route) {
22139
22319
  const trimmed = route.trim();
@@ -22166,16 +22346,16 @@ function collectManifestPublicActionKeys(gateway) {
22166
22346
  }
22167
22347
 
22168
22348
  // src/cli/platform/helpers/publish-ledger.ts
22169
- import { mkdir as mkdir19, readFile as readFile24, writeFile as writeFile22 } from "node:fs/promises";
22170
- import path73 from "node:path";
22349
+ import { mkdir as mkdir19, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
22350
+ import path74 from "node:path";
22171
22351
  var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
22172
22352
  function publishLedgerPath(siteDirectory) {
22173
- return path73.join(path73.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
22353
+ return path74.join(path74.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
22174
22354
  }
22175
22355
  async function readPublishLedger(siteDirectory) {
22176
22356
  const filePath = publishLedgerPath(siteDirectory);
22177
22357
  try {
22178
- const raw = await readFile24(filePath, "utf8");
22358
+ const raw = await readFile25(filePath, "utf8");
22179
22359
  const parsed = JSON.parse(raw);
22180
22360
  if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
22181
22361
  return null;
@@ -22187,13 +22367,13 @@ async function readPublishLedger(siteDirectory) {
22187
22367
  }
22188
22368
  async function writePublishLedger(siteDirectory, ledger) {
22189
22369
  const filePath = publishLedgerPath(siteDirectory);
22190
- await mkdir19(path73.dirname(filePath), { recursive: true });
22370
+ await mkdir19(path74.dirname(filePath), { recursive: true });
22191
22371
  const next = {
22192
22372
  ...ledger,
22193
22373
  version: 1,
22194
22374
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
22195
22375
  };
22196
- await writeFile22(filePath, `${JSON.stringify(next, null, 2)}
22376
+ await writeFile23(filePath, `${JSON.stringify(next, null, 2)}
22197
22377
  `, "utf8");
22198
22378
  return filePath;
22199
22379
  }
@@ -22709,9 +22889,9 @@ async function createProjectWithWarmPoolRetry(client, body, options) {
22709
22889
  import { spawn as spawn4 } from "node:child_process";
22710
22890
  import { mkdtemp, readdir as readdir2, rm as rm11 } from "node:fs/promises";
22711
22891
  import { tmpdir } from "node:os";
22712
- import path74 from "node:path";
22892
+ import path75 from "node:path";
22713
22893
  async function directoryHasRuntimeConfig(dir) {
22714
- if (!await pathExists(dir)) {
22894
+ if (!await pathExists2(dir)) {
22715
22895
  return false;
22716
22896
  }
22717
22897
  const entries = await readdir2(dir);
@@ -22752,20 +22932,20 @@ function runDotnetPublish(projectDir, outputDir) {
22752
22932
  async function findCsproj(projectDir) {
22753
22933
  const entries = await readdir2(projectDir);
22754
22934
  const csproj = entries.find((name) => name.endsWith(".csproj"));
22755
- return csproj ? path74.join(projectDir, csproj) : null;
22935
+ return csproj ? path75.join(projectDir, csproj) : null;
22756
22936
  }
22757
22937
  async function prepareBackendPackagingDirectory(args) {
22758
- const sourceDirectory = path74.resolve(args.sourceDirectory);
22938
+ const sourceDirectory = path75.resolve(args.sourceDirectory);
22759
22939
  if (args.publishDirectory?.trim()) {
22760
22940
  return {
22761
- directory: path74.resolve(args.publishDirectory),
22941
+ directory: path75.resolve(args.publishDirectory),
22762
22942
  packagingMode: "published"
22763
22943
  };
22764
22944
  }
22765
22945
  if (await directoryHasRuntimeConfig(sourceDirectory)) {
22766
22946
  return { directory: sourceDirectory, packagingMode: "published" };
22767
22947
  }
22768
- const publishSubdir = path74.join(sourceDirectory, "publish");
22948
+ const publishSubdir = path75.join(sourceDirectory, "publish");
22769
22949
  if (await directoryHasRuntimeConfig(publishSubdir)) {
22770
22950
  return { directory: publishSubdir, packagingMode: "published" };
22771
22951
  }
@@ -22777,9 +22957,9 @@ async function prepareBackendPackagingDirectory(args) {
22777
22957
  return { directory: sourceDirectory, packagingMode: "source" };
22778
22958
  }
22779
22959
  const tempRoot = await mkdtemp(
22780
- path74.join(tmpdir(), "apitogo-dotnet-publish-")
22960
+ path75.join(tmpdir(), "apitogo-dotnet-publish-")
22781
22961
  );
22782
- const outputDir = path74.join(tempRoot, "publish");
22962
+ const outputDir = path75.join(tempRoot, "publish");
22783
22963
  const result = await runDotnetPublish(sourceDirectory, outputDir);
22784
22964
  if (result.exitCode !== 0) {
22785
22965
  await rm11(tempRoot, { recursive: true, force: true });
@@ -22825,12 +23005,12 @@ function formatJobStatusResponse(options) {
22825
23005
  // src/cli/platform/helpers/zip.ts
22826
23006
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs9 } from "node:fs";
22827
23007
  import { tmpdir as tmpdir2 } from "node:os";
22828
- import path75 from "node:path";
23008
+ import path76 from "node:path";
22829
23009
  import { ZipArchive } from "archiver";
22830
23010
  async function packageBackendDirectory(sourceDirectory) {
22831
- const resolved = path75.resolve(sourceDirectory);
23011
+ const resolved = path76.resolve(sourceDirectory);
22832
23012
  const files = await collectPackageableFiles(resolved);
22833
- const zipPath = path75.join(
23013
+ const zipPath = path76.join(
22834
23014
  tmpdir2(),
22835
23015
  `apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
22836
23016
  );
@@ -22842,8 +23022,8 @@ async function packageBackendDirectory(sourceDirectory) {
22842
23022
  output4.on("error", reject);
22843
23023
  archive.pipe(output4);
22844
23024
  for (const rel2 of files) {
22845
- archive.append(createReadStream2(path75.join(resolved, rel2)), {
22846
- name: rel2.split(path75.sep).join("/")
23025
+ archive.append(createReadStream2(path76.join(resolved, rel2)), {
23026
+ name: rel2.split(path76.sep).join("/")
22847
23027
  });
22848
23028
  }
22849
23029
  void archive.finalize();
@@ -24344,11 +24524,11 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
24344
24524
  }
24345
24525
 
24346
24526
  // src/cli/platform/tools/dev-portal-site-build.ts
24347
- import path79 from "node:path";
24527
+ import path80 from "node:path";
24348
24528
 
24349
24529
  // src/cli/platform/helpers/dev-portal-site-api-url.ts
24350
- import { readdir as readdir3, readFile as readFile25, writeFile as writeFile23 } from "node:fs/promises";
24351
- import path76 from "node:path";
24530
+ import { readdir as readdir3, readFile as readFile26, writeFile as writeFile24 } from "node:fs/promises";
24531
+ import path77 from "node:path";
24352
24532
  var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
24353
24533
  var PLACEHOLDER_HOST_MARKERS = [
24354
24534
  "dp-example.azurecontainerapps.io",
@@ -24369,10 +24549,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
24369
24549
  return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
24370
24550
  }
24371
24551
  async function readSiteApiBaseUrl(sourceDirectory) {
24372
- const resolved = path76.resolve(sourceDirectory);
24552
+ const resolved = path77.resolve(sourceDirectory);
24373
24553
  for (const envFile of [".env", ".env.production"]) {
24374
24554
  try {
24375
- const content = await readFile25(path76.join(resolved, envFile), "utf8");
24555
+ const content = await readFile26(path77.join(resolved, envFile), "utf8");
24376
24556
  const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
24377
24557
  if (lines.length === 0) {
24378
24558
  continue;
@@ -24397,25 +24577,25 @@ async function readSiteApiBaseUrl(sourceDirectory) {
24397
24577
  return null;
24398
24578
  }
24399
24579
  async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
24400
- const resolved = path76.resolve(sourceDirectory);
24580
+ const resolved = path77.resolve(sourceDirectory);
24401
24581
  const line2 = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
24402
24582
  let patchedExisting = false;
24403
24583
  for (const envFile of [".env.production", ".env"]) {
24404
- const envPath = path76.join(resolved, envFile);
24584
+ const envPath = path77.join(resolved, envFile);
24405
24585
  try {
24406
- const content = await readFile25(envPath, "utf8");
24586
+ const content = await readFile26(envPath, "utf8");
24407
24587
  const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
24408
24588
  const patched = withoutAssignments ? `${withoutAssignments}
24409
24589
  ${line2}
24410
24590
  ` : `${line2}
24411
24591
  `;
24412
- await writeFile23(envPath, patched);
24592
+ await writeFile24(envPath, patched);
24413
24593
  patchedExisting = true;
24414
24594
  } catch {
24415
24595
  }
24416
24596
  }
24417
24597
  if (!patchedExisting) {
24418
- await writeFile23(path76.join(resolved, ".env"), `${line2}
24598
+ await writeFile24(path77.join(resolved, ".env"), `${line2}
24419
24599
  `);
24420
24600
  }
24421
24601
  }
@@ -24423,7 +24603,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
24423
24603
  return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
24424
24604
  }
24425
24605
  async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
24426
- const sourceDirectory = path76.resolve(args.sourceDirectory);
24606
+ const sourceDirectory = path77.resolve(args.sourceDirectory);
24427
24607
  const explicit = args.apiBaseUrl?.trim();
24428
24608
  if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
24429
24609
  await patchSiteApiBaseUrl(sourceDirectory, explicit);
@@ -24459,7 +24639,7 @@ async function* walkFiles(root) {
24459
24639
  return;
24460
24640
  }
24461
24641
  for (const entry of entries) {
24462
- const full = path76.join(root, entry.name);
24642
+ const full = path77.join(root, entry.name);
24463
24643
  if (entry.isDirectory()) {
24464
24644
  if (entry.name === "node_modules" || entry.name === ".git") {
24465
24645
  continue;
@@ -24471,8 +24651,8 @@ async function* walkFiles(root) {
24471
24651
  }
24472
24652
  }
24473
24653
  async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
24474
- const dist = path76.resolve(distDirectory);
24475
- const siteRoot = path76.dirname(dist);
24654
+ const dist = path77.resolve(distDirectory);
24655
+ const siteRoot = path77.dirname(dist);
24476
24656
  const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
24477
24657
  if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
24478
24658
  throw new Error(
@@ -24483,7 +24663,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
24483
24663
  let found = false;
24484
24664
  let foundPlaceholder = false;
24485
24665
  for await (const file of walkFiles(dist)) {
24486
- const content = await readFile25(file, "utf8");
24666
+ const content = await readFile26(file, "utf8");
24487
24667
  if (content.includes(needle)) {
24488
24668
  found = true;
24489
24669
  }
@@ -24508,7 +24688,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
24508
24688
 
24509
24689
  // src/cli/platform/tools/dev-portal.ts
24510
24690
  import { promises as fs11 } from "node:fs";
24511
- import path78 from "node:path";
24691
+ import path79 from "node:path";
24512
24692
 
24513
24693
  // src/cli/platform/helpers/dev-portal-backend-job.ts
24514
24694
  var DEV_PORTAL_BACKEND_UPDATE_RESOURCE_TYPE = "DevPortalBackendUpdate";
@@ -24618,7 +24798,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
24618
24798
  // src/cli/platform/helpers/tarball.ts
24619
24799
  import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs10 } from "node:fs";
24620
24800
  import { tmpdir as tmpdir3 } from "node:os";
24621
- import path77 from "node:path";
24801
+ import path78 from "node:path";
24622
24802
  import { TarArchive } from "archiver";
24623
24803
  var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
24624
24804
  function normalizeArchiveRoot(archiveRoot) {
@@ -24629,10 +24809,10 @@ function normalizeArchiveRoot(archiveRoot) {
24629
24809
  return `${trimmed}/`;
24630
24810
  }
24631
24811
  async function packageDirectoryAsTarGz(sourceDirectory, options) {
24632
- const resolved = path77.resolve(sourceDirectory);
24812
+ const resolved = path78.resolve(sourceDirectory);
24633
24813
  const files = await collectPackageableFiles(resolved);
24634
24814
  const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
24635
- const archivePath = path77.join(
24815
+ const archivePath = path78.join(
24636
24816
  tmpdir3(),
24637
24817
  `apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
24638
24818
  );
@@ -24644,8 +24824,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
24644
24824
  output4.on("error", reject);
24645
24825
  archive.pipe(output4);
24646
24826
  for (const rel2 of files) {
24647
- const entryName = entryPrefix + rel2.split(path77.sep).join("/");
24648
- archive.append(createReadStream3(path77.join(resolved, rel2)), {
24827
+ const entryName = entryPrefix + rel2.split(path78.sep).join("/");
24828
+ archive.append(createReadStream3(path78.join(resolved, rel2)), {
24649
24829
  name: entryName
24650
24830
  });
24651
24831
  }
@@ -24887,7 +25067,7 @@ function validateDeployArchiveInput(args) {
24887
25067
  async function resolveDevPortalArchive(args) {
24888
25068
  validateDeployArchiveInput(args);
24889
25069
  if (args.archivePath?.trim()) {
24890
- const archivePath = path78.resolve(args.archivePath.trim());
25070
+ const archivePath = path79.resolve(args.archivePath.trim());
24891
25071
  const stat7 = await fs11.stat(archivePath).catch(() => null);
24892
25072
  if (!stat7?.isFile()) {
24893
25073
  throw new Error(`archivePath is not a file: ${archivePath}`);
@@ -24952,7 +25132,7 @@ async function handleDeployDevPortal(client, config2, args, progress) {
24952
25132
  // src/cli/platform/tools/dev-portal-site-build.ts
24953
25133
  async function handleBuildDevPortalSite(client, config2, args, progress) {
24954
25134
  const buildProgress = progress?.child("Build dev portal site");
24955
- const sourceDirectory = path79.resolve(args.sourceDirectory);
25135
+ const sourceDirectory = path80.resolve(args.sourceDirectory);
24956
25136
  await buildProgress?.onStep("Ensuring live portal API URL");
24957
25137
  const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
24958
25138
  client,
@@ -26448,7 +26628,7 @@ function resultLooksFailed(payload) {
26448
26628
  return parsed.status === "failed" || parsed.status === "blocked";
26449
26629
  }
26450
26630
  async function apply(argv) {
26451
- const sourceDirectory = path80.resolve(process.cwd(), argv.dir);
26631
+ const sourceDirectory = path81.resolve(process.cwd(), argv.dir);
26452
26632
  let config2;
26453
26633
  try {
26454
26634
  config2 = loadConfig();
@@ -26518,7 +26698,7 @@ async function apply(argv) {
26518
26698
  if (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_not_found") {
26519
26699
  const resolution = await resolveProjectNotFoundInteractively(
26520
26700
  parsed,
26521
- path80.basename(sourceDirectory)
26701
+ path81.basename(sourceDirectory)
26522
26702
  );
26523
26703
  if (resolution) {
26524
26704
  effectiveProjectId = void 0;
@@ -26538,7 +26718,7 @@ async function apply(argv) {
26538
26718
  while (canPromptInteractively && parsed?.status === "blocked" && parsed.reason === "project_name_exists") {
26539
26719
  const resolution = await resolveProjectNameExistsInteractively(
26540
26720
  parsed,
26541
- effectiveProjectName ?? path80.basename(sourceDirectory)
26721
+ effectiveProjectName ?? path81.basename(sourceDirectory)
26542
26722
  );
26543
26723
  if (!resolution) {
26544
26724
  break;
@@ -26610,7 +26790,7 @@ async function apply(argv) {
26610
26790
 
26611
26791
  // src/cli/deploy/command.ts
26612
26792
  init_invariant();
26613
- import path82 from "node:path";
26793
+ import path83 from "node:path";
26614
26794
 
26615
26795
  // src/cli/deploy/v2.ts
26616
26796
  import { rm as rm12 } from "node:fs/promises";
@@ -26618,11 +26798,11 @@ init_invariant();
26618
26798
 
26619
26799
  // src/cli/portal/report.ts
26620
26800
  import { access as access13 } from "node:fs/promises";
26621
- import path81 from "node:path";
26801
+ import path82 from "node:path";
26622
26802
 
26623
26803
  // src/cli/deploy/gateway.ts
26624
26804
  import { createHash as createHash4 } from "node:crypto";
26625
- import { readFile as readFile26 } from "node:fs/promises";
26805
+ import { readFile as readFile27 } from "node:fs/promises";
26626
26806
  init_invariant();
26627
26807
  var GatewayDeployError = class extends ApitogoError {
26628
26808
  constructor(code, message, developerHint) {
@@ -26662,7 +26842,7 @@ async function readSpec(gateway) {
26662
26842
  "Add one to gateway.specs in the config."
26663
26843
  );
26664
26844
  try {
26665
- return await readFile26(file);
26845
+ return await readFile27(file);
26666
26846
  } catch {
26667
26847
  throw new GatewayDeployError(
26668
26848
  "GATEWAY_SPEC_UNREADABLE",
@@ -26897,7 +27077,7 @@ async function planPortalService(resolved, ledger) {
26897
27077
  const hash2 = await portalBuildHash(resolved, prepared);
26898
27078
  const previous = stepOf(ledger, "portal", "build");
26899
27079
  const built = await exists4(
26900
- path81.join(resolved.state.buildDir, "index.html")
27080
+ path82.join(resolved.state.buildDir, "index.html")
26901
27081
  );
26902
27082
  if (previous?.status === "succeeded" && previous.hash === hash2 && built) {
26903
27083
  return {
@@ -27204,7 +27384,7 @@ async function statusV2(dir, only, options = {}) {
27204
27384
  if (service === "portal") {
27205
27385
  const build2 = stepOf(ledger, "portal", "build");
27206
27386
  const built = await exists4(
27207
- path81.join(resolved.state.buildDir, "index.html")
27387
+ path82.join(resolved.state.buildDir, "index.html")
27208
27388
  );
27209
27389
  const state = build2?.status === "failed" ? "build-failed" : build2?.status === "succeeded" && built ? "built" : "not-built";
27210
27390
  services.push({
@@ -27215,7 +27395,7 @@ async function statusV2(dir, only, options = {}) {
27215
27395
  ...build2?.finishedAt ? [`last build: ${build2.finishedAt}`] : [],
27216
27396
  ...build2?.status === "failed" ? [`error: ${build2.error ?? "unknown"}`] : [],
27217
27397
  ...state === "built" ? [
27218
- `output: ${path81.relative(resolved.configDir, resolved.state.buildDir)}`
27398
+ `output: ${path82.relative(resolved.configDir, resolved.state.buildDir)}`
27219
27399
  ] : [],
27220
27400
  ...url2 ? [`url: ${url2}`] : ["url: not known (portal is not deployed yet)"]
27221
27401
  ]
@@ -27483,7 +27663,7 @@ async function deployProject(argv) {
27483
27663
  const config2 = loadConfig();
27484
27664
  const output4 = await deployV2(
27485
27665
  {
27486
- dir: path82.resolve(process.cwd(), argv.dir),
27666
+ dir: path83.resolve(process.cwd(), argv.dir),
27487
27667
  only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
27488
27668
  projectId: argv.projectId,
27489
27669
  env: argv.env,
@@ -27564,7 +27744,7 @@ var deploy_default = {
27564
27744
  }),
27565
27745
  handler: async (argv) => {
27566
27746
  await captureEvent({ argv, event: "apitogo deploy" });
27567
- if (await isConfigV2(path83.resolve(process.cwd(), argv.dir))) {
27747
+ if (await isConfigV2(path84.resolve(process.cwd(), argv.dir))) {
27568
27748
  await deployProject(argv);
27569
27749
  return;
27570
27750
  }
@@ -27573,8 +27753,8 @@ var deploy_default = {
27573
27753
  };
27574
27754
 
27575
27755
  // src/cli/export/handler.ts
27576
- import { mkdir as mkdir20, writeFile as writeFile24 } from "node:fs/promises";
27577
- import path84 from "node:path";
27756
+ import { mkdir as mkdir20, writeFile as writeFile25 } from "node:fs/promises";
27757
+ import path85 from "node:path";
27578
27758
  init_invariant();
27579
27759
  var ExportError = class extends ApitogoError {
27580
27760
  constructor(message, developerHint) {
@@ -27588,7 +27768,7 @@ async function exportOpenApi(args, deps) {
27588
27768
  `Cannot export "${args.target}".`,
27589
27769
  "Only `apitogo export openapi` exists."
27590
27770
  );
27591
- const dir = path84.resolve(process.cwd(), args.dir ?? ".");
27771
+ const dir = path85.resolve(process.cwd(), args.dir ?? ".");
27592
27772
  if (!await isConfigV2(dir))
27593
27773
  throw new ExportError(
27594
27774
  "This command needs a config version 2 project.",
@@ -27613,9 +27793,9 @@ async function exportOpenApi(args, deps) {
27613
27793
  throw error;
27614
27794
  }
27615
27795
  if (!args.out) return { text };
27616
- const file = path84.resolve(process.cwd(), args.out);
27617
- await mkdir20(path84.dirname(file), { recursive: true });
27618
- await writeFile24(file, text);
27796
+ const file = path85.resolve(process.cwd(), args.out);
27797
+ await mkdir20(path85.dirname(file), { recursive: true });
27798
+ await writeFile25(file, text);
27619
27799
  return { text, file };
27620
27800
  }
27621
27801
  async function exportCommand(args) {
@@ -27665,15 +27845,15 @@ var export_default = {
27665
27845
  };
27666
27846
 
27667
27847
  // src/cli/init/handler.ts
27668
- import path88 from "node:path";
27848
+ import path89 from "node:path";
27669
27849
 
27670
27850
  // src/cli/scaffold/run-scaffold-discovery.ts
27671
- import { access as access15, readFile as readFile29, writeFile as writeFile26 } from "node:fs/promises";
27672
- import path87 from "node:path";
27851
+ import { access as access15, readFile as readFile30, writeFile as writeFile27 } from "node:fs/promises";
27852
+ import path88 from "node:path";
27673
27853
 
27674
27854
  // src/cli/scaffold/detect-backend.ts
27675
- import { readdir as readdir4, readFile as readFile27 } from "node:fs/promises";
27676
- import path85 from "node:path";
27855
+ import { readdir as readdir4, readFile as readFile28 } from "node:fs/promises";
27856
+ import path86 from "node:path";
27677
27857
  var DEFAULT_RUNTIME_VERSION = {
27678
27858
  dotnet: "DOTNET_10",
27679
27859
  nodejs: "NODE_22_LTS",
@@ -27690,7 +27870,7 @@ async function listFiles(directory) {
27690
27870
  }
27691
27871
  async function readText(filePath) {
27692
27872
  try {
27693
- return await readFile27(filePath, "utf8");
27873
+ return await readFile28(filePath, "utf8");
27694
27874
  } catch {
27695
27875
  return void 0;
27696
27876
  }
@@ -27719,15 +27899,15 @@ function isRunnableNodePackage(pkg) {
27719
27899
  return typeof scripts.start === "string" || typeof pkg.main === "string";
27720
27900
  }
27721
27901
  async function detectParentBackend(siteDirectory) {
27722
- const site = path85.resolve(siteDirectory);
27723
- const directory = path85.dirname(site);
27902
+ const site = path86.resolve(siteDirectory);
27903
+ const directory = path86.dirname(site);
27724
27904
  if (directory === site) {
27725
27905
  return void 0;
27726
27906
  }
27727
27907
  const files = await listFiles(directory);
27728
27908
  const toResult = (runtime, runtimeVersion, marker) => ({
27729
27909
  directory,
27730
- sourceDirectory: path85.relative(site, directory).split(path85.sep).join("/") || ".",
27910
+ sourceDirectory: path86.relative(site, directory).split(path86.sep).join("/") || ".",
27731
27911
  runtime,
27732
27912
  runtimeVersion,
27733
27913
  marker
@@ -27735,7 +27915,7 @@ async function detectParentBackend(siteDirectory) {
27735
27915
  const csproj = files.find((f) => f.endsWith(".csproj"));
27736
27916
  const solution = files.find((f) => /\.slnx?$/.test(f));
27737
27917
  if (csproj || solution) {
27738
- const content = csproj ? await readText(path85.join(directory, csproj)) : void 0;
27918
+ const content = csproj ? await readText(path86.join(directory, csproj)) : void 0;
27739
27919
  return toResult(
27740
27920
  "dotnet",
27741
27921
  dotnetVersionFromCsproj(content),
@@ -27743,7 +27923,7 @@ async function detectParentBackend(siteDirectory) {
27743
27923
  );
27744
27924
  }
27745
27925
  if (files.includes("package.json")) {
27746
- const raw = await readText(path85.join(directory, "package.json"));
27926
+ const raw = await readText(path86.join(directory, "package.json"));
27747
27927
  try {
27748
27928
  const pkg = JSON.parse(raw ?? "");
27749
27929
  if (isRunnableNodePackage(pkg)) {
@@ -27758,7 +27938,7 @@ async function detectParentBackend(siteDirectory) {
27758
27938
  }
27759
27939
  const pythonMarker = PYTHON_MARKERS.find((m) => files.includes(m));
27760
27940
  if (pythonMarker) {
27761
- const versionSource = await readText(path85.join(directory, ".python-version")) ?? (pythonMarker === "pyproject.toml" ? (await readText(path85.join(directory, pythonMarker)))?.match(
27941
+ const versionSource = await readText(path86.join(directory, ".python-version")) ?? (pythonMarker === "pyproject.toml" ? (await readText(path86.join(directory, pythonMarker)))?.match(
27762
27942
  /requires-python\s*=\s*"([^"]+)"/
27763
27943
  )?.[1] : void 0);
27764
27944
  return toResult(
@@ -27776,12 +27956,12 @@ import {
27776
27956
  lstat as lstat2,
27777
27957
  mkdir as mkdir21,
27778
27958
  readdir as readdir5,
27779
- readFile as readFile28,
27959
+ readFile as readFile29,
27780
27960
  readlink,
27781
27961
  symlink as symlink2,
27782
- writeFile as writeFile25
27962
+ writeFile as writeFile26
27783
27963
  } from "node:fs/promises";
27784
- import path86 from "node:path";
27964
+ import path87 from "node:path";
27785
27965
  var DOCS_DIR_WHITELIST = [
27786
27966
  "docs",
27787
27967
  "documents",
@@ -27818,14 +27998,14 @@ async function isDirectory2(filePath) {
27818
27998
  }
27819
27999
  }
27820
28000
  function toPosix3(value) {
27821
- return value.split(path86.sep).join(path86.posix.sep);
28001
+ return value.split(path87.sep).join(path87.posix.sep);
27822
28002
  }
27823
28003
  function isWhitelistedDirName(name) {
27824
28004
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
27825
28005
  }
27826
28006
  function isInside2(parent, child) {
27827
- const relative = path86.relative(parent, child);
27828
- return relative === "" || !relative.startsWith("..") && !path86.isAbsolute(relative);
28007
+ const relative = path87.relative(parent, child);
28008
+ return relative === "" || !relative.startsWith("..") && !path87.isAbsolute(relative);
27829
28009
  }
27830
28010
  async function collectMarkdownFiles(dir, excludeDir) {
27831
28011
  const files = [];
@@ -27839,9 +28019,9 @@ async function collectMarkdownFiles(dir, excludeDir) {
27839
28019
  if (entry.name.startsWith(".")) {
27840
28020
  continue;
27841
28021
  }
27842
- const full = path86.join(dir, entry.name);
28022
+ const full = path87.join(dir, entry.name);
27843
28023
  if (entry.isDirectory()) {
27844
- if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path86.resolve(full) === excludeDir) {
28024
+ if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink() || excludeDir && path87.resolve(full) === excludeDir) {
27845
28025
  continue;
27846
28026
  }
27847
28027
  files.push(...await collectMarkdownFiles(full, excludeDir));
@@ -27854,11 +28034,11 @@ async function collectMarkdownFiles(dir, excludeDir) {
27854
28034
  return files;
27855
28035
  }
27856
28036
  async function collectSearchRoots(siteDirectory) {
27857
- const site = path86.resolve(siteDirectory);
27858
- const parent = path86.dirname(site);
28037
+ const site = path87.resolve(siteDirectory);
28038
+ const parent = path87.dirname(site);
27859
28039
  const roots = [];
27860
28040
  const add = (dir) => {
27861
- const resolved = path86.resolve(dir);
28041
+ const resolved = path87.resolve(dir);
27862
28042
  if (!roots.includes(resolved)) {
27863
28043
  roots.push(resolved);
27864
28044
  }
@@ -27871,7 +28051,7 @@ async function collectSearchRoots(siteDirectory) {
27871
28051
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
27872
28052
  continue;
27873
28053
  }
27874
- add(path86.join(parent, entry.name));
28054
+ add(path87.join(parent, entry.name));
27875
28055
  }
27876
28056
  } catch {
27877
28057
  }
@@ -27880,13 +28060,13 @@ async function collectSearchRoots(siteDirectory) {
27880
28060
  return roots;
27881
28061
  }
27882
28062
  async function discoverNearbyDocsDirectories(siteDirectory) {
27883
- const site = path86.resolve(siteDirectory);
27884
- const sitePages = path86.join(site, PAGES_DIR);
28063
+ const site = path87.resolve(siteDirectory);
28064
+ const sitePages = path87.join(site, PAGES_DIR);
27885
28065
  const searchedDirectories = await collectSearchRoots(site);
27886
28066
  const directories = [];
27887
28067
  const seen = /* @__PURE__ */ new Set();
27888
28068
  const consider = async (dir) => {
27889
- const resolved = path86.resolve(dir);
28069
+ const resolved = path87.resolve(dir);
27890
28070
  if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
27891
28071
  return;
27892
28072
  }
@@ -27903,7 +28083,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
27903
28083
  directories.push({ sourceDirectory: resolved, files });
27904
28084
  };
27905
28085
  for (const root of searchedDirectories) {
27906
- if (isWhitelistedDirName(path86.basename(root))) {
28086
+ if (isWhitelistedDirName(path87.basename(root))) {
27907
28087
  await consider(root);
27908
28088
  }
27909
28089
  try {
@@ -27915,7 +28095,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
27915
28095
  if (!isWhitelistedDirName(entry.name)) {
27916
28096
  continue;
27917
28097
  }
27918
- await consider(path86.join(root, entry.name));
28098
+ await consider(path87.join(root, entry.name));
27919
28099
  }
27920
28100
  } catch {
27921
28101
  }
@@ -27934,8 +28114,8 @@ function slugifyDirName(name) {
27934
28114
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
27935
28115
  }
27936
28116
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
27937
- const base = slugifyDirName(path86.basename(sourceDirectory));
27938
- const parent = slugifyDirName(path86.basename(path86.dirname(sourceDirectory)));
28117
+ const base = slugifyDirName(path87.basename(sourceDirectory));
28118
+ const parent = slugifyDirName(path87.basename(path87.dirname(sourceDirectory)));
27939
28119
  const candidates = [base, `${parent}-${base}`];
27940
28120
  let index = 2;
27941
28121
  while (true) {
@@ -27943,7 +28123,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
27943
28123
  if (used.has(name)) {
27944
28124
  continue;
27945
28125
  }
27946
- const target = path86.join(pagesDir, name);
28126
+ const target = path87.join(pagesDir, name);
27947
28127
  if (await pathExists5(target)) {
27948
28128
  const stat7 = await lstat2(target);
27949
28129
  if (!stat7.isDirectory() || !await isManagedLinkDir(target)) {
@@ -27974,8 +28154,8 @@ async function alreadyLinked(linkPath, sourcePath) {
27974
28154
  return false;
27975
28155
  }
27976
28156
  const current = await readlink(linkPath);
27977
- const resolved = path86.resolve(path86.dirname(linkPath), current);
27978
- return resolved === path86.resolve(sourcePath);
28157
+ const resolved = path87.resolve(path87.dirname(linkPath), current);
28158
+ return resolved === path87.resolve(sourcePath);
27979
28159
  } catch {
27980
28160
  return false;
27981
28161
  }
@@ -27987,8 +28167,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
27987
28167
  if (await pathExists5(linkPath)) {
27988
28168
  return "skipped";
27989
28169
  }
27990
- await mkdir21(path86.dirname(linkPath), { recursive: true });
27991
- const relativeTarget = path86.relative(path86.dirname(linkPath), sourcePath);
28170
+ await mkdir21(path87.dirname(linkPath), { recursive: true });
28171
+ const relativeTarget = path87.relative(path87.dirname(linkPath), sourcePath);
27992
28172
  await symlink2(
27993
28173
  relativeTarget,
27994
28174
  linkPath,
@@ -28003,11 +28183,11 @@ async function applyDocsNavigation(siteDirectory, routes) {
28003
28183
  if (routes.length === 0) {
28004
28184
  return;
28005
28185
  }
28006
- const configPath = path86.join(siteDirectory, CONFIG_FILENAME);
28186
+ const configPath = path87.join(siteDirectory, CONFIG_FILENAME);
28007
28187
  if (!await pathExists5(configPath)) {
28008
28188
  return;
28009
28189
  }
28010
- const raw = await readFile28(configPath, "utf8");
28190
+ const raw = await readFile29(configPath, "utf8");
28011
28191
  const parsed = JSON.parse(raw);
28012
28192
  if (!isPlainObject5(parsed)) {
28013
28193
  return;
@@ -28016,12 +28196,12 @@ async function applyDocsNavigation(siteDirectory, routes) {
28016
28196
  force: false
28017
28197
  });
28018
28198
  const updated = ensureHeaderDocsNavigation(parsed, routes);
28019
- await writeFile25(configPath, `${JSON.stringify(updated, null, 2)}
28199
+ await writeFile26(configPath, `${JSON.stringify(updated, null, 2)}
28020
28200
  `, "utf8");
28021
28201
  }
28022
28202
  async function discoverAndWireDocs(siteDirectory) {
28023
- const site = path86.resolve(siteDirectory);
28024
- const pagesDir = path86.join(site, PAGES_DIR);
28203
+ const site = path87.resolve(siteDirectory);
28204
+ const pagesDir = path87.join(site, PAGES_DIR);
28025
28205
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
28026
28206
  if (directories.length === 0) {
28027
28207
  return {
@@ -28043,15 +28223,15 @@ async function discoverAndWireDocs(siteDirectory) {
28043
28223
  directory.sourceDirectory,
28044
28224
  usedNames
28045
28225
  );
28046
- const linkDirectory = path86.join(pagesDir, linkName);
28226
+ const linkDirectory = path87.join(pagesDir, linkName);
28047
28227
  const linked = [];
28048
28228
  const skipped = [];
28049
28229
  for (const sourcePath of directory.files) {
28050
28230
  const relativeSource = toPosix3(
28051
- path86.relative(directory.sourceDirectory, sourcePath)
28231
+ path87.relative(directory.sourceDirectory, sourcePath)
28052
28232
  );
28053
- const linkPath = path86.join(linkDirectory, relativeSource);
28054
- const relativeLink = toPosix3(path86.relative(site, linkPath));
28233
+ const linkPath = path87.join(linkDirectory, relativeSource);
28234
+ const relativeLink = toPosix3(path87.relative(site, linkPath));
28055
28235
  const route = toRoutePath(relativeLink, PAGES_DIR);
28056
28236
  if (routes.includes(route)) {
28057
28237
  skipped.push({
@@ -28099,11 +28279,11 @@ async function discoverAndWireDocs(siteDirectory) {
28099
28279
  };
28100
28280
  }
28101
28281
  function siteRelative(siteDirectory, filePath) {
28102
- const relative = toPosix3(path86.relative(siteDirectory, filePath));
28282
+ const relative = toPosix3(path87.relative(siteDirectory, filePath));
28103
28283
  if (!relative) {
28104
28284
  return ".";
28105
28285
  }
28106
- if (path86.isAbsolute(relative)) {
28286
+ if (path87.isAbsolute(relative)) {
28107
28287
  return toPosix3(filePath);
28108
28288
  }
28109
28289
  if (relative.startsWith("..")) {
@@ -28191,8 +28371,8 @@ async function pathExists6(filePath) {
28191
28371
  }
28192
28372
  async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
28193
28373
  const input5 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
28194
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28195
- const raw = await readFile29(jsonConfigPath, "utf8");
28374
+ const jsonConfigPath = path88.join(siteDirectory, "apitogo.config.json");
28375
+ const raw = await readFile30(jsonConfigPath, "utf8");
28196
28376
  const siteConfig = JSON.parse(raw);
28197
28377
  const updated = applyOpenApiToSiteConfig(siteConfig, {
28198
28378
  input: input5,
@@ -28200,7 +28380,7 @@ async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
28200
28380
  });
28201
28381
  const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
28202
28382
  updated.backend = { ...backend, openApiPath: input5 };
28203
- await writeFile26(
28383
+ await writeFile27(
28204
28384
  jsonConfigPath,
28205
28385
  `${JSON.stringify(updated, null, 2)}
28206
28386
  `,
@@ -28219,7 +28399,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
28219
28399
  const invalidCandidates = [];
28220
28400
  let selected;
28221
28401
  for (const candidate of search.candidates) {
28222
- const content = await readFile29(candidate, "utf8");
28402
+ const content = await readFile30(candidate, "utf8");
28223
28403
  const parsed = liteParseOpenApi(content, candidate);
28224
28404
  if (parsed.valid) {
28225
28405
  selected = {
@@ -28243,7 +28423,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
28243
28423
  wired: false
28244
28424
  };
28245
28425
  }
28246
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28426
+ const jsonConfigPath = path88.join(siteDirectory, "apitogo.config.json");
28247
28427
  if (!await pathExists6(jsonConfigPath)) {
28248
28428
  return {
28249
28429
  openApiDiscovery: {
@@ -28293,13 +28473,13 @@ async function discoverAndWireBackend(siteDirectory, mode) {
28293
28473
  if (mode !== "nearby") {
28294
28474
  return { status: "skipped", mode };
28295
28475
  }
28296
- const jsonConfigPath = path87.join(siteDirectory, "apitogo.config.json");
28476
+ const jsonConfigPath = path88.join(siteDirectory, "apitogo.config.json");
28297
28477
  if (!await pathExists6(jsonConfigPath)) {
28298
28478
  return { status: "not_found" };
28299
28479
  }
28300
28480
  try {
28301
28481
  const siteConfig = JSON.parse(
28302
- await readFile29(jsonConfigPath, "utf8")
28482
+ await readFile30(jsonConfigPath, "utf8")
28303
28483
  );
28304
28484
  const existing = siteConfig.backend && typeof siteConfig.backend === "object" && !Array.isArray(siteConfig.backend) ? siteConfig.backend : {};
28305
28485
  if (typeof existing.sourceDirectory === "string" && existing.sourceDirectory.trim()) {
@@ -28320,7 +28500,7 @@ async function discoverAndWireBackend(siteDirectory, mode) {
28320
28500
  runtime: detected.runtime,
28321
28501
  runtimeVersion: detected.runtimeVersion
28322
28502
  };
28323
- await writeFile26(
28503
+ await writeFile27(
28324
28504
  jsonConfigPath,
28325
28505
  `${JSON.stringify(siteConfig, null, 2)}
28326
28506
  `,
@@ -28360,8 +28540,8 @@ function slugifyName2(name) {
28360
28540
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
28361
28541
  }
28362
28542
  function resolveInitOutputDirectory(dirArg, name) {
28363
- const resolved = path88.resolve(process.cwd(), dirArg);
28364
- const base = path88.basename(resolved);
28543
+ const resolved = path89.resolve(process.cwd(), dirArg);
28544
+ const base = path89.basename(resolved);
28365
28545
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
28366
28546
  if (isDot) {
28367
28547
  const fromName = name?.trim();
@@ -28371,7 +28551,7 @@ function resolveInitOutputDirectory(dirArg, name) {
28371
28551
  );
28372
28552
  }
28373
28553
  return {
28374
- outputDirectory: path88.resolve(process.cwd(), slugifyName2(fromName)),
28554
+ outputDirectory: path89.resolve(process.cwd(), slugifyName2(fromName)),
28375
28555
  siteName: fromName
28376
28556
  };
28377
28557
  }
@@ -28554,8 +28734,8 @@ import open2 from "open";
28554
28734
  import colors14 from "picocolors";
28555
28735
 
28556
28736
  // src/cli/platform/device-auth.ts
28557
- function url(apiUrl, path101) {
28558
- return `${apiUrl}${path101.startsWith("/") ? path101 : `/${path101}`}`;
28737
+ function url(apiUrl, path102) {
28738
+ return `${apiUrl}${path102.startsWith("/") ? path102 : `/${path102}`}`;
28559
28739
  }
28560
28740
  async function requestDeviceCode(apiUrl) {
28561
28741
  const response = await fetchWithRetry(
@@ -28737,7 +28917,7 @@ var logout_default = {
28737
28917
  };
28738
28918
 
28739
28919
  // src/cli/portal/commands.ts
28740
- import path89 from "node:path";
28920
+ import path90 from "node:path";
28741
28921
  init_invariant();
28742
28922
  function parseOnly(value) {
28743
28923
  if (value === void 0) return void 0;
@@ -28754,7 +28934,7 @@ function parseOnly(value) {
28754
28934
  async function run2(command2, argv, compute, format) {
28755
28935
  const json = argv.json === true;
28756
28936
  try {
28757
- const dir = path89.resolve(process.cwd(), argv.dir ?? ".");
28937
+ const dir = path90.resolve(process.cwd(), argv.dir ?? ".");
28758
28938
  if (!await isConfigV2(dir)) {
28759
28939
  throw new ServiceEditError(
28760
28940
  `${command2} works with a config version 2 project, and there is none in ${dir}.`,
@@ -28838,7 +29018,7 @@ var plan_default = {
28838
29018
 
28839
29019
  // src/cli/project/create-handler.ts
28840
29020
  init_invariant();
28841
- import path90 from "node:path";
29021
+ import path91 from "node:path";
28842
29022
 
28843
29023
  // src/cli/project/v2.ts
28844
29024
  init_invariant();
@@ -28985,7 +29165,7 @@ async function createLinkedProject(argv, dir) {
28985
29165
  }
28986
29166
  }
28987
29167
  async function createProject(argv) {
28988
- const dir = path90.resolve(process.cwd(), argv.dir ?? ".");
29168
+ const dir = path91.resolve(process.cwd(), argv.dir ?? ".");
28989
29169
  if (await isConfigV2(dir)) {
28990
29170
  await createLinkedProject(argv, dir);
28991
29171
  return;
@@ -29109,14 +29289,14 @@ var remove_default = {
29109
29289
 
29110
29290
  // src/cli/dev/handler.ts
29111
29291
  init_joinUrl();
29112
- import path93 from "node:path";
29292
+ import path94 from "node:path";
29113
29293
 
29114
29294
  // src/vite/dev-server.ts
29115
29295
  init_logger();
29116
29296
  import fs12 from "node:fs/promises";
29117
29297
  import http from "node:http";
29118
29298
  import https from "node:https";
29119
- import path92 from "node:path";
29299
+ import path93 from "node:path";
29120
29300
  import { createHttpTerminator } from "http-terminator";
29121
29301
  import {
29122
29302
  createServer as createViteServer,
@@ -29149,7 +29329,7 @@ init_loader();
29149
29329
  // src/vite/pagefind-dev-index.ts
29150
29330
  init_invariant();
29151
29331
  init_joinUrl();
29152
- import path91 from "node:path";
29332
+ import path92 from "node:path";
29153
29333
  import { createIndex as createIndex2 } from "pagefind";
29154
29334
  import { isRunnableDevEnvironment } from "vite";
29155
29335
  async function* buildPagefindDevIndex(vite, config2) {
@@ -29202,7 +29382,7 @@ async function* buildPagefindDevIndex(vite, config2) {
29202
29382
  path: urlPath
29203
29383
  };
29204
29384
  }
29205
- const outputPath = path91.join(vite.config.publicDir, "pagefind");
29385
+ const outputPath = path92.join(vite.config.publicDir, "pagefind");
29206
29386
  await pagefindIndex.writeFiles({ outputPath });
29207
29387
  yield { type: "complete", success: true, indexed };
29208
29388
  }
@@ -29221,9 +29401,9 @@ var DevServer = class {
29221
29401
  this.protocol = "https";
29222
29402
  const { dir } = this.options;
29223
29403
  const [key, cert, ca] = await Promise.all([
29224
- fs12.readFile(path92.resolve(dir, config2.https.key)),
29225
- fs12.readFile(path92.resolve(dir, config2.https.cert)),
29226
- config2.https.ca ? fs12.readFile(path92.resolve(dir, config2.https.ca)) : void 0
29404
+ fs12.readFile(path93.resolve(dir, config2.https.key)),
29405
+ fs12.readFile(path93.resolve(dir, config2.https.cert)),
29406
+ config2.https.ca ? fs12.readFile(path93.resolve(dir, config2.https.ca)) : void 0
29227
29407
  ]);
29228
29408
  return https.createServer({ key, cert, ca });
29229
29409
  }
@@ -29240,7 +29420,7 @@ var DevServer = class {
29240
29420
  );
29241
29421
  const server = await this.createNodeServer(config2);
29242
29422
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
29243
- const publicRoot = path92.resolve(
29423
+ const publicRoot = path93.resolve(
29244
29424
  this.options.dir,
29245
29425
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
29246
29426
  );
@@ -29257,7 +29437,7 @@ var DevServer = class {
29257
29437
  // built-in transform middleware which would treat the path as a static asset.
29258
29438
  name: "apitogo:entry-client",
29259
29439
  configureServer(server2) {
29260
- const entryPath = path92.posix.join(
29440
+ const entryPath = path93.posix.join(
29261
29441
  server2.config.base,
29262
29442
  "/__z/entry.client.tsx"
29263
29443
  );
@@ -29422,7 +29602,7 @@ init_package_json();
29422
29602
  async function dev(argv) {
29423
29603
  const packageJson3 = getZudokuPackageJson();
29424
29604
  process.env.NODE_ENV = "development";
29425
- let dir = path93.resolve(process.cwd(), argv.dir);
29605
+ let dir = path94.resolve(process.cwd(), argv.dir);
29426
29606
  if (await isConfigV2(dir)) {
29427
29607
  const { root, prepared } = await preparePortalWorkspace(dir, "development");
29428
29608
  dir = root;
@@ -29521,7 +29701,7 @@ var run_default = {
29521
29701
  };
29522
29702
 
29523
29703
  // src/cli/secrets/handler.ts
29524
- import path94 from "node:path";
29704
+ import path95 from "node:path";
29525
29705
  init_invariant();
29526
29706
 
29527
29707
  // src/cli/secrets/input.ts
@@ -29586,7 +29766,7 @@ var SecretsError = class extends ApitogoError {
29586
29766
  async function resolveProjectId2(argv, deps) {
29587
29767
  const explicit = argv.projectId?.trim();
29588
29768
  if (explicit) return explicit;
29589
- const dir = path94.resolve(process.cwd(), argv.dir ?? ".");
29769
+ const dir = path95.resolve(process.cwd(), argv.dir ?? ".");
29590
29770
  if (await isConfigV2(dir)) {
29591
29771
  const id = loadConfigV2(dir).resolved.project.id;
29592
29772
  if (id) return id;
@@ -29746,12 +29926,12 @@ var secrets_default = {
29746
29926
  };
29747
29927
 
29748
29928
  // src/cli/cmds/status.ts
29749
- import path96 from "node:path";
29929
+ import path97 from "node:path";
29750
29930
 
29751
29931
  // src/cli/status/handler.ts
29752
- import path95 from "node:path";
29932
+ import path96 from "node:path";
29753
29933
  async function status(argv) {
29754
- const sourceDirectory = path95.resolve(process.cwd(), argv.dir);
29934
+ const sourceDirectory = path96.resolve(process.cwd(), argv.dir);
29755
29935
  let config2;
29756
29936
  try {
29757
29937
  config2 = loadConfig();
@@ -29849,7 +30029,7 @@ var status_default = {
29849
30029
  }),
29850
30030
  handler: async (argv) => {
29851
30031
  await captureEvent({ argv, event: "apitogo status" });
29852
- if (await isConfigV2(path96.resolve(process.cwd(), argv.dir))) {
30032
+ if (await isConfigV2(path97.resolve(process.cwd(), argv.dir))) {
29853
30033
  await statusOfProject(argv);
29854
30034
  return;
29855
30035
  }
@@ -29858,11 +30038,11 @@ var status_default = {
29858
30038
  };
29859
30039
 
29860
30040
  // src/cli/cmds/teardown.ts
29861
- import path99 from "node:path";
30041
+ import path100 from "node:path";
29862
30042
 
29863
30043
  // src/cli/teardown/command.ts
29864
30044
  init_invariant();
29865
- import path97 from "node:path";
30045
+ import path98 from "node:path";
29866
30046
  import { createInterface as createInterface7 } from "node:readline/promises";
29867
30047
 
29868
30048
  // src/cli/teardown/v2.ts
@@ -30079,7 +30259,7 @@ async function teardownProject(argv) {
30079
30259
  const progress = createConsoleProgressReporter();
30080
30260
  const result = await teardownV2(
30081
30261
  {
30082
- dir: path97.resolve(process.cwd(), argv.dir),
30262
+ dir: path98.resolve(process.cwd(), argv.dir),
30083
30263
  projectId: argv.projectId,
30084
30264
  only: Array.isArray(argv.only) ? argv.only.join(",") : argv.only,
30085
30265
  yes: argv.yes === true,
@@ -30138,7 +30318,7 @@ async function teardownProject(argv) {
30138
30318
  }
30139
30319
 
30140
30320
  // src/cli/teardown/handler.ts
30141
- import path98 from "node:path";
30321
+ import path99 from "node:path";
30142
30322
  function resultLooksFailed3(payload) {
30143
30323
  try {
30144
30324
  const parsed = JSON.parse(payload);
@@ -30154,7 +30334,7 @@ async function teardown(argv) {
30154
30334
  );
30155
30335
  return;
30156
30336
  }
30157
- const sourceDirectory = path98.resolve(process.cwd(), argv.dir);
30337
+ const sourceDirectory = path99.resolve(process.cwd(), argv.dir);
30158
30338
  let config2;
30159
30339
  try {
30160
30340
  config2 = loadConfig();
@@ -30232,7 +30412,7 @@ var teardown_default = {
30232
30412
  }),
30233
30413
  handler: async (argv) => {
30234
30414
  await captureEvent({ argv, event: "apitogo teardown" });
30235
- if (await isConfigV2(path99.resolve(process.cwd(), argv.dir))) {
30415
+ if (await isConfigV2(path100.resolve(process.cwd(), argv.dir))) {
30236
30416
  await teardownProject(argv);
30237
30417
  return;
30238
30418
  }
@@ -30309,37 +30489,37 @@ function createApitogoCli(argv) {
30309
30489
 
30310
30490
  // src/cli/local-handoff.ts
30311
30491
  import { spawn as spawn5 } from "node:child_process";
30312
- import { existsSync as existsSync8, realpathSync } from "node:fs";
30313
- import path100 from "node:path";
30492
+ import { existsSync as existsSync9, realpathSync } from "node:fs";
30493
+ import path101 from "node:path";
30314
30494
  var LOCAL_HANDOFF_ENV = "APITOGO_LOCAL_CLI";
30315
30495
  var PACKAGE_NAME = "@lukoweb/apitogo";
30316
30496
  var resolveProjectDir = (argv, cwd) => {
30317
30497
  for (let i = 0; i < argv.length; i++) {
30318
30498
  const arg = argv[i];
30319
30499
  const next = argv[i + 1];
30320
- if (arg === "--dir" && next) return path100.resolve(cwd, next);
30500
+ if (arg === "--dir" && next) return path101.resolve(cwd, next);
30321
30501
  if (arg?.startsWith("--dir=")) {
30322
- return path100.resolve(cwd, arg.slice("--dir=".length));
30502
+ return path101.resolve(cwd, arg.slice("--dir=".length));
30323
30503
  }
30324
30504
  }
30325
30505
  return cwd;
30326
30506
  };
30327
30507
  var findLocalCli = (projectDir, runningRoot) => {
30328
- let dir = path100.resolve(projectDir);
30508
+ let dir = path101.resolve(projectDir);
30329
30509
  let localPackageRoot;
30330
30510
  while (!localPackageRoot) {
30331
- const candidate = path100.join(dir, "node_modules", PACKAGE_NAME);
30332
- if (existsSync8(path100.join(candidate, "package.json"))) {
30511
+ const candidate = path101.join(dir, "node_modules", PACKAGE_NAME);
30512
+ if (existsSync9(path101.join(candidate, "package.json"))) {
30333
30513
  localPackageRoot = candidate;
30334
- } else if (dir === path100.dirname(dir)) {
30514
+ } else if (dir === path101.dirname(dir)) {
30335
30515
  return void 0;
30336
30516
  } else {
30337
- dir = path100.dirname(dir);
30517
+ dir = path101.dirname(dir);
30338
30518
  }
30339
30519
  }
30340
30520
  const localRoot = realpathSync(localPackageRoot);
30341
30521
  if (localRoot === realpathSync(runningRoot)) return void 0;
30342
- return path100.join(localRoot, "cli.js");
30522
+ return path101.join(localRoot, "cli.js");
30343
30523
  };
30344
30524
  var handoffToLocalCli = async (argv, runningRoot) => {
30345
30525
  if (process.env[LOCAL_HANDOFF_ENV] || process.env.ZUDOKU_ENV === "internal") {
@@ -30351,7 +30531,7 @@ var handoffToLocalCli = async (argv, runningRoot) => {
30351
30531
  );
30352
30532
  if (!localCli) return void 0;
30353
30533
  printDiagnosticsToConsole(
30354
- `Using the project's local ${PACKAGE_NAME} (${path100.dirname(localCli)})`
30534
+ `Using the project's local ${PACKAGE_NAME} (${path101.dirname(localCli)})`
30355
30535
  );
30356
30536
  const child = spawn5(process.execPath, [localCli, ...argv], {
30357
30537
  stdio: "inherit",