@lukoweb/apitogo 0.1.95 → 0.1.97

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
@@ -10,18 +10,18 @@ var __export = (target, all) => {
10
10
 
11
11
  // src/cli/common/package-json.ts
12
12
  import { readFileSync } from "node:fs";
13
- import path18 from "node:path";
13
+ import path19 from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
15
  var getPackageJsonPath, getPackageJson, getZudokuPackageJson, getZudokuRootDir;
16
16
  var init_package_json = __esm({
17
17
  "src/cli/common/package-json.ts"() {
18
18
  getPackageJsonPath = (pkg) => fileURLToPath(import.meta.resolve(`${pkg}/package.json`)).replaceAll(
19
- path18.sep,
20
- path18.posix.sep
19
+ path19.sep,
20
+ path19.posix.sep
21
21
  );
22
22
  getPackageJson = (pkgPath) => JSON.parse(readFileSync(pkgPath, "utf-8"));
23
23
  getZudokuPackageJson = () => getPackageJson(getPackageJsonPath("@lukoweb/apitogo"));
24
- getZudokuRootDir = () => path18.dirname(getPackageJsonPath("@lukoweb/apitogo"));
24
+ getZudokuRootDir = () => path19.dirname(getPackageJsonPath("@lukoweb/apitogo"));
25
25
  }
26
26
  });
27
27
 
@@ -654,12 +654,12 @@ var init_apitogo_config_core = __esm({
654
654
 
655
655
  // src/config/apitogo-config-loader.node.ts
656
656
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
657
- import path19 from "node:path";
657
+ import path20 from "node:path";
658
658
  function loadApitogoConfig(rootDir = process.cwd()) {
659
- const configPath = path19.join(path19.resolve(rootDir), APITOGO_CONFIG_FILENAME2);
659
+ const configPath = path20.join(path20.resolve(rootDir), APITOGO_CONFIG_FILENAME2);
660
660
  if (!existsSync2(configPath)) {
661
661
  throw new Error(
662
- `Missing ${APITOGO_CONFIG_FILENAME2} in ${path19.resolve(rootDir)}`
662
+ `Missing ${APITOGO_CONFIG_FILENAME2} in ${path20.resolve(rootDir)}`
663
663
  );
664
664
  }
665
665
  const raw = readFileSync2(configPath, "utf8");
@@ -734,7 +734,7 @@ import { stat } from "node:fs/promises";
734
734
  var fileExists;
735
735
  var init_file_exists = __esm({
736
736
  "src/config/file-exists.ts"() {
737
- fileExists = (path67) => stat(path67).then(() => true).catch(() => false);
737
+ fileExists = (path70) => stat(path70).then(() => true).catch(() => false);
738
738
  }
739
739
  });
740
740
 
@@ -978,7 +978,7 @@ var init_landing_manifest = __esm({
978
978
  });
979
979
 
980
980
  // src/config/local-manifest.ts
981
- import path20 from "node:path";
981
+ import path21 from "node:path";
982
982
  import { z as z4 } from "zod";
983
983
  function isPricingEnabled(manifest) {
984
984
  return manifest?.pricing?.enabled === true;
@@ -1028,8 +1028,8 @@ function resolveManifestEnv(viteMode) {
1028
1028
  return viteMode === "production" ? "production" : "development";
1029
1029
  }
1030
1030
  function manifestPathsForEnv(rootDir, _env) {
1031
- const resolvedRoot = path20.resolve(rootDir);
1032
- const configPath = path20.join(resolvedRoot, APITOGO_CONFIG_FILENAME2);
1031
+ const resolvedRoot = path21.resolve(rootDir);
1032
+ const configPath = path21.join(resolvedRoot, APITOGO_CONFIG_FILENAME2);
1033
1033
  return {
1034
1034
  basePath: configPath,
1035
1035
  overridePath: configPath,
@@ -1705,7 +1705,7 @@ var init_shadcn_registry = __esm({
1705
1705
 
1706
1706
  // src/vite/plugin-theme.ts
1707
1707
  import { createRequire as createRequire2 } from "node:module";
1708
- import path21 from "node:path";
1708
+ import path22 from "node:path";
1709
1709
  import { normalizeTheme } from "shiki";
1710
1710
  var THEME_VARIABLES, uncamelize, processColorValue, generateCss, generateRegistryCss, processCustomCss, MAIN_REPLACE, DEFAULT_THEME_REPLACE, GOOGLE_FONTS, getGoogleFontUrl, processFont, processFontConfig, DEFAULT_FONT_SANS, DEFAULT_FONT_MONO, DEFAULT_FONT_HEADING, processFonts, MODULE_SOURCE_PACKAGES, resolveModuleSourceDirs, virtualModuleId, resolvedVirtualModuleId, viteThemePlugin;
1711
1711
  var init_plugin_theme = __esm({
@@ -1884,7 +1884,7 @@ var init_plugin_theme = __esm({
1884
1884
  resolveModuleSourceDirs = (config2) => {
1885
1885
  if (config2.__meta.mode === "internal") {
1886
1886
  return MODULE_SOURCE_PACKAGES.map(
1887
- (pkg) => path21.join(
1887
+ (pkg) => path22.join(
1888
1888
  config2.__meta.moduleDir,
1889
1889
  "..",
1890
1890
  pkg.replace("@lukoweb/apitogo-", ""),
@@ -1893,12 +1893,12 @@ var init_plugin_theme = __esm({
1893
1893
  );
1894
1894
  }
1895
1895
  const require2 = createRequire2(
1896
- path21.join(config2.__meta.rootDir, "package.json")
1896
+ path22.join(config2.__meta.rootDir, "package.json")
1897
1897
  );
1898
1898
  const dirs = [];
1899
1899
  for (const pkg of MODULE_SOURCE_PACKAGES) {
1900
1900
  try {
1901
- dirs.push(path21.dirname(require2.resolve(pkg)));
1901
+ dirs.push(path22.dirname(require2.resolve(pkg)));
1902
1902
  } catch {
1903
1903
  }
1904
1904
  }
@@ -2024,7 +2024,7 @@ ${rootVars.join("\n")}
2024
2024
  ...config2.__meta.dependencies,
2025
2025
  ...config2.__pluginDirs ?? [],
2026
2026
  ...resolveModuleSourceDirs(config2)
2027
- ].map((file) => path21.relative(path21.dirname(id), file))
2027
+ ].map((file) => path22.relative(path22.dirname(id), file))
2028
2028
  );
2029
2029
  const code = [...files].map((file) => `@source "${file}";`);
2030
2030
  code.push("@theme inline {");
@@ -4866,7 +4866,7 @@ var init_ZudokuConfig = __esm({
4866
4866
 
4867
4867
  // src/config/loader.ts
4868
4868
  import { stat as stat2 } from "node:fs/promises";
4869
- import path22 from "node:path";
4869
+ import path23 from "node:path";
4870
4870
  import colors3 from "picocolors";
4871
4871
  import {
4872
4872
  runnerImport,
@@ -4893,7 +4893,7 @@ function mergeJsonConfigWithRuntimeOverrides(fileConfig, importedConfig) {
4893
4893
  }
4894
4894
  async function getConfigFilePath(rootDir) {
4895
4895
  for (const fileName of zudokuConfigFiles) {
4896
- const filepath = path22.join(rootDir, fileName);
4896
+ const filepath = path23.join(rootDir, fileName);
4897
4897
  if (await fileExists(filepath)) {
4898
4898
  return filepath;
4899
4899
  }
@@ -5126,7 +5126,7 @@ __export(llms_exports, {
5126
5126
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
5127
5127
  });
5128
5128
  import { writeFile as writeFile9 } from "node:fs/promises";
5129
- import path44 from "node:path";
5129
+ import path46 from "node:path";
5130
5130
  import colors7 from "picocolors";
5131
5131
  async function generateLlmsTxtFiles({
5132
5132
  markdownFileInfos,
@@ -5161,7 +5161,7 @@ async function generateLlmsTxtFiles({
5161
5161
  }
5162
5162
  }
5163
5163
  const llmsTxt2 = llmsTxtParts.join("\n");
5164
- await writeFile9(path44.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5164
+ await writeFile9(path46.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5165
5165
  if (process.env.APITOGO_JSON_ONLY !== "1") {
5166
5166
  console.log(colors7.blue("\u2713 generated llms.txt"));
5167
5167
  }
@@ -5189,7 +5189,7 @@ ${info.content}
5189
5189
  }
5190
5190
  const llmsFull = llmsFullParts.join("\n");
5191
5191
  await writeFile9(
5192
- path44.join(baseOutputDir, "llms-full.txt"),
5192
+ path46.join(baseOutputDir, "llms-full.txt"),
5193
5193
  llmsFull,
5194
5194
  "utf-8"
5195
5195
  );
@@ -5315,7 +5315,7 @@ async function shutdownAnalytics() {
5315
5315
  }
5316
5316
 
5317
5317
  // src/cli/apply/handler.ts
5318
- import path17 from "node:path";
5318
+ import path18 from "node:path";
5319
5319
 
5320
5320
  // src/cli/common/output.ts
5321
5321
  import * as Sentry from "@sentry/node";
@@ -5504,8 +5504,8 @@ var PlatformApiClient = class {
5504
5504
  constructor(config2) {
5505
5505
  this.config = config2;
5506
5506
  }
5507
- url(path67) {
5508
- return `${this.config.apiUrl}${path67.startsWith("/") ? path67 : `/${path67}`}`;
5507
+ url(path70) {
5508
+ return `${this.config.apiUrl}${path70.startsWith("/") ? path70 : `/${path70}`}`;
5509
5509
  }
5510
5510
  headers(extra) {
5511
5511
  return {
@@ -5515,9 +5515,9 @@ var PlatformApiClient = class {
5515
5515
  ...extra
5516
5516
  };
5517
5517
  }
5518
- async request(method, path67, init4) {
5518
+ async request(method, path70, init4) {
5519
5519
  const response = await fetchWithRetry(
5520
- this.url(path67),
5520
+ this.url(path70),
5521
5521
  {
5522
5522
  method,
5523
5523
  ...init4,
@@ -5717,15 +5717,15 @@ var PlatformApiClient = class {
5717
5717
  }
5718
5718
  );
5719
5719
  }
5720
- deleteDevPortalPage(projectId, path67) {
5721
- const query = new URLSearchParams({ path: path67 });
5720
+ deleteDevPortalPage(projectId, path70) {
5721
+ const query = new URLSearchParams({ path: path70 });
5722
5722
  return this.request(
5723
5723
  "DELETE",
5724
5724
  `/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
5725
5725
  );
5726
5726
  }
5727
- renameDevPortalPage(projectId, path67, newName) {
5728
- const query = new URLSearchParams({ path: path67 });
5727
+ renameDevPortalPage(projectId, path70, newName) {
5728
+ const query = new URLSearchParams({ path: path70 });
5729
5729
  return this.request(
5730
5730
  "POST",
5731
5731
  `/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
@@ -5896,8 +5896,8 @@ var PlatformApiClient = class {
5896
5896
  }
5897
5897
  };
5898
5898
  async function readFileBytes(filePath) {
5899
- const { readFile: readFile19 } = await import("node:fs/promises");
5900
- const buffer = await readFile19(filePath);
5899
+ const { readFile: readFile20 } = await import("node:fs/promises");
5900
+ const buffer = await readFile20(filePath);
5901
5901
  const arrayBuffer = new ArrayBuffer(buffer.byteLength);
5902
5902
  new Uint8Array(arrayBuffer).set(buffer);
5903
5903
  return arrayBuffer;
@@ -7317,8 +7317,8 @@ function normalizeActionKey(actionKey) {
7317
7317
  const trimmed = actionKey.trim();
7318
7318
  if (trimmed.includes(":")) {
7319
7319
  const [method2, ...pathParts] = trimmed.split(":");
7320
- const path68 = pathParts.join(":").trim();
7321
- return `${method2.toLowerCase()}:${path68.startsWith("/") ? path68 : `/${path68}`}`;
7320
+ const path71 = pathParts.join(":").trim();
7321
+ return `${method2.toLowerCase()}:${path71.startsWith("/") ? path71 : `/${path71}`}`;
7322
7322
  }
7323
7323
  const spaceIndex = trimmed.indexOf(" ");
7324
7324
  if (spaceIndex <= 0) {
@@ -7327,8 +7327,8 @@ function normalizeActionKey(actionKey) {
7327
7327
  );
7328
7328
  }
7329
7329
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
7330
- const path67 = trimmed.slice(spaceIndex + 1).trim();
7331
- return `${method}:${path67.startsWith("/") ? path67 : `/${path67}`}`;
7330
+ const path70 = trimmed.slice(spaceIndex + 1).trim();
7331
+ return `${method}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
7332
7332
  }
7333
7333
  async function applyGatewayPublicRoutes(client, projectId, routes, options) {
7334
7334
  const applied = [];
@@ -8793,10 +8793,14 @@ function formatJobStatusResponse(options) {
8793
8793
  }
8794
8794
 
8795
8795
  // src/cli/platform/helpers/openapi.ts
8796
- import { promises as fs3 } from "node:fs";
8797
- import path9 from "node:path";
8796
+ import { promises as fs4 } from "node:fs";
8797
+ import path10 from "node:path";
8798
8798
  import SwaggerParser from "@apidevtools/swagger-parser";
8799
8799
  import YAML2 from "yaml";
8800
+
8801
+ // src/cli/scaffold/discover-openapi-files.ts
8802
+ import { promises as fs3 } from "node:fs";
8803
+ import path9 from "node:path";
8800
8804
  var OPENAPI_BASENAMES = [
8801
8805
  "openapi.yaml",
8802
8806
  "openapi.yml",
@@ -8805,6 +8809,7 @@ var OPENAPI_BASENAMES = [
8805
8809
  "swagger.yml",
8806
8810
  "swagger.json"
8807
8811
  ];
8812
+ var OPENAPI_NOT_FOUND_SUGGESTION = "No OpenAPI file found near the site (checked parent, sibling folders, and the site directory for openapi.yaml|yml|json / swagger.yaml|yml|json). Ask the user for a path, or offer to draft a starter OpenAPI 3 spec from their API description, write it next to the site (e.g. ../openapi.yaml), then call set_dev_portal_openapi.";
8808
8813
  var SKIP_OPENAPI_SEARCH_DIRS = /* @__PURE__ */ new Set([
8809
8814
  "node_modules",
8810
8815
  ".git",
@@ -8816,28 +8821,34 @@ var SKIP_OPENAPI_SEARCH_DIRS = /* @__PURE__ */ new Set([
8816
8821
  ".cache",
8817
8822
  ".apitogo"
8818
8823
  ]);
8819
- async function discoverNearbyOpenApi(siteDirectory) {
8824
+ async function collectFromDir(dir, searchedDirectories, candidates) {
8825
+ const resolved = path9.resolve(dir);
8826
+ if (searchedDirectories.includes(resolved)) {
8827
+ return;
8828
+ }
8829
+ searchedDirectories.push(resolved);
8830
+ for (const name of OPENAPI_BASENAMES) {
8831
+ const candidate = path9.join(resolved, name);
8832
+ try {
8833
+ await fs3.access(candidate);
8834
+ candidates.push(candidate);
8835
+ } catch {
8836
+ }
8837
+ }
8838
+ }
8839
+ async function collectSiteOpenApiFiles(siteDirectory) {
8840
+ const searchedDirectories = [];
8841
+ const candidates = [];
8842
+ await collectFromDir(siteDirectory, searchedDirectories, candidates);
8843
+ return { candidates: [...new Set(candidates)], searchedDirectories };
8844
+ }
8845
+ async function collectNearbyOpenApiFiles(siteDirectory) {
8820
8846
  const site = path9.resolve(siteDirectory);
8821
8847
  const parent = path9.dirname(site);
8822
8848
  const searchedDirectories = [];
8823
8849
  const candidates = [];
8824
- const collectFromDir = async (dir) => {
8825
- const resolved = path9.resolve(dir);
8826
- if (searchedDirectories.includes(resolved)) {
8827
- return;
8828
- }
8829
- searchedDirectories.push(resolved);
8830
- for (const name of OPENAPI_BASENAMES) {
8831
- const candidate = path9.join(resolved, name);
8832
- try {
8833
- await fs3.access(candidate);
8834
- candidates.push(candidate);
8835
- } catch {
8836
- }
8837
- }
8838
- };
8839
8850
  if (parent && parent !== site) {
8840
- await collectFromDir(parent);
8851
+ await collectFromDir(parent, searchedDirectories, candidates);
8841
8852
  try {
8842
8853
  const entries = await fs3.readdir(parent, { withFileTypes: true });
8843
8854
  for (const entry of entries) {
@@ -8848,15 +8859,75 @@ async function discoverNearbyOpenApi(siteDirectory) {
8848
8859
  if (path9.resolve(sibling) === site) {
8849
8860
  continue;
8850
8861
  }
8851
- await collectFromDir(sibling);
8862
+ await collectFromDir(sibling, searchedDirectories, candidates);
8852
8863
  }
8853
8864
  } catch {
8854
8865
  }
8855
8866
  }
8856
- await collectFromDir(site);
8857
- const unique = [...new Set(candidates)];
8867
+ await collectFromDir(site, searchedDirectories, candidates);
8868
+ return { candidates: [...new Set(candidates)], searchedDirectories };
8869
+ }
8870
+ function parseOpenApiObject(doc) {
8871
+ const openapi = doc.openapi;
8872
+ if (typeof openapi !== "string" || !openapi.startsWith("3.")) {
8873
+ return {
8874
+ valid: false,
8875
+ errors: [`OpenAPI 3.x required; found ${String(openapi ?? "missing")}.`]
8876
+ };
8877
+ }
8878
+ const info = doc.info;
8879
+ return {
8880
+ valid: true,
8881
+ version: openapi,
8882
+ title: info?.title,
8883
+ errors: []
8884
+ };
8885
+ }
8886
+ function liteParseOpenApi(content, filePath) {
8887
+ const ext = path9.extname(filePath).toLowerCase();
8888
+ if (ext === ".json") {
8889
+ try {
8890
+ const parsed = JSON.parse(content);
8891
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
8892
+ return {
8893
+ valid: false,
8894
+ errors: ["OpenAPI document must be a JSON object."]
8895
+ };
8896
+ }
8897
+ return parseOpenApiObject(parsed);
8898
+ } catch (err) {
8899
+ return {
8900
+ valid: false,
8901
+ errors: [
8902
+ `Failed to parse OpenAPI document: ${err instanceof Error ? err.message : String(err)}`
8903
+ ]
8904
+ };
8905
+ }
8906
+ }
8907
+ const versionMatch = content.match(
8908
+ /^\s*openapi:\s*['"]?(3\.\d+(?:\.\d+)?)['"]?/m
8909
+ );
8910
+ if (!versionMatch?.[1]) {
8911
+ return {
8912
+ valid: false,
8913
+ errors: ["OpenAPI 3.x required; missing openapi: 3.x field."]
8914
+ };
8915
+ }
8916
+ const infoBlock = content.match(/^\s*info:\s*\n((?:[ \t].*\n)+)/m);
8917
+ const titleMatch = infoBlock?.[1]?.match(/^\s*title:\s*['"]?(.+?)['"]?\s*$/m);
8918
+ return {
8919
+ valid: true,
8920
+ version: versionMatch[1],
8921
+ title: titleMatch?.[1]?.trim(),
8922
+ errors: []
8923
+ };
8924
+ }
8925
+
8926
+ // src/cli/platform/helpers/openapi.ts
8927
+ async function discoverNearbyOpenApi(siteDirectory) {
8928
+ const { candidates, searchedDirectories } = await collectNearbyOpenApiFiles(siteDirectory);
8858
8929
  const invalidCandidates = [];
8859
- for (const candidate of unique) {
8930
+ for (const candidate of candidates) {
8860
8931
  const validation = await validateOpenApiFile(candidate);
8861
8932
  if (validation.valid) {
8862
8933
  return {
@@ -8864,35 +8935,39 @@ async function discoverNearbyOpenApi(siteDirectory) {
8864
8935
  selectedPath: candidate,
8865
8936
  version: validation.version,
8866
8937
  title: validation.title,
8867
- candidates: unique,
8938
+ candidates,
8868
8939
  searchedDirectories
8869
8940
  };
8870
8941
  }
8871
8942
  invalidCandidates.push({ path: candidate, errors: validation.errors });
8872
8943
  }
8873
8944
  return {
8874
- status: unique.length > 0 ? "invalid" : "not_found",
8875
- candidates: unique,
8945
+ status: candidates.length > 0 ? "invalid" : "not_found",
8946
+ candidates,
8876
8947
  searchedDirectories,
8877
8948
  ...invalidCandidates.length > 0 ? { invalidCandidates } : {}
8878
8949
  };
8879
8950
  }
8880
- var OPENAPI_NOT_FOUND_SUGGESTION = "No OpenAPI file found near the site (checked parent, sibling folders, and the site directory for openapi.yaml|yml|json / swagger.yaml|yml|json). Ask the user for a path, or offer to draft a starter OpenAPI 3 spec from their API description, write it next to the site (e.g. ../openapi.yaml), then call set_dev_portal_openapi.";
8881
8951
  async function validateOpenApiFile(filePath) {
8882
- const resolved = path9.resolve(filePath);
8883
- const content = await fs3.readFile(resolved, "utf8");
8884
- const ext = path9.extname(resolved).toLowerCase();
8952
+ const resolved = path10.resolve(filePath);
8953
+ const content = await fs4.readFile(resolved, "utf8");
8954
+ const ext = path10.extname(resolved).toLowerCase();
8885
8955
  let parsed;
8886
8956
  try {
8887
8957
  parsed = ext === ".json" ? JSON.parse(content) : YAML2.parse(content);
8888
8958
  } catch (err) {
8889
8959
  return {
8890
8960
  valid: false,
8891
- errors: [`Failed to parse OpenAPI document: ${err instanceof Error ? err.message : String(err)}`]
8961
+ errors: [
8962
+ `Failed to parse OpenAPI document: ${err instanceof Error ? err.message : String(err)}`
8963
+ ]
8892
8964
  };
8893
8965
  }
8894
8966
  if (!parsed || typeof parsed !== "object") {
8895
- return { valid: false, errors: ["OpenAPI document must be a JSON or YAML object."] };
8967
+ return {
8968
+ valid: false,
8969
+ errors: ["OpenAPI document must be a JSON or YAML object."]
8970
+ };
8896
8971
  }
8897
8972
  const doc = parsed;
8898
8973
  const openapi = doc.openapi;
@@ -8918,14 +8993,14 @@ async function validateOpenApiFile(filePath) {
8918
8993
  }
8919
8994
 
8920
8995
  // src/cli/platform/helpers/zip.ts
8921
- import { createReadStream as createReadStream2, createWriteStream, promises as fs4 } from "node:fs";
8996
+ import { createReadStream as createReadStream2, createWriteStream, promises as fs5 } from "node:fs";
8922
8997
  import { tmpdir as tmpdir2 } from "node:os";
8923
- import path10 from "node:path";
8998
+ import path11 from "node:path";
8924
8999
  import { ZipArchive } from "archiver";
8925
9000
  async function packageBackendDirectory(sourceDirectory) {
8926
- const resolved = path10.resolve(sourceDirectory);
9001
+ const resolved = path11.resolve(sourceDirectory);
8927
9002
  const files = await collectPackageableFiles(resolved);
8928
- const zipPath = path10.join(
9003
+ const zipPath = path11.join(
8929
9004
  tmpdir2(),
8930
9005
  `apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
8931
9006
  );
@@ -8937,15 +9012,15 @@ async function packageBackendDirectory(sourceDirectory) {
8937
9012
  output2.on("error", reject);
8938
9013
  archive.pipe(output2);
8939
9014
  for (const rel of files) {
8940
- archive.append(createReadStream2(path10.join(resolved, rel)), { name: rel.split(path10.sep).join("/") });
9015
+ archive.append(createReadStream2(path11.join(resolved, rel)), { name: rel.split(path11.sep).join("/") });
8941
9016
  }
8942
9017
  void archive.finalize();
8943
9018
  });
8944
- const { size } = await fs4.stat(zipPath);
9019
+ const { size } = await fs5.stat(zipPath);
8945
9020
  return { zipPath, byteSize: size };
8946
9021
  }
8947
9022
  async function cleanupZip(zipPath) {
8948
- await fs4.unlink(zipPath).catch(() => void 0);
9023
+ await fs5.unlink(zipPath).catch(() => void 0);
8949
9024
  }
8950
9025
 
8951
9026
  // src/cli/platform/tools/infrastructure.ts
@@ -10363,13 +10438,13 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
10363
10438
  }
10364
10439
 
10365
10440
  // src/cli/platform/tools/dev-portal.ts
10366
- import { promises as fs6 } from "node:fs";
10367
- import path13 from "node:path";
10441
+ import { promises as fs7 } from "node:fs";
10442
+ import path14 from "node:path";
10368
10443
 
10369
10444
  // src/cli/platform/helpers/tarball.ts
10370
- import { createReadStream as createReadStream3, createWriteStream as createWriteStream2, promises as fs5 } from "node:fs";
10445
+ import { createReadStream as createReadStream3, createWriteStream as createWriteStream2, promises as fs6 } from "node:fs";
10371
10446
  import { tmpdir as tmpdir3 } from "node:os";
10372
- import path11 from "node:path";
10447
+ import path12 from "node:path";
10373
10448
  import { TarArchive } from "archiver";
10374
10449
  var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
10375
10450
  function normalizeArchiveRoot(archiveRoot) {
@@ -10380,10 +10455,10 @@ function normalizeArchiveRoot(archiveRoot) {
10380
10455
  return `${trimmed}/`;
10381
10456
  }
10382
10457
  async function packageDirectoryAsTarGz(sourceDirectory, options) {
10383
- const resolved = path11.resolve(sourceDirectory);
10458
+ const resolved = path12.resolve(sourceDirectory);
10384
10459
  const files = await collectPackageableFiles(resolved);
10385
10460
  const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
10386
- const archivePath = path11.join(
10461
+ const archivePath = path12.join(
10387
10462
  tmpdir3(),
10388
10463
  `apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
10389
10464
  );
@@ -10395,16 +10470,16 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
10395
10470
  output2.on("error", reject);
10396
10471
  archive.pipe(output2);
10397
10472
  for (const rel of files) {
10398
- const entryName = entryPrefix + rel.split(path11.sep).join("/");
10399
- archive.append(createReadStream3(path11.join(resolved, rel)), { name: entryName });
10473
+ const entryName = entryPrefix + rel.split(path12.sep).join("/");
10474
+ archive.append(createReadStream3(path12.join(resolved, rel)), { name: entryName });
10400
10475
  }
10401
10476
  void archive.finalize();
10402
10477
  });
10403
- const { size } = await fs5.stat(archivePath);
10478
+ const { size } = await fs6.stat(archivePath);
10404
10479
  return { archivePath, byteSize: size };
10405
10480
  }
10406
10481
  async function cleanupArchive(archivePath) {
10407
- await fs5.unlink(archivePath).catch(() => void 0);
10482
+ await fs6.unlink(archivePath).catch(() => void 0);
10408
10483
  }
10409
10484
  function isTarGzPath(filePath) {
10410
10485
  const normalized = filePath.toLowerCase();
@@ -10520,7 +10595,7 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
10520
10595
 
10521
10596
  // src/cli/platform/helpers/dev-portal-site-api-url.ts
10522
10597
  import { readdir as readdir2, readFile as readFile6, writeFile as writeFile5 } from "node:fs/promises";
10523
- import path12 from "node:path";
10598
+ import path13 from "node:path";
10524
10599
  var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
10525
10600
  var PLACEHOLDER_HOST_MARKERS = [
10526
10601
  "dp-example.azurecontainerapps.io",
@@ -10538,10 +10613,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
10538
10613
  return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
10539
10614
  }
10540
10615
  async function readSiteApiBaseUrl(sourceDirectory) {
10541
- const resolved = path12.resolve(sourceDirectory);
10616
+ const resolved = path13.resolve(sourceDirectory);
10542
10617
  for (const envFile of [".env", ".env.production"]) {
10543
10618
  try {
10544
- const content = await readFile6(path12.join(resolved, envFile), "utf8");
10619
+ const content = await readFile6(path13.join(resolved, envFile), "utf8");
10545
10620
  const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
10546
10621
  if (lines.length === 0) {
10547
10622
  continue;
@@ -10566,11 +10641,11 @@ async function readSiteApiBaseUrl(sourceDirectory) {
10566
10641
  return null;
10567
10642
  }
10568
10643
  async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
10569
- const resolved = path12.resolve(sourceDirectory);
10644
+ const resolved = path13.resolve(sourceDirectory);
10570
10645
  const line = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
10571
10646
  let patchedExisting = false;
10572
10647
  for (const envFile of [".env.production", ".env"]) {
10573
- const envPath = path12.join(resolved, envFile);
10648
+ const envPath = path13.join(resolved, envFile);
10574
10649
  try {
10575
10650
  const content = await readFile6(envPath, "utf8");
10576
10651
  const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
@@ -10584,7 +10659,7 @@ ${line}
10584
10659
  }
10585
10660
  }
10586
10661
  if (!patchedExisting) {
10587
- await writeFile5(path12.join(resolved, ".env"), `${line}
10662
+ await writeFile5(path13.join(resolved, ".env"), `${line}
10588
10663
  `);
10589
10664
  }
10590
10665
  }
@@ -10592,7 +10667,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
10592
10667
  return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
10593
10668
  }
10594
10669
  async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
10595
- const sourceDirectory = path12.resolve(args.sourceDirectory);
10670
+ const sourceDirectory = path13.resolve(args.sourceDirectory);
10596
10671
  const explicit = args.apiBaseUrl?.trim();
10597
10672
  if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
10598
10673
  await patchSiteApiBaseUrl(sourceDirectory, explicit);
@@ -10628,7 +10703,7 @@ async function* walkFiles(root) {
10628
10703
  return;
10629
10704
  }
10630
10705
  for (const entry of entries) {
10631
- const full = path12.join(root, entry.name);
10706
+ const full = path13.join(root, entry.name);
10632
10707
  if (entry.isDirectory()) {
10633
10708
  if (entry.name === "node_modules" || entry.name === ".git") {
10634
10709
  continue;
@@ -10640,8 +10715,8 @@ async function* walkFiles(root) {
10640
10715
  }
10641
10716
  }
10642
10717
  async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
10643
- const dist = path12.resolve(distDirectory);
10644
- const siteRoot = path12.dirname(dist);
10718
+ const dist = path13.resolve(distDirectory);
10719
+ const siteRoot = path13.dirname(dist);
10645
10720
  const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
10646
10721
  if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
10647
10722
  throw new Error(
@@ -10896,8 +10971,8 @@ function validateDeployArchiveInput(args) {
10896
10971
  async function resolveDevPortalArchive(args) {
10897
10972
  validateDeployArchiveInput(args);
10898
10973
  if (args.archivePath?.trim()) {
10899
- const archivePath = path13.resolve(args.archivePath.trim());
10900
- const stat4 = await fs6.stat(archivePath).catch(() => null);
10974
+ const archivePath = path14.resolve(args.archivePath.trim());
10975
+ const stat4 = await fs7.stat(archivePath).catch(() => null);
10901
10976
  if (!stat4?.isFile()) {
10902
10977
  throw new Error(`archivePath is not a file: ${archivePath}`);
10903
10978
  }
@@ -10964,12 +11039,12 @@ async function handleDeployDevPortal(client, config2, args, progress) {
10964
11039
  }
10965
11040
 
10966
11041
  // src/cli/platform/tools/dev-portal-site-build.ts
10967
- import path15 from "node:path";
11042
+ import path16 from "node:path";
10968
11043
 
10969
11044
  // src/cli/platform/helpers/npm-build.ts
10970
11045
  import { spawn as spawn2 } from "node:child_process";
10971
11046
  import { access as access3, readFile as readFile7 } from "node:fs/promises";
10972
- import path14 from "node:path";
11047
+ import path15 from "node:path";
10973
11048
  var BUILD_LOG_TAIL_BYTES = 8192;
10974
11049
  var MIN_NODE_MAJOR = 20;
10975
11050
  var NpmBuildError = class extends Error {
@@ -11034,13 +11109,13 @@ function runCommand(command, args, cwd, env) {
11034
11109
  }
11035
11110
  async function runNpmInstall(sourceDirectory, options) {
11036
11111
  assertNodeVersion(options?.nodeVersion);
11037
- const cwd = path14.resolve(sourceDirectory);
11038
- const packageJsonPath = path14.join(cwd, "package.json");
11112
+ const cwd = path15.resolve(sourceDirectory);
11113
+ const packageJsonPath = path15.join(cwd, "package.json");
11039
11114
  if (!await pathExists2(packageJsonPath)) {
11040
11115
  throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
11041
11116
  }
11042
11117
  const startedAt = Date.now();
11043
- const lockPath = path14.join(cwd, "package-lock.json");
11118
+ const lockPath = path15.join(cwd, "package-lock.json");
11044
11119
  const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
11045
11120
  const install = await runCommand("npm", installArgs, cwd);
11046
11121
  const installLog = install.output;
@@ -11058,8 +11133,8 @@ async function runNpmInstall(sourceDirectory, options) {
11058
11133
  }
11059
11134
  async function runNpmBuild(sourceDirectory, options) {
11060
11135
  assertNodeVersion(options?.nodeVersion);
11061
- const cwd = path14.resolve(sourceDirectory);
11062
- const packageJsonPath = path14.join(cwd, "package.json");
11136
+ const cwd = path15.resolve(sourceDirectory);
11137
+ const packageJsonPath = path15.join(cwd, "package.json");
11063
11138
  if (!await pathExists2(packageJsonPath)) {
11064
11139
  throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
11065
11140
  }
@@ -11076,8 +11151,8 @@ async function runNpmBuild(sourceDirectory, options) {
11076
11151
  build2.exitCode
11077
11152
  );
11078
11153
  }
11079
- const distPath = path14.join(cwd, "dist");
11080
- const indexPath = path14.join(distPath, "index.html");
11154
+ const distPath = path15.join(cwd, "dist");
11155
+ const indexPath = path15.join(distPath, "index.html");
11081
11156
  if (!await pathExists2(indexPath)) {
11082
11157
  throw new NpmBuildError(
11083
11158
  `Build completed but dist/index.html was not found at ${indexPath}`,
@@ -11095,7 +11170,7 @@ async function runNpmBuild(sourceDirectory, options) {
11095
11170
  // src/cli/platform/tools/dev-portal-site-build.ts
11096
11171
  async function handleBuildDevPortalSite(client, config2, args, progress) {
11097
11172
  const buildProgress = progress?.child("Build dev portal site");
11098
- const sourceDirectory = path15.resolve(args.sourceDirectory);
11173
+ const sourceDirectory = path16.resolve(args.sourceDirectory);
11099
11174
  await buildProgress?.onStep("Ensuring live portal API URL");
11100
11175
  const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
11101
11176
  client,
@@ -11175,10 +11250,10 @@ async function handleBuildDevPortalSite(client, config2, args, progress) {
11175
11250
  // src/cli/platform/helpers/dev-portal-site-validation.ts
11176
11251
  import { readFile as readFile8 } from "node:fs/promises";
11177
11252
  import { createRequire } from "node:module";
11178
- import path16 from "node:path";
11253
+ import path17 from "node:path";
11179
11254
  var cachedFallbackTs;
11180
11255
  async function loadTypeScriptForSite(sourceDirectory) {
11181
- const require2 = createRequire(path16.join(path16.resolve(sourceDirectory), "package.json"));
11256
+ const require2 = createRequire(path17.join(path17.resolve(sourceDirectory), "package.json"));
11182
11257
  try {
11183
11258
  return require2("typescript");
11184
11259
  } catch {
@@ -11222,7 +11297,7 @@ async function referencedFileExists(sourceDirectory, reference) {
11222
11297
  if (/^https?:\/\//i.test(reference)) {
11223
11298
  return true;
11224
11299
  }
11225
- return pathExists(path16.resolve(sourceDirectory, reference.replace(/^\.\//, "")));
11300
+ return pathExists(path17.resolve(sourceDirectory, reference.replace(/^\.\//, "")));
11226
11301
  }
11227
11302
  async function validateSiteConfigStructure(config2, sourceDirectory) {
11228
11303
  const errors = [];
@@ -11323,11 +11398,11 @@ var DEFAULT_TSX_CANDIDATES = [
11323
11398
  "landing/LandingPage.tsx"
11324
11399
  ];
11325
11400
  async function validateDevPortalSiteConfig(sourceDirectory, options) {
11326
- const resolvedDir = path16.resolve(sourceDirectory);
11401
+ const resolvedDir = path17.resolve(sourceDirectory);
11327
11402
  const issues = [];
11328
11403
  const checkedFiles = [];
11329
11404
  const skippedChecks = [];
11330
- const jsonPath = path16.join(resolvedDir, APITOGO_CONFIG_FILENAME);
11405
+ const jsonPath = path17.join(resolvedDir, APITOGO_CONFIG_FILENAME);
11331
11406
  if (await pathExists(jsonPath)) {
11332
11407
  checkedFiles.push(APITOGO_CONFIG_FILENAME);
11333
11408
  let parsed;
@@ -11356,7 +11431,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
11356
11431
  );
11357
11432
  const existingTsxFiles = [];
11358
11433
  for (const relativeFile of tsxFiles) {
11359
- if (await pathExists(path16.join(resolvedDir, relativeFile))) {
11434
+ if (await pathExists(path17.join(resolvedDir, relativeFile))) {
11360
11435
  existingTsxFiles.push(relativeFile);
11361
11436
  }
11362
11437
  }
@@ -11369,7 +11444,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
11369
11444
  } else {
11370
11445
  for (const relativeFile of existingTsxFiles) {
11371
11446
  checkedFiles.push(relativeFile);
11372
- const content = await readFile8(path16.join(resolvedDir, relativeFile), "utf8");
11447
+ const content = await readFile8(path17.join(resolvedDir, relativeFile), "utf8");
11373
11448
  issues.push(
11374
11449
  ...checkTsxSyntax(ts, relativeFile, content).map((message) => ({
11375
11450
  file: relativeFile,
@@ -11407,8 +11482,8 @@ function normalizeActionKeyFormat(actionKey) {
11407
11482
  const trimmed = actionKey.trim();
11408
11483
  if (trimmed.includes(":")) {
11409
11484
  const [method2, ...pathParts] = trimmed.split(":");
11410
- const path68 = pathParts.join(":").trim();
11411
- return `${method2.toLowerCase()}:${path68.startsWith("/") ? path68 : `/${path68}`}`;
11485
+ const path71 = pathParts.join(":").trim();
11486
+ return `${method2.toLowerCase()}:${path71.startsWith("/") ? path71 : `/${path71}`}`;
11412
11487
  }
11413
11488
  const spaceIndex = trimmed.indexOf(" ");
11414
11489
  if (spaceIndex <= 0) {
@@ -11417,8 +11492,8 @@ function normalizeActionKeyFormat(actionKey) {
11417
11492
  );
11418
11493
  }
11419
11494
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
11420
- const path67 = trimmed.slice(spaceIndex + 1).trim();
11421
- return `${method}:${path67.startsWith("/") ? path67 : `/${path67}`}`;
11495
+ const path70 = trimmed.slice(spaceIndex + 1).trim();
11496
+ return `${method}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
11422
11497
  }
11423
11498
  function normalizePublicRoute(route) {
11424
11499
  const trimmed = route.trim();
@@ -12299,7 +12374,7 @@ function resultLooksFailed(payload) {
12299
12374
  }
12300
12375
  }
12301
12376
  async function apply(argv) {
12302
- const sourceDirectory = path17.resolve(process.cwd(), argv.dir);
12377
+ const sourceDirectory = path18.resolve(process.cwd(), argv.dir);
12303
12378
  const config2 = loadConfig();
12304
12379
  const client = new PlatformApiClient(config2);
12305
12380
  let only;
@@ -12384,11 +12459,11 @@ var apply_default = {
12384
12459
  };
12385
12460
 
12386
12461
  // src/cli/build/handler.ts
12387
- import path48 from "node:path";
12462
+ import path50 from "node:path";
12388
12463
 
12389
12464
  // src/vite/build.ts
12390
12465
  import { mkdir as mkdir9, readFile as readFile11, rename, rm as rm3, writeFile as writeFile10 } from "node:fs/promises";
12391
- import path46 from "node:path";
12466
+ import path48 from "node:path";
12392
12467
  import { build as esbuild } from "esbuild";
12393
12468
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
12394
12469
 
@@ -12524,7 +12599,7 @@ init_invariant();
12524
12599
  init_joinUrl();
12525
12600
 
12526
12601
  // src/vite/config.ts
12527
- import path41 from "node:path";
12602
+ import path43 from "node:path";
12528
12603
  import dotenv from "dotenv";
12529
12604
  import colors5 from "picocolors";
12530
12605
  import {
@@ -12535,7 +12610,7 @@ import {
12535
12610
  // package.json
12536
12611
  var package_default = {
12537
12612
  name: "@lukoweb/apitogo",
12538
- version: "0.1.95",
12613
+ version: "0.1.97",
12539
12614
  type: "module",
12540
12615
  sideEffects: [
12541
12616
  "**/*.css",
@@ -12965,25 +13040,25 @@ async function loadDevPortalViteDefines(rootDir, mode) {
12965
13040
 
12966
13041
  // src/vite/package-root.ts
12967
13042
  init_file_exists();
12968
- import path23 from "node:path";
13043
+ import path24 from "node:path";
12969
13044
  var findPackageRoot = async (startDir) => {
12970
13045
  let dir = startDir;
12971
- while (dir !== path23.dirname(dir)) {
12972
- if (await fileExists(path23.join(dir, "package.json"))) return dir;
12973
- dir = path23.dirname(dir);
13046
+ while (dir !== path24.dirname(dir)) {
13047
+ if (await fileExists(path24.join(dir, "package.json"))) return dir;
13048
+ dir = path24.dirname(dir);
12974
13049
  }
12975
13050
  };
12976
13051
 
12977
13052
  // src/vite/pagefind-dev-stub.ts
12978
- import fs7 from "node:fs/promises";
12979
- import path24 from "node:path";
13053
+ import fs8 from "node:fs/promises";
13054
+ import path25 from "node:path";
12980
13055
  var NOT_BUILT_YET = 'throw new Error("NOT_BUILT_YET");';
12981
13056
  async function ensurePagefindDevStub(publicDir) {
12982
- const pagefindPath = path24.join(publicDir, "pagefind/pagefind.js");
12983
- const exists = await fs7.stat(pagefindPath).catch(() => false);
13057
+ const pagefindPath = path25.join(publicDir, "pagefind/pagefind.js");
13058
+ const exists = await fs8.stat(pagefindPath).catch(() => false);
12984
13059
  if (!exists) {
12985
- await fs7.mkdir(path24.dirname(pagefindPath), { recursive: true });
12986
- await fs7.writeFile(pagefindPath, NOT_BUILT_YET);
13060
+ await fs8.mkdir(path25.dirname(pagefindPath), { recursive: true });
13061
+ await fs8.writeFile(pagefindPath, NOT_BUILT_YET);
12987
13062
  }
12988
13063
  }
12989
13064
 
@@ -12994,7 +13069,7 @@ import react from "@vitejs/plugin-react";
12994
13069
  // src/vite/css/plugin.ts
12995
13070
  init_loader();
12996
13071
  init_plugin_theme();
12997
- import path25 from "node:path";
13072
+ import path26 from "node:path";
12998
13073
  import { isCSSRequest as isCSSRequest2 } from "vite";
12999
13074
 
13000
13075
  // src/vite/css/collect.ts
@@ -13029,7 +13104,7 @@ var VIRTUAL_ENTRY = "virtual:ssr-css.css";
13029
13104
  function vitePluginSsrCss(pluginOpts) {
13030
13105
  let server;
13031
13106
  const config2 = getCurrentConfig();
13032
- const virtualHref = path25.join(
13107
+ const virtualHref = path26.join(
13033
13108
  config2.basePath ?? "",
13034
13109
  `/@id/__x00__${VIRTUAL_ENTRY}?direct`
13035
13110
  );
@@ -13165,8 +13240,8 @@ var viteApiKeysPlugin = () => {
13165
13240
  var plugin_api_keys_default = viteApiKeysPlugin;
13166
13241
 
13167
13242
  // src/vite/plugin-api.ts
13168
- import fs9 from "node:fs/promises";
13169
- import path31 from "node:path";
13243
+ import fs10 from "node:fs/promises";
13244
+ import path32 from "node:path";
13170
13245
  import { deepEqual as deepEqual2 } from "fast-equals";
13171
13246
  import { runnerImport as runnerImport3 } from "vite";
13172
13247
  init_package_json();
@@ -13175,7 +13250,7 @@ init_loader();
13175
13250
  // src/config/validators/BuildSchema.ts
13176
13251
  init_file_exists();
13177
13252
  init_loader();
13178
- import path26 from "node:path";
13253
+ import path27 from "node:path";
13179
13254
  import { runnerImport as runnerImport2 } from "vite";
13180
13255
  import { z as z10 } from "zod";
13181
13256
  var BuildProcessorSchema = z10.custom((val) => typeof val === "function");
@@ -13204,7 +13279,7 @@ var buildConfigFiles = [
13204
13279
  ];
13205
13280
  async function getBuildConfigFilePath(rootDir) {
13206
13281
  for (const fileName of buildConfigFiles) {
13207
- const filepath = path26.join(rootDir, fileName);
13282
+ const filepath = path27.join(rootDir, fileName);
13208
13283
  if (await fileExists(filepath)) {
13209
13284
  return filepath;
13210
13285
  }
@@ -13313,14 +13388,14 @@ var flattenAllOf = (schema2) => {
13313
13388
  };
13314
13389
 
13315
13390
  // src/lib/util/traverse.ts
13316
- var traverse = (specification, transform, path67 = []) => {
13317
- const transformed = transform(specification, path67);
13391
+ var traverse = (specification, transform, path70 = []) => {
13392
+ const transformed = transform(specification, path70);
13318
13393
  if (typeof transformed !== "object" || transformed === null) {
13319
13394
  return transformed;
13320
13395
  }
13321
13396
  const result = Array.isArray(transformed) ? [] : {};
13322
13397
  for (const [key, value] of Object.entries(transformed)) {
13323
- const currentPath = [...path67, key];
13398
+ const currentPath = [...path70, key];
13324
13399
  if (Array.isArray(value)) {
13325
13400
  result[key] = value.map(
13326
13401
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -13348,9 +13423,9 @@ var resolveLocalRef = (schema2, ref) => {
13348
13423
  if (schemaCache?.has(ref)) {
13349
13424
  return schemaCache.get(ref);
13350
13425
  }
13351
- const path67 = ref.split("/").slice(1);
13426
+ const path70 = ref.split("/").slice(1);
13352
13427
  let current = schema2;
13353
- for (const segment of path67) {
13428
+ for (const segment of path70) {
13354
13429
  if (!current || typeof current !== "object") {
13355
13430
  current = null;
13356
13431
  }
@@ -13369,7 +13444,7 @@ var dereference = async (schema2, resolvers = []) => {
13369
13444
  }
13370
13445
  const cloned = structuredClone(schema2);
13371
13446
  const visited = /* @__PURE__ */ new Set();
13372
- const resolve = async (current, path67) => {
13447
+ const resolve = async (current, path70) => {
13373
13448
  if (isIndexableObject(current)) {
13374
13449
  if (visited.has(current)) {
13375
13450
  return CIRCULAR_REF;
@@ -13377,7 +13452,7 @@ var dereference = async (schema2, resolvers = []) => {
13377
13452
  visited.add(current);
13378
13453
  if (Array.isArray(current)) {
13379
13454
  for (let index = 0; index < current.length; index++) {
13380
- current[index] = await resolve(current[index], `${path67}/${index}`);
13455
+ current[index] = await resolve(current[index], `${path70}/${index}`);
13381
13456
  }
13382
13457
  } else {
13383
13458
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -13388,13 +13463,13 @@ var dereference = async (schema2, resolvers = []) => {
13388
13463
  for (const resolver of resolvers) {
13389
13464
  const resolved = await resolver($ref);
13390
13465
  if (resolved) {
13391
- result2 = await resolve(resolved, path67);
13466
+ result2 = await resolve(resolved, path70);
13392
13467
  break;
13393
13468
  }
13394
13469
  }
13395
13470
  if (result2 === void 0) {
13396
13471
  const resolved = await resolveLocalRef(cloned, $ref);
13397
- result2 = await resolve(resolved, path67);
13472
+ result2 = await resolve(resolved, path70);
13398
13473
  }
13399
13474
  if (hasSiblings) {
13400
13475
  if (result2 === CIRCULAR_REF) {
@@ -13407,7 +13482,7 @@ var dereference = async (schema2, resolvers = []) => {
13407
13482
  return result2;
13408
13483
  }
13409
13484
  for (const key in current) {
13410
- current[key] = await resolve(current[key], `${path67}/${key}`);
13485
+ current[key] = await resolve(current[key], `${path70}/${key}`);
13411
13486
  }
13412
13487
  }
13413
13488
  visited.delete(current);
@@ -13446,9 +13521,9 @@ var upgradeSchema = (schema2) => {
13446
13521
  }
13447
13522
  return sub;
13448
13523
  });
13449
- schema2 = traverse(schema2, (sub, path67) => {
13524
+ schema2 = traverse(schema2, (sub, path70) => {
13450
13525
  if (sub.example !== void 0) {
13451
- if (isSchemaPath(path67 ?? [])) {
13526
+ if (isSchemaPath(path70 ?? [])) {
13452
13527
  sub.examples = [sub.example];
13453
13528
  } else {
13454
13529
  sub.examples = {
@@ -13461,11 +13536,11 @@ var upgradeSchema = (schema2) => {
13461
13536
  }
13462
13537
  return sub;
13463
13538
  });
13464
- schema2 = traverse(schema2, (schema3, path67) => {
13539
+ schema2 = traverse(schema2, (schema3, path70) => {
13465
13540
  if (schema3.type === "object" && schema3.properties !== void 0) {
13466
- const parentPath = path67?.slice(0, -1);
13541
+ const parentPath = path70?.slice(0, -1);
13467
13542
  const isMultipart = parentPath?.some((segment, index) => {
13468
- return segment === "content" && path67?.[index + 1] === "multipart/form-data";
13543
+ return segment === "content" && path70?.[index + 1] === "multipart/form-data";
13469
13544
  });
13470
13545
  if (isMultipart) {
13471
13546
  const entries = Object.entries(schema3.properties);
@@ -13479,8 +13554,8 @@ var upgradeSchema = (schema2) => {
13479
13554
  }
13480
13555
  return schema3;
13481
13556
  });
13482
- schema2 = traverse(schema2, (schema3, path67) => {
13483
- if (path67?.includes("content") && path67.includes("application/octet-stream")) {
13557
+ schema2 = traverse(schema2, (schema3, path70) => {
13558
+ if (path70?.includes("content") && path70.includes("application/octet-stream")) {
13484
13559
  return {};
13485
13560
  }
13486
13561
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -13506,11 +13581,11 @@ var upgradeSchema = (schema2) => {
13506
13581
  }
13507
13582
  return sub;
13508
13583
  });
13509
- schema2 = traverse(schema2, (schema3, path67) => {
13584
+ schema2 = traverse(schema2, (schema3, path70) => {
13510
13585
  if (schema3.type === "string" && schema3.format === "byte") {
13511
- const parentPath = path67?.slice(0, -1);
13586
+ const parentPath = path70?.slice(0, -1);
13512
13587
  const contentMediaType = parentPath?.find(
13513
- (_, index) => path67?.[index - 1] === "content"
13588
+ (_, index) => path70?.[index - 1] === "content"
13514
13589
  );
13515
13590
  return {
13516
13591
  type: "string",
@@ -13522,7 +13597,7 @@ var upgradeSchema = (schema2) => {
13522
13597
  });
13523
13598
  return schema2;
13524
13599
  };
13525
- function isSchemaPath(path67) {
13600
+ function isSchemaPath(path70) {
13526
13601
  const schemaLocations = [
13527
13602
  ["components", "schemas"],
13528
13603
  "properties",
@@ -13535,10 +13610,10 @@ function isSchemaPath(path67) {
13535
13610
  ];
13536
13611
  return schemaLocations.some((location) => {
13537
13612
  if (Array.isArray(location)) {
13538
- return location.every((segment, index) => path67[index] === segment);
13613
+ return location.every((segment, index) => path70[index] === segment);
13539
13614
  }
13540
- return path67.includes(location);
13541
- }) || path67.includes("schema") || path67.some((segment) => segment.endsWith("Schema"));
13615
+ return path70.includes(location);
13616
+ }) || path70.includes("schema") || path70.some((segment) => segment.endsWith("Schema"));
13542
13617
  }
13543
13618
 
13544
13619
  // src/lib/oas/parser/index.ts
@@ -13620,13 +13695,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
13620
13695
  "anyOf",
13621
13696
  "oneOf"
13622
13697
  ]);
13623
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path67 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
13698
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path70 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
13624
13699
  if (obj === null || typeof obj !== "object") return obj;
13625
13700
  const refPath = obj.__$ref;
13626
13701
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
13627
13702
  if (isCircular) {
13628
13703
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
13629
- const circularProp = path67.find((p) => !OPENAPI_PROPS.has(p)) || path67[0];
13704
+ const circularProp = path70.find((p) => !OPENAPI_PROPS.has(p)) || path70[0];
13630
13705
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
13631
13706
  }
13632
13707
  if (refs.has(obj)) return refs.get(obj);
@@ -13636,7 +13711,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
13636
13711
  value,
13637
13712
  currentPath,
13638
13713
  refs,
13639
- [...path67, key],
13714
+ [...path70, key],
13640
13715
  currentRefPaths
13641
13716
  );
13642
13717
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -13671,7 +13746,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
13671
13746
  var getAllTags = (schema2) => {
13672
13747
  const rootTags = schema2.tags ?? [];
13673
13748
  const operations = Object.values(schema2.paths ?? {}).flatMap(
13674
- (path67) => HttpMethods.map((k) => path67?.[k]).filter((op) => op != null)
13749
+ (path70) => HttpMethods.map((k) => path70?.[k]).filter((op) => op != null)
13675
13750
  );
13676
13751
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
13677
13752
  const hasUntaggedOperations = operations.some(
@@ -13726,7 +13801,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
13726
13801
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
13727
13802
  var getAllOperations = (paths) => {
13728
13803
  const operations = Object.entries(paths ?? {}).flatMap(
13729
- ([path67, value]) => HttpMethods.flatMap((method) => {
13804
+ ([path70, value]) => HttpMethods.flatMap((method) => {
13730
13805
  if (!value?.[method]) return [];
13731
13806
  const operation = value[method];
13732
13807
  const pathParameters = value.parameters ?? [];
@@ -13746,7 +13821,7 @@ var getAllOperations = (paths) => {
13746
13821
  return {
13747
13822
  ...operation,
13748
13823
  method,
13749
- path: path67,
13824
+ path: path70,
13750
13825
  parameters,
13751
13826
  servers,
13752
13827
  tags: operation.tags ?? []
@@ -14104,8 +14179,8 @@ var Schema = builder.objectRef("Schema").implement({
14104
14179
  }),
14105
14180
  paths: t.field({
14106
14181
  type: [PathItem],
14107
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path67, value]) => ({
14108
- path: path67,
14182
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path70, value]) => ({
14183
+ path: path70,
14109
14184
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
14110
14185
  methods: Object.keys(value)
14111
14186
  }))
@@ -14217,8 +14292,8 @@ function injectApitogoGatewayServer(options) {
14217
14292
  var ensureArray = (value) => Array.isArray(value) ? value : [value];
14218
14293
 
14219
14294
  // src/vite/api/SchemaManager.ts
14220
- import fs8 from "node:fs/promises";
14221
- import path27 from "node:path";
14295
+ import fs9 from "node:fs/promises";
14296
+ import path28 from "node:path";
14222
14297
  import {
14223
14298
  $RefParser as $RefParser2
14224
14299
  } from "@apidevtools/json-schema-ref-parser";
@@ -14270,7 +14345,7 @@ init_joinUrl();
14270
14345
 
14271
14346
  // src/vite/api/schema-codegen.ts
14272
14347
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
14273
- var getSegmentsFromPath = (path67) => path67.split("/").slice(1).map(unescapeJsonPointer);
14348
+ var getSegmentsFromPath = (path70) => path70.split("/").slice(1).map(unescapeJsonPointer);
14274
14349
  var createLocalRefMap = (obj) => {
14275
14350
  const refMap = /* @__PURE__ */ new Map();
14276
14351
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -14301,16 +14376,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
14301
14376
  /"__refMap\+Siblings:(.*?)"/g,
14302
14377
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
14303
14378
  );
14304
- var lookup2 = (schema2, path67, filePath) => {
14305
- const parts = getSegmentsFromPath(path67);
14379
+ var lookup2 = (schema2, path70, filePath) => {
14380
+ const parts = getSegmentsFromPath(path70);
14306
14381
  let val = schema2;
14307
14382
  for (const part of parts) {
14308
14383
  while (val.$ref?.startsWith("#/")) {
14309
- val = val.$ref === path67 ? val : lookup2(schema2, val.$ref, filePath);
14384
+ val = val.$ref === path70 ? val : lookup2(schema2, val.$ref, filePath);
14310
14385
  }
14311
14386
  if (val[part] === void 0) {
14312
14387
  throw new Error(
14313
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path67}`
14388
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path70}`
14314
14389
  );
14315
14390
  }
14316
14391
  val = val[part];
@@ -14408,18 +14483,18 @@ var SchemaManager = class {
14408
14483
  ];
14409
14484
  }
14410
14485
  getPathForFile = (input3, params) => {
14411
- const filePath = path27.resolve(this.config.__meta.rootDir, input3);
14486
+ const filePath = path28.resolve(this.config.__meta.rootDir, input3);
14412
14487
  const apis = ensureArray(this.config.apis ?? []);
14413
14488
  for (const apiConfig of apis) {
14414
14489
  if (!apiConfig || apiConfig.type !== "file" || !apiConfig.path) continue;
14415
14490
  const match = normalizeInputs(apiConfig.input).some(
14416
- (i) => path27.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
14491
+ (i) => path28.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
14417
14492
  );
14418
14493
  if (match) return apiConfig.path;
14419
14494
  }
14420
14495
  };
14421
14496
  processSchema = async (input3) => {
14422
- const filePath = path27.resolve(this.config.__meta.rootDir, input3.input);
14497
+ const filePath = path28.resolve(this.config.__meta.rootDir, input3.input);
14423
14498
  const params = input3.params;
14424
14499
  const configuredPath = this.getPathForFile(input3.input, params);
14425
14500
  if (!configuredPath) {
@@ -14455,15 +14530,15 @@ var SchemaManager = class {
14455
14530
  const processedTime = Date.now();
14456
14531
  const code = generateCode(processedSchema, filePath);
14457
14532
  const prefixPath = slugify(configuredPath);
14458
- const processedFilePath = path27.posix.join(
14533
+ const processedFilePath = path28.posix.join(
14459
14534
  this.storeDir,
14460
- `${prefixPath}-${path27.basename(filePath)}${paramsSuffix(params)}.js`
14535
+ `${prefixPath}-${path28.basename(filePath)}${paramsSuffix(params)}.js`
14461
14536
  );
14462
14537
  const importKey = processedFilePath;
14463
- await fs8.writeFile(processedFilePath, code);
14538
+ await fs9.writeFile(processedFilePath, code);
14464
14539
  const processedJsonPath = paramsSuffix(params) ? processedFilePath.replace(/\.js$/, ".json") : "";
14465
14540
  if (processedJsonPath) {
14466
- await fs8.writeFile(
14541
+ await fs9.writeFile(
14467
14542
  processedJsonPath,
14468
14543
  JSON.stringify(processedSchema, null, 2)
14469
14544
  );
@@ -14506,7 +14581,7 @@ var SchemaManager = class {
14506
14581
  };
14507
14582
  getAllTrackedFiles = () => Array.from(this.referencedBy.keys());
14508
14583
  getFilesToReprocess = (changedFile) => {
14509
- const resolvedPath = path27.resolve(this.config.__meta.rootDir, changedFile);
14584
+ const resolvedPath = path28.resolve(this.config.__meta.rootDir, changedFile);
14510
14585
  const referencedBy = this.referencedBy.get(resolvedPath);
14511
14586
  if (!referencedBy) return [];
14512
14587
  const filesToProcess = referencedBy.size === 0 ? [resolvedPath] : Array.from(referencedBy);
@@ -14535,7 +14610,7 @@ var SchemaManager = class {
14535
14610
  version: "",
14536
14611
  path: input3.path ?? "",
14537
14612
  label: input3.label,
14538
- inputPath: path27.resolve(this.config.__meta.rootDir, input3.input),
14613
+ inputPath: path28.resolve(this.config.__meta.rootDir, input3.input),
14539
14614
  params: input3.params,
14540
14615
  importKey: "",
14541
14616
  downloadUrl: "",
@@ -14555,8 +14630,8 @@ var SchemaManager = class {
14555
14630
  }
14556
14631
  }
14557
14632
  };
14558
- getLatestSchema = (path67) => this.processedSchemas[path67]?.at(0);
14559
- getSchemasForPath = (path67) => this.processedSchemas[path67];
14633
+ getLatestSchema = (path70) => this.processedSchemas[path70]?.at(0);
14634
+ getSchemasForPath = (path70) => this.processedSchemas[path70];
14560
14635
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
14561
14636
  getUrlToFilePathMap = () => {
14562
14637
  const map = /* @__PURE__ */ new Map();
@@ -14578,7 +14653,7 @@ var SchemaManager = class {
14578
14653
  };
14579
14654
  createSchemaPath = (inputPath, versionPath, apiPath, params) => {
14580
14655
  const suffix = paramsSuffix(params);
14581
- const extension = suffix ? ".json" : path27.extname(inputPath);
14656
+ const extension = suffix ? ".json" : path28.extname(inputPath);
14582
14657
  return joinUrl(
14583
14658
  this.config.basePath,
14584
14659
  apiPath,
@@ -14601,7 +14676,7 @@ var SchemaManager = class {
14601
14676
  // src/vite/plugin-config-reload.ts
14602
14677
  init_logger();
14603
14678
  init_loader();
14604
- import path30 from "node:path";
14679
+ import path31 from "node:path";
14605
14680
  import colors4 from "picocolors";
14606
14681
 
14607
14682
  // src/vite/plugin-navigation.ts
@@ -14611,7 +14686,7 @@ import { stringify as stringify3 } from "javascript-stringify";
14611
14686
  import { isElement } from "react-is";
14612
14687
 
14613
14688
  // src/config/validators/NavigationSchema.ts
14614
- import path28 from "node:path";
14689
+ import path29 from "node:path";
14615
14690
  import { glob } from "glob";
14616
14691
  import { fromMarkdown } from "mdast-util-from-markdown";
14617
14692
  import { mdxFromMarkdown } from "mdast-util-mdx";
@@ -14662,7 +14737,7 @@ var extractRichH1 = (content) => {
14662
14737
  }
14663
14738
  };
14664
14739
  var isNavigationItem = (item) => item !== void 0;
14665
- var toPosixPath = (filePath) => filePath.split(path28.win32.sep).join(path28.posix.sep);
14740
+ var toPosixPath = (filePath) => filePath.split(path29.win32.sep).join(path29.posix.sep);
14666
14741
  var NavigationResolver = class {
14667
14742
  rootDir;
14668
14743
  globPatterns;
@@ -14795,13 +14870,13 @@ init_invariant();
14795
14870
 
14796
14871
  // src/vite/debug.ts
14797
14872
  import { mkdir as mkdir5, writeFile as writeFile6 } from "node:fs/promises";
14798
- import path29 from "node:path";
14873
+ import path30 from "node:path";
14799
14874
  async function writePluginDebugCode(rootDir, pluginName, code, extension = "js") {
14800
14875
  if (process.env.ZUDOKU_BUILD_DEBUG) {
14801
- const debugDir = path29.join(rootDir, "dist", "debug");
14876
+ const debugDir = path30.join(rootDir, "dist", "debug");
14802
14877
  await mkdir5(debugDir, { recursive: true });
14803
14878
  await writeFile6(
14804
- path29.join(debugDir, `${pluginName}.${extension}`),
14879
+ path30.join(debugDir, `${pluginName}.${extension}`),
14805
14880
  typeof code === "string" ? code : code.join("\n")
14806
14881
  );
14807
14882
  }
@@ -14910,7 +14985,7 @@ var viteConfigReloadPlugin = () => ({
14910
14985
  reload(server);
14911
14986
  logger.info(
14912
14987
  colors4.blue(
14913
- `Config ${path30.basename(currentConfig.__meta.configPath)} changed. Reloading...`
14988
+ `Config ${path31.basename(currentConfig.__meta.configPath)} changed. Reloading...`
14914
14989
  ),
14915
14990
  { timestamp: true }
14916
14991
  );
@@ -14924,11 +14999,11 @@ var viteApiPlugin = async () => {
14924
14999
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
14925
15000
  const initialConfig = getCurrentConfig();
14926
15001
  const zuploProcessors = ZuploEnv.isZuplo ? await runnerImport3(
14927
- path31.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
15002
+ path32.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
14928
15003
  ).then((m) => m.module.default(initialConfig.__meta.rootDir)) : [];
14929
15004
  const buildConfig = await getBuildConfig();
14930
15005
  const buildProcessors = buildConfig?.processors ?? [];
14931
- const tmpStoreDir = path31.posix.join(
15006
+ const tmpStoreDir = path32.posix.join(
14932
15007
  initialConfig.__meta.rootDir,
14933
15008
  "node_modules/.apitogo/processed"
14934
15009
  );
@@ -14945,8 +15020,8 @@ var viteApiPlugin = async () => {
14945
15020
  return {
14946
15021
  name: "zudoku-api-plugins",
14947
15022
  async buildStart() {
14948
- await fs9.rm(tmpStoreDir, { recursive: true, force: true });
14949
- await fs9.mkdir(tmpStoreDir, { recursive: true });
15023
+ await fs10.rm(tmpStoreDir, { recursive: true, force: true });
15024
+ await fs10.mkdir(tmpStoreDir, { recursive: true });
14950
15025
  await schemaManager.processAllSchemas();
14951
15026
  schemaManager.getAllTrackedFiles().forEach((file) => this.addWatchFile(file));
14952
15027
  },
@@ -14959,8 +15034,8 @@ var viteApiPlugin = async () => {
14959
15034
  const pathMap = schemaManager.getUrlToFilePathMap();
14960
15035
  const inputPath = pathMap.get(req.url);
14961
15036
  if (!inputPath) return next();
14962
- const content = await fs9.readFile(inputPath, "utf-8");
14963
- const mimeType = path31.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
15037
+ const content = await fs10.readFile(inputPath, "utf-8");
15038
+ const mimeType = path32.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
14964
15039
  res.setHeader("Content-Type", `${mimeType}; charset=utf-8`);
14965
15040
  return res.end(content);
14966
15041
  });
@@ -15147,10 +15222,10 @@ var viteApiPlugin = async () => {
15147
15222
  const pathMap = schemaManager.getUrlToFilePathMap();
15148
15223
  if (process.env.NODE_ENV !== "production") return;
15149
15224
  for (const [urlPath, inputPath] of pathMap) {
15150
- const content = await fs9.readFile(inputPath, "utf-8");
15151
- const outputPath = path31.join(config2.__meta.rootDir, "dist", urlPath);
15152
- await fs9.mkdir(path31.dirname(outputPath), { recursive: true });
15153
- await fs9.writeFile(outputPath, content, "utf-8");
15225
+ const content = await fs10.readFile(inputPath, "utf-8");
15226
+ const outputPath = path32.join(config2.__meta.rootDir, "dist", urlPath);
15227
+ await fs10.mkdir(path32.dirname(outputPath), { recursive: true });
15228
+ await fs10.writeFile(outputPath, content, "utf-8");
15154
15229
  }
15155
15230
  }
15156
15231
  };
@@ -15192,7 +15267,7 @@ var plugin_auth_default = viteAuthPlugin;
15192
15267
 
15193
15268
  // src/vite/plugin-component.ts
15194
15269
  init_loader();
15195
- import path32 from "node:path";
15270
+ import path33 from "node:path";
15196
15271
  var viteAliasPlugin = () => {
15197
15272
  return {
15198
15273
  name: "zudoku-component-plugin",
@@ -15220,7 +15295,7 @@ var viteAliasPlugin = () => {
15220
15295
  ];
15221
15296
  const aliases = replacements.map(([find, replacement]) => ({
15222
15297
  find,
15223
- replacement: path32.posix.join(config2.__meta.moduleDir, replacement)
15298
+ replacement: path33.posix.join(config2.__meta.moduleDir, replacement)
15224
15299
  }));
15225
15300
  return config2.__meta.mode === "internal" || config2.__meta.mode === "standalone" ? { resolve: { alias: aliases } } : void 0;
15226
15301
  }
@@ -15231,11 +15306,11 @@ var plugin_component_default = viteAliasPlugin;
15231
15306
  // src/vite/plugin-config.ts
15232
15307
  init_package_json();
15233
15308
  init_loader();
15234
- import path33 from "node:path";
15309
+ import path34 from "node:path";
15235
15310
  import { normalizePath } from "vite";
15236
15311
  var virtualModuleId3 = "virtual:zudoku-config";
15237
15312
  var resolvedVirtualModuleId3 = `\0${virtualModuleId3}`;
15238
- var browserConfigLoaderPath = path33.join(
15313
+ var browserConfigLoaderPath = path34.join(
15239
15314
  getZudokuRootDir(),
15240
15315
  "src/config/apitogo-config-loader.browser.ts"
15241
15316
  );
@@ -15406,7 +15481,7 @@ var viteDocMetadataPlugin = () => ({
15406
15481
 
15407
15482
  // src/vite/plugin-docs.ts
15408
15483
  init_loader();
15409
- import path34 from "node:path";
15484
+ import path35 from "node:path";
15410
15485
  import { glob as glob3 } from "glob";
15411
15486
  import globParent from "glob-parent";
15412
15487
  init_ZudokuConfig();
@@ -15475,7 +15550,7 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
15475
15550
  if (process.env.NODE_ENV !== "development") {
15476
15551
  const draftStatuses = await Promise.all(
15477
15552
  globbedFiles.map(async (file) => {
15478
- const absolutePath = path34.resolve(config2.__meta.rootDir, file);
15553
+ const absolutePath = path35.resolve(config2.__meta.rootDir, file);
15479
15554
  const { data } = await readFrontmatter(absolutePath);
15480
15555
  return { file, isDraft: data.draft === true };
15481
15556
  })
@@ -15488,9 +15563,9 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
15488
15563
  if (draftFiles.has(file)) {
15489
15564
  continue;
15490
15565
  }
15491
- const relativePath = path34.posix.relative(parent, file);
15566
+ const relativePath = path35.posix.relative(parent, file);
15492
15567
  const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
15493
- const filePath = options.absolute ? path34.resolve(config2.__meta.rootDir, file) : file;
15568
+ const filePath = options.absolute ? path35.resolve(config2.__meta.rootDir, file) : file;
15494
15569
  fileMapping[routePath] = filePath;
15495
15570
  }
15496
15571
  }
@@ -15554,7 +15629,7 @@ var viteDocsPlugin = () => {
15554
15629
  const globbedDocuments = {};
15555
15630
  for (const [routePath, file] of Object.entries(fileMapping)) {
15556
15631
  const importPath = ensureLeadingSlash(
15557
- path34.posix.join(globImportBasePath, file)
15632
+ path35.posix.join(globImportBasePath, file)
15558
15633
  );
15559
15634
  globbedDocuments[routePath] = importPath;
15560
15635
  }
@@ -15580,7 +15655,7 @@ var plugin_docs_default = viteDocsPlugin;
15580
15655
  // src/vite/plugin-local-manifest.ts
15581
15656
  init_apitogo_config_loader();
15582
15657
  init_local_manifest();
15583
- import path35 from "node:path";
15658
+ import path36 from "node:path";
15584
15659
  var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
15585
15660
  var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
15586
15661
  var viteLocalManifestPlugin = () => {
@@ -15630,8 +15705,8 @@ var viteLocalManifestPlugin = () => {
15630
15705
  server.watcher.add(watchPath);
15631
15706
  }
15632
15707
  server.watcher.on("change", async (changedPath) => {
15633
- const resolvedChanged = path35.resolve(changedPath);
15634
- if (!watchPaths.some((p) => path35.resolve(p) === resolvedChanged)) {
15708
+ const resolvedChanged = path36.resolve(changedPath);
15709
+ if (!watchPaths.some((p) => path36.resolve(p) === resolvedChanged)) {
15635
15710
  return;
15636
15711
  }
15637
15712
  const module = server.moduleGraph.getModuleById(
@@ -15658,7 +15733,7 @@ init_loader();
15658
15733
  init_ProtectedRoutesSchema();
15659
15734
  init_joinUrl();
15660
15735
  import { mkdir as mkdir6, writeFile as writeFile7 } from "node:fs/promises";
15661
- import path36 from "node:path";
15736
+ import path37 from "node:path";
15662
15737
  import { matchPath } from "react-router";
15663
15738
  var processMarkdownFile = async (filePath) => {
15664
15739
  const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
@@ -15746,7 +15821,7 @@ var viteMarkdownExportPlugin = () => {
15746
15821
  if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
15747
15822
  return;
15748
15823
  }
15749
- const distDir = path36.join(
15824
+ const distDir = path37.join(
15750
15825
  config2.__meta.rootDir,
15751
15826
  "dist",
15752
15827
  config2.basePath ?? ""
@@ -15767,15 +15842,15 @@ var viteMarkdownExportPlugin = () => {
15767
15842
  content: finalMarkdown
15768
15843
  });
15769
15844
  const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
15770
- const outputPath = `${path36.join(distDir, ...segments)}.md`;
15771
- await mkdir6(path36.dirname(outputPath), { recursive: true });
15845
+ const outputPath = `${path37.join(distDir, ...segments)}.md`;
15846
+ await mkdir6(path37.dirname(outputPath), { recursive: true });
15772
15847
  await writeFile7(outputPath, finalMarkdown, "utf-8");
15773
15848
  } catch (error) {
15774
15849
  console.warn(`Failed to export markdown for ${routePath}:`, error);
15775
15850
  }
15776
15851
  }
15777
15852
  if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
15778
- const markdownInfoPath = path36.join(
15853
+ const markdownInfoPath = path37.join(
15779
15854
  config2.__meta.rootDir,
15780
15855
  "node_modules/.apitogo/markdown-info.json"
15781
15856
  );
@@ -15927,9 +16002,9 @@ var remarkCodeTabs = () => (tree) => {
15927
16002
  };
15928
16003
 
15929
16004
  // src/vite/mdx/remark-inject-filepath.ts
15930
- import path37 from "node:path";
16005
+ import path38 from "node:path";
15931
16006
  var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
15932
- const relativePath = path37.relative(rootDir, vfile.path).split(path37.sep).join(path37.posix.sep);
16007
+ const relativePath = path38.relative(rootDir, vfile.path).split(path38.sep).join(path38.posix.sep);
15933
16008
  tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
15934
16009
  };
15935
16010
 
@@ -16016,18 +16091,18 @@ var remarkLastModified = () => {
16016
16091
  };
16017
16092
 
16018
16093
  // src/vite/mdx/remark-link-rewrite.ts
16019
- import path38 from "node:path";
16094
+ import path39 from "node:path";
16020
16095
  import { visit as visit5 } from "unist-util-visit";
16021
16096
  var remarkLinkRewrite = (basePath = "") => (tree) => {
16022
16097
  visit5(tree, "link", (node) => {
16023
16098
  if (!node.url) return;
16024
16099
  if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
16025
16100
  node.url = node.url.replace(/\\/g, "/");
16026
- const base = path38.posix.join(basePath);
16101
+ const base = path39.posix.join(basePath);
16027
16102
  if (basePath && node.url.startsWith(base)) {
16028
16103
  node.url = node.url.slice(base.length);
16029
16104
  } else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
16030
- node.url = path38.posix.join("..", node.url);
16105
+ node.url = path39.posix.join("..", node.url);
16031
16106
  }
16032
16107
  node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
16033
16108
  });
@@ -16247,14 +16322,14 @@ var plugin_mdx_default = viteMdxPlugin;
16247
16322
 
16248
16323
  // src/vite/plugin-modules.ts
16249
16324
  init_loader();
16250
- import path39 from "node:path";
16325
+ import path40 from "node:path";
16251
16326
  import { normalizePath as normalizePath2 } from "vite";
16252
- var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path39.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
16253
- var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path39.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
16327
+ var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path40.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
16328
+ var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path40.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
16254
16329
  var getBillingPluginImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
16255
- path39.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
16330
+ path40.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
16256
16331
  ) : "@lukoweb/apitogo-plugin-dev-portal-billing";
16257
- var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path39.resolve(rootDir, pagePath));
16332
+ var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path40.resolve(rootDir, pagePath));
16258
16333
  var viteModulesPlugin = () => {
16259
16334
  const virtualModuleId4 = "virtual:zudoku-modules-plugin";
16260
16335
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -16392,9 +16467,53 @@ var viteModulesPlugin = () => {
16392
16467
  };
16393
16468
  var plugin_modules_default = viteModulesPlugin;
16394
16469
 
16470
+ // src/vite/plugin-offroot-resolve.ts
16471
+ init_loader();
16472
+ import path41 from "node:path";
16473
+ function stripQuery(id) {
16474
+ const query = id.indexOf("?");
16475
+ return query === -1 ? id : id.slice(0, query);
16476
+ }
16477
+ function isInside(parent, child) {
16478
+ const relative = path41.relative(path41.resolve(parent), path41.resolve(child));
16479
+ return relative === "" || !relative.startsWith("..") && !path41.isAbsolute(relative);
16480
+ }
16481
+ function isBareSpecifier(source) {
16482
+ return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path41.isAbsolute(source);
16483
+ }
16484
+ function isInsideNodeModules(filePath) {
16485
+ return filePath.split(path41.sep).includes("node_modules");
16486
+ }
16487
+ function shouldResolveFromSiteRoot(source, importer, rootDir) {
16488
+ if (!importer || !isBareSpecifier(source)) {
16489
+ return false;
16490
+ }
16491
+ const importerPath = stripQuery(importer);
16492
+ if (isInside(rootDir, importerPath) || isInsideNodeModules(importerPath)) {
16493
+ return false;
16494
+ }
16495
+ return true;
16496
+ }
16497
+ function viteOffrootResolvePlugin() {
16498
+ return {
16499
+ name: "zudoku-offroot-resolve",
16500
+ enforce: "pre",
16501
+ async resolveId(source, importer, options) {
16502
+ const rootDir = getCurrentConfig().__meta.rootDir;
16503
+ if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
16504
+ return;
16505
+ }
16506
+ return this.resolve(source, path41.join(rootDir, "package.json"), {
16507
+ ...options,
16508
+ skipSelf: true
16509
+ });
16510
+ }
16511
+ };
16512
+ }
16513
+
16395
16514
  // src/vite/plugin-search.ts
16396
16515
  init_loader();
16397
- import path40 from "node:path";
16516
+ import path42 from "node:path";
16398
16517
  var viteSearchPlugin = () => {
16399
16518
  const virtualModuleId4 = "virtual:zudoku-search-plugin";
16400
16519
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -16412,7 +16531,7 @@ var viteSearchPlugin = () => {
16412
16531
  return resolvedVirtualModuleId5;
16413
16532
  }
16414
16533
  if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
16415
- return path40.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
16534
+ return path42.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
16416
16535
  }
16417
16536
  },
16418
16537
  async load(id) {
@@ -16528,6 +16647,7 @@ init_plugin_theme();
16528
16647
  function vitePlugin() {
16529
16648
  return [
16530
16649
  viteShikiRegisterPlugin(),
16650
+ viteOffrootResolvePlugin(),
16531
16651
  viteConfigReloadPlugin(),
16532
16652
  plugin_local_manifest_default(),
16533
16653
  plugin_mdx_default(),
@@ -16551,17 +16671,17 @@ function vitePlugin() {
16551
16671
  }
16552
16672
 
16553
16673
  // src/vite/config.ts
16554
- var browserConfigLoaderPath2 = path41.join(
16674
+ var browserConfigLoaderPath2 = path43.join(
16555
16675
  getZudokuRootDir(),
16556
16676
  "src/config/apitogo-config-loader.browser.ts"
16557
16677
  );
16558
16678
  var resolveMergedPublicDir = (rootDir, merged) => {
16559
16679
  if (merged.publicDir === false) return void 0;
16560
16680
  const rel = typeof merged.publicDir === "string" ? merged.publicDir : "public";
16561
- return path41.resolve(rootDir, rel);
16681
+ return path43.resolve(rootDir, rel);
16562
16682
  };
16563
- var getAppClientEntryPath = () => path41.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
16564
- var getAppServerEntryPath = () => path41.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
16683
+ var getAppClientEntryPath = () => path43.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
16684
+ var getAppServerEntryPath = () => path43.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
16565
16685
  var hasLoggedCdnInfo = false;
16566
16686
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
16567
16687
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -16591,7 +16711,7 @@ async function getViteConfig(dir, configEnv) {
16591
16711
  );
16592
16712
  if (ZuploEnv.isZuplo) {
16593
16713
  dotenv.config({
16594
- path: path41.resolve(config2.__meta.rootDir, "../.env.zuplo"),
16714
+ path: path43.resolve(config2.__meta.rootDir, "../.env.zuplo"),
16595
16715
  quiet: true
16596
16716
  });
16597
16717
  }
@@ -16616,11 +16736,11 @@ async function getViteConfig(dir, configEnv) {
16616
16736
  client: {
16617
16737
  resolve: {
16618
16738
  alias: {
16619
- [path41.join(
16739
+ [path43.join(
16620
16740
  getZudokuRootDir(),
16621
16741
  "src/config/apitogo-config-loader.node.ts"
16622
16742
  )]: browserConfigLoaderPath2,
16623
- [path41.join(
16743
+ [path43.join(
16624
16744
  getZudokuRootDir(),
16625
16745
  "src/config/apitogo-config-loader.node.js"
16626
16746
  )]: browserConfigLoaderPath2
@@ -16652,6 +16772,9 @@ async function getViteConfig(dir, configEnv) {
16652
16772
  server: {
16653
16773
  middlewareMode: true,
16654
16774
  open: true,
16775
+ fs: {
16776
+ allow: [dir, path43.dirname(dir)]
16777
+ },
16655
16778
  watch: {
16656
16779
  ignored: [
16657
16780
  `${dir}/dist`,
@@ -16666,8 +16789,8 @@ async function getViteConfig(dir, configEnv) {
16666
16789
  ssr: configEnv.isSsrBuild,
16667
16790
  sourcemap: true,
16668
16791
  target: "es2022",
16669
- outDir: path41.resolve(
16670
- path41.join(
16792
+ outDir: path43.resolve(
16793
+ path43.join(
16671
16794
  dir,
16672
16795
  "dist",
16673
16796
  config2.basePath ?? "",
@@ -16686,7 +16809,7 @@ async function getViteConfig(dir, configEnv) {
16686
16809
  },
16687
16810
  experimental: {
16688
16811
  renderBuiltUrl(filename) {
16689
- if (cdnUrl?.base && [".js", ".css"].includes(path41.extname(filename))) {
16812
+ if (cdnUrl?.base && [".js", ".css"].includes(path43.extname(filename))) {
16690
16813
  return joinUrl(cdnUrl.base, filename);
16691
16814
  }
16692
16815
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -16699,7 +16822,7 @@ async function getViteConfig(dir, configEnv) {
16699
16822
  esbuildOptions: {
16700
16823
  target: "es2022"
16701
16824
  },
16702
- entries: [path41.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
16825
+ entries: [path43.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
16703
16826
  exclude: [
16704
16827
  "@lukoweb/apitogo",
16705
16828
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -16805,7 +16928,7 @@ init_package_json();
16805
16928
  init_joinUrl();
16806
16929
  import assert from "node:assert";
16807
16930
  import { cp, mkdir as mkdir7, writeFile as writeFile8 } from "node:fs/promises";
16808
- import path42 from "node:path";
16931
+ import path44 from "node:path";
16809
16932
  var pkgJson = getZudokuPackageJson();
16810
16933
  function generateOutput({
16811
16934
  config: config2,
@@ -16862,9 +16985,9 @@ async function writeOutput(dir, {
16862
16985
  rewrites
16863
16986
  }) {
16864
16987
  const output2 = generateOutput({ config: config2, redirects, rewrites });
16865
- const outputDir = process.env.VERCEL ? path42.join(dir, ".vercel/output") : path42.join(dir, "dist/.output");
16988
+ const outputDir = process.env.VERCEL ? path44.join(dir, ".vercel/output") : path44.join(dir, "dist/.output");
16866
16989
  await mkdir7(outputDir, { recursive: true });
16867
- const outputFile = path42.join(outputDir, "config.json");
16990
+ const outputFile = path44.join(outputDir, "config.json");
16868
16991
  await writeFile8(outputFile, JSON.stringify(output2, null, 2), "utf-8");
16869
16992
  if (process.env.VERCEL) {
16870
16993
  console.log("Wrote Vercel output to", outputDir);
@@ -16876,7 +16999,7 @@ init_logger();
16876
16999
  init_file_exists();
16877
17000
  import { readFile as readFile10, rm as rm2 } from "node:fs/promises";
16878
17001
  import os from "node:os";
16879
- import path45 from "node:path";
17002
+ import path47 from "node:path";
16880
17003
  import { pathToFileURL } from "node:url";
16881
17004
  import { createIndex } from "pagefind";
16882
17005
  import colors8 from "picocolors";
@@ -16918,7 +17041,7 @@ function throttle(fn) {
16918
17041
  init_joinUrl();
16919
17042
  import { createWriteStream as createWriteStream3, existsSync as existsSync3 } from "node:fs";
16920
17043
  import { mkdir as mkdir8 } from "node:fs/promises";
16921
- import path43 from "node:path";
17044
+ import path45 from "node:path";
16922
17045
  import colors6 from "picocolors";
16923
17046
  import { SitemapStream } from "sitemap";
16924
17047
  async function generateSitemap({
@@ -16932,11 +17055,11 @@ async function generateSitemap({
16932
17055
  return;
16933
17056
  }
16934
17057
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
16935
- const outputDir = path43.resolve(baseOutputDir, config2.outDir ?? "");
17058
+ const outputDir = path45.resolve(baseOutputDir, config2.outDir ?? "");
16936
17059
  if (!existsSync3(outputDir)) {
16937
17060
  await mkdir8(outputDir, { recursive: true });
16938
17061
  }
16939
- const sitemapOutputPath = path43.join(outputDir, "sitemap.xml");
17062
+ const sitemapOutputPath = path45.join(outputDir, "sitemap.xml");
16940
17063
  const writeStream = createWriteStream3(sitemapOutputPath);
16941
17064
  sitemap.pipe(writeStream);
16942
17065
  let lastmod;
@@ -16966,14 +17089,14 @@ async function generateSitemap({
16966
17089
 
16967
17090
  // src/vite/prerender/utils.ts
16968
17091
  init_joinUrl();
16969
- var resolveRoutePath = (path67) => {
16970
- const segments = path67.split("/");
17092
+ var resolveRoutePath = (path70) => {
17093
+ const segments = path70.split("/");
16971
17094
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
16972
17095
  return void 0;
16973
17096
  }
16974
17097
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
16975
17098
  };
16976
- var isSkipped = (path67) => path67.includes("*") || /^\d+$/.test(path67);
17099
+ var isSkipped = (path70) => path70.includes("*") || /^\d+$/.test(path70);
16977
17100
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
16978
17101
  if (route.path && isSkipped(route.path)) return [];
16979
17102
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -17022,12 +17145,12 @@ var prerender = async ({
17022
17145
  serverConfigFilename,
17023
17146
  writeRedirects = true
17024
17147
  }) => {
17025
- const distDir = path45.join(dir, "dist", basePath);
17148
+ const distDir = path47.join(dir, "dist", basePath);
17026
17149
  const serverConfigPath = pathToFileURL(
17027
- path45.join(distDir, "server", serverConfigFilename)
17150
+ path47.join(distDir, "server", serverConfigFilename)
17028
17151
  ).href;
17029
17152
  const entryServerPath = pathToFileURL(
17030
- path45.join(distDir, "server/entry.server.js")
17153
+ path47.join(distDir, "server/entry.server.js")
17031
17154
  ).href;
17032
17155
  const rawConfig = await import(serverConfigPath).then(
17033
17156
  (m) => m.default
@@ -17112,7 +17235,7 @@ var prerender = async ({
17112
17235
  })
17113
17236
  );
17114
17237
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
17115
- outputPath: path45.join(distDir, "pagefind")
17238
+ outputPath: path47.join(distDir, "pagefind")
17116
17239
  });
17117
17240
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
17118
17241
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
@@ -17144,7 +17267,7 @@ var prerender = async ({
17144
17267
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
17145
17268
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
17146
17269
  const llmsConfig = docsConfig.llms ?? {};
17147
- const markdownInfoPath = path45.join(
17270
+ const markdownInfoPath = path47.join(
17148
17271
  dir,
17149
17272
  "node_modules/.apitogo/markdown-info.json"
17150
17273
  );
@@ -17235,7 +17358,7 @@ async function runBuild(options) {
17235
17358
  html,
17236
17359
  basePath: config2.basePath
17237
17360
  });
17238
- await rm3(path46.join(clientOutDir, "index.html"), { force: true });
17361
+ await rm3(path48.join(clientOutDir, "index.html"), { force: true });
17239
17362
  } else {
17240
17363
  await runPrerender({
17241
17364
  dir,
@@ -17259,7 +17382,7 @@ var runPrerender = async (options) => {
17259
17382
  serverConfigFilename,
17260
17383
  writeRedirects: process.env.VERCEL === void 0
17261
17384
  });
17262
- const indexHtml = path46.join(clientOutDir, "index.html");
17385
+ const indexHtml = path48.join(clientOutDir, "index.html");
17263
17386
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
17264
17387
  await writeFile10(indexHtml, html, "utf-8");
17265
17388
  }
@@ -17269,15 +17392,15 @@ var runPrerender = async (options) => {
17269
17392
  for (const statusPage of statusPages) {
17270
17393
  await rename(
17271
17394
  statusPage,
17272
- path46.join(dir, DIST_DIR, path46.basename(statusPage))
17395
+ path48.join(dir, DIST_DIR, path48.basename(statusPage))
17273
17396
  );
17274
17397
  }
17275
17398
  await rm3(serverOutDir, { recursive: true, force: true });
17276
17399
  if (process.env.VERCEL) {
17277
- await mkdir9(path46.join(dir, ".vercel/output/static"), { recursive: true });
17400
+ await mkdir9(path48.join(dir, ".vercel/output/static"), { recursive: true });
17278
17401
  await rename(
17279
- path46.join(dir, DIST_DIR),
17280
- path46.join(dir, ".vercel/output/static")
17402
+ path48.join(dir, DIST_DIR),
17403
+ path48.join(dir, ".vercel/output/static")
17281
17404
  );
17282
17405
  }
17283
17406
  await writeOutput(dir, {
@@ -17287,7 +17410,7 @@ var runPrerender = async (options) => {
17287
17410
  });
17288
17411
  if (ZuploEnv.isZuplo && issuer) {
17289
17412
  await writeFile10(
17290
- path46.join(dir, DIST_DIR, ".output/zuplo.json"),
17413
+ path48.join(dir, DIST_DIR, ".output/zuplo.json"),
17291
17414
  JSON.stringify({ issuer }, null, 2),
17292
17415
  "utf-8"
17293
17416
  );
@@ -17299,10 +17422,10 @@ var runPrerender = async (options) => {
17299
17422
  };
17300
17423
  var bundleSSREntry = async (options) => {
17301
17424
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
17302
- const tempEntryPath = path46.join(dir, "__ssr-entry.ts");
17425
+ const tempEntryPath = path48.join(dir, "__ssr-entry.ts");
17303
17426
  const packageRoot = getZudokuRootDir();
17304
17427
  const templateContent = await readFile11(
17305
- path46.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
17428
+ path48.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
17306
17429
  "utf-8"
17307
17430
  );
17308
17431
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
@@ -17317,9 +17440,9 @@ var bundleSSREntry = async (options) => {
17317
17440
  platform: adapter === "node" ? "node" : "neutral",
17318
17441
  target: "es2022",
17319
17442
  format: "esm",
17320
- outfile: path46.join(serverOutDir, "entry.js"),
17443
+ outfile: path48.join(serverOutDir, "entry.js"),
17321
17444
  external: ["./entry.server.js", `./${serverConfigFilename}`],
17322
- nodePaths: [path46.join(packageRoot, "node_modules")],
17445
+ nodePaths: [path48.join(packageRoot, "node_modules")],
17323
17446
  banner: { js: "// Bundled SSR entry" }
17324
17447
  });
17325
17448
  } finally {
@@ -17332,11 +17455,11 @@ init_logger();
17332
17455
  init_package_json();
17333
17456
 
17334
17457
  // src/cli/preview/handler.ts
17335
- import path47 from "node:path";
17458
+ import path49 from "node:path";
17336
17459
  import { preview as vitePreview } from "vite";
17337
17460
  var DEFAULT_PREVIEW_PORT = 4e3;
17338
17461
  async function preview(argv) {
17339
- const dir = path47.resolve(process.cwd(), argv.dir);
17462
+ const dir = path49.resolve(process.cwd(), argv.dir);
17340
17463
  const viteConfig = await getViteConfig(dir, {
17341
17464
  command: "serve",
17342
17465
  mode: "production",
@@ -17377,7 +17500,7 @@ async function build(argv) {
17377
17500
  printDiagnosticsToConsole("");
17378
17501
  printDiagnosticsToConsole("");
17379
17502
  }
17380
- const dir = path48.resolve(process.cwd(), argv.dir);
17503
+ const dir = path50.resolve(process.cwd(), argv.dir);
17381
17504
  try {
17382
17505
  await runBuild({
17383
17506
  dir,
@@ -17437,12 +17560,12 @@ var build_default = {
17437
17560
  };
17438
17561
 
17439
17562
  // src/cli/check/handler.ts
17440
- import path50 from "node:path";
17563
+ import path52 from "node:path";
17441
17564
 
17442
17565
  // src/cli/platform/tools/check-publish-readiness.ts
17443
- import path49 from "node:path";
17566
+ import path51 from "node:path";
17444
17567
  async function checkPublishReadiness(client, _config, args) {
17445
- const sourceDirectory = path49.resolve(args.sourceDirectory);
17568
+ const sourceDirectory = path51.resolve(args.sourceDirectory);
17446
17569
  const manifest = await readManifest(sourceDirectory) ?? createScaffoldManifest();
17447
17570
  const emailOptions = await resolveEmailOptionsForPublish(
17448
17571
  client,
@@ -17520,7 +17643,7 @@ async function checkPublishReadiness(client, _config, args) {
17520
17643
 
17521
17644
  // src/cli/check/handler.ts
17522
17645
  async function check(argv) {
17523
- const sourceDirectory = path50.resolve(process.cwd(), argv.dir);
17646
+ const sourceDirectory = path52.resolve(process.cwd(), argv.dir);
17524
17647
  const config2 = loadConfig();
17525
17648
  const client = new PlatformApiClient(config2);
17526
17649
  let result;
@@ -17565,13 +17688,13 @@ var check_default = {
17565
17688
  // src/cli/make-config/handler.ts
17566
17689
  import { constants as constants2 } from "node:fs";
17567
17690
  import { access as access8, mkdir as mkdir12, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
17568
- import path58 from "node:path";
17691
+ import path60 from "node:path";
17569
17692
  import { stdin as input2 } from "node:process";
17570
17693
  import { glob as glob5 } from "glob";
17571
17694
 
17572
17695
  // src/cli/scaffold/dev-portal-config-pages.ts
17573
17696
  import { access as access4, readFile as readFile12, rename as rename2, rm as rm4, writeFile as writeFile11 } from "node:fs/promises";
17574
- import path51 from "node:path";
17697
+ import path53 from "node:path";
17575
17698
  async function writeConfigAtomically(filePath, content) {
17576
17699
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
17577
17700
  try {
@@ -17584,7 +17707,7 @@ async function writeConfigAtomically(filePath, content) {
17584
17707
  }
17585
17708
  async function resolveApitogoConfigPath(sourceDirectory) {
17586
17709
  for (const filename of ["apitogo.config.tsx", "apitogo.config.jsx"]) {
17587
- const configPath = path51.join(sourceDirectory, filename);
17710
+ const configPath = path53.join(sourceDirectory, filename);
17588
17711
  try {
17589
17712
  await access4(configPath);
17590
17713
  return configPath;
@@ -18321,16 +18444,16 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
18321
18444
 
18322
18445
  // src/cli/scaffold/wire-openapi.ts
18323
18446
  import { access as access6, readFile as readFile14, writeFile as writeFile13 } from "node:fs/promises";
18324
- import path54 from "node:path";
18447
+ import path56 from "node:path";
18325
18448
 
18326
18449
  // src/cli/scaffold/scaffold-dev-portal-site.ts
18327
18450
  import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "node:fs/promises";
18328
- import path53 from "node:path";
18451
+ import path55 from "node:path";
18329
18452
 
18330
18453
  // src/cli/scaffold/create-apitogo-cli.ts
18331
18454
  import { spawn as spawn3 } from "node:child_process";
18332
18455
  import { access as access5, rm as rm5 } from "node:fs/promises";
18333
- import path52 from "node:path";
18456
+ import path54 from "node:path";
18334
18457
 
18335
18458
  // src/cli/scaffold/apitogo-npm-packages.ts
18336
18459
  var DEFAULT_CREATE_APITOGO_PACKAGE2 = "@lukoweb/create-apitogo@latest";
@@ -18431,9 +18554,9 @@ function resolveDocToolPath(explicit) {
18431
18554
  return value || void 0;
18432
18555
  }
18433
18556
  function splitOutputDirectory(outputDirectory) {
18434
- const resolvedOutputDirectory = path52.resolve(outputDirectory);
18435
- const projectName = path52.basename(resolvedOutputDirectory);
18436
- const parentDirectory = path52.dirname(resolvedOutputDirectory);
18557
+ const resolvedOutputDirectory = path54.resolve(outputDirectory);
18558
+ const projectName = path54.basename(resolvedOutputDirectory);
18559
+ const parentDirectory = path54.dirname(resolvedOutputDirectory);
18437
18560
  if (!projectName || projectName === "." || projectName === "..") {
18438
18561
  throw new Error(
18439
18562
  "outputDirectory must be a named folder (e.g. ./dev-portal-site), not the current directory."
@@ -18459,7 +18582,7 @@ async function directoryHasEntries(dir) {
18459
18582
  }
18460
18583
  }
18461
18584
  function resolveLocalCreateApitogoEntry(docToolPath) {
18462
- return path52.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
18585
+ return path54.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
18463
18586
  }
18464
18587
  async function resolveCreateApitogoInvocation(options) {
18465
18588
  const docToolPath = resolveDocToolPath(options.docToolPath);
@@ -18541,7 +18664,7 @@ async function runCreateApitogoDevPortal(options) {
18541
18664
  result.exitCode
18542
18665
  );
18543
18666
  }
18544
- if (!await pathExists3(path52.join(resolvedOutputDirectory, "package.json"))) {
18667
+ if (!await pathExists3(path54.join(resolvedOutputDirectory, "package.json"))) {
18545
18668
  throw new CreateApitogoCliError(
18546
18669
  `create-apitogo completed but package.json was not found at ${resolvedOutputDirectory}`,
18547
18670
  result.output,
@@ -18597,7 +18720,7 @@ function ensureRequiredApitogoModules(pkg, options) {
18597
18720
  ]
18598
18721
  ]) {
18599
18722
  if (options.docToolPath) {
18600
- deps[moduleName] = `file:${path53.join(options.docToolPath, localPath)}`;
18723
+ deps[moduleName] = `file:${path55.join(options.docToolPath, localPath)}`;
18601
18724
  continue;
18602
18725
  }
18603
18726
  deps[moduleName] = `npm:${moduleName}@${moduleAliasVersion}`;
@@ -18626,7 +18749,7 @@ function rewritePackageJson(raw, options) {
18626
18749
  if (!deps) continue;
18627
18750
  for (const [dep, relativePath] of Object.entries(DOC_TOOL_LOCAL_PACKAGE_PATHS)) {
18628
18751
  if (dep in deps) {
18629
- deps[dep] = `file:${path53.join(options.docToolPath, relativePath)}`;
18752
+ deps[dep] = `file:${path55.join(options.docToolPath, relativePath)}`;
18630
18753
  linkedWorkspacePackage = true;
18631
18754
  }
18632
18755
  }
@@ -18723,23 +18846,23 @@ function patchDashboardPageConfig(content) {
18723
18846
  );
18724
18847
  }
18725
18848
  async function ensureAccountPlansPage(outputDirectory) {
18726
- const pagePath = path53.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
18849
+ const pagePath = path55.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
18727
18850
  try {
18728
18851
  await readFile13(pagePath, "utf8");
18729
18852
  return void 0;
18730
18853
  } catch {
18731
- await mkdir10(path53.dirname(pagePath), { recursive: true });
18854
+ await mkdir10(path55.dirname(pagePath), { recursive: true });
18732
18855
  await writeFile12(pagePath, ACCOUNT_PLANS_PAGE);
18733
18856
  return ACCOUNT_PLANS_PAGE_PATH;
18734
18857
  }
18735
18858
  }
18736
18859
  async function ensureDashboardPage(outputDirectory) {
18737
- const pagePath = path53.join(outputDirectory, DASHBOARD_PAGE_PATH);
18860
+ const pagePath = path55.join(outputDirectory, DASHBOARD_PAGE_PATH);
18738
18861
  try {
18739
18862
  await readFile13(pagePath, "utf8");
18740
18863
  return void 0;
18741
18864
  } catch {
18742
- await mkdir10(path53.dirname(pagePath), { recursive: true });
18865
+ await mkdir10(path55.dirname(pagePath), { recursive: true });
18743
18866
  await writeFile12(pagePath, DASHBOARD_PAGE);
18744
18867
  return DASHBOARD_PAGE_PATH;
18745
18868
  }
@@ -18790,7 +18913,7 @@ function patchApitogoConfig(content, options) {
18790
18913
  async function patchScaffoldedSite(outputDirectory, options) {
18791
18914
  const title = options.branding?.title ?? options.siteName;
18792
18915
  const filesWritten = [];
18793
- const packageJsonPath = path53.join(outputDirectory, "package.json");
18916
+ const packageJsonPath = path55.join(outputDirectory, "package.json");
18794
18917
  if (options.patchPackageJson !== false) {
18795
18918
  const packageJson2 = await readFile13(packageJsonPath, "utf8");
18796
18919
  await writeFile12(
@@ -18803,7 +18926,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
18803
18926
  );
18804
18927
  filesWritten.push("package.json");
18805
18928
  }
18806
- const configPath = path53.join(outputDirectory, "apitogo.config.tsx");
18929
+ const configPath = path55.join(outputDirectory, "apitogo.config.tsx");
18807
18930
  const configContent = await readFile13(configPath, "utf8");
18808
18931
  await writeFile12(
18809
18932
  configPath,
@@ -18865,15 +18988,7 @@ async function pathExists4(filePath) {
18865
18988
  }
18866
18989
  }
18867
18990
  async function discoverSiteOpenApi(siteDirectory) {
18868
- const site = path54.resolve(siteDirectory);
18869
- const searchedDirectories = [site];
18870
- const candidates = [];
18871
- for (const name of OPENAPI_BASENAMES) {
18872
- const candidate = path54.join(site, name);
18873
- if (await pathExists4(candidate)) {
18874
- candidates.push(candidate);
18875
- }
18876
- }
18991
+ const { candidates, searchedDirectories } = await collectSiteOpenApiFiles(siteDirectory);
18877
18992
  const invalidCandidates = [];
18878
18993
  for (const candidate of candidates) {
18879
18994
  const validation = await validateOpenApiFile(candidate);
@@ -18906,8 +19021,8 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
18906
19021
  return discoverNearbyOpenApi(siteDirectory);
18907
19022
  }
18908
19023
  async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
18909
- const resolvedSource = path54.resolve(sourceDirectory);
18910
- const resolvedOpenApi = path54.resolve(openApiPath);
19024
+ const resolvedSource = path56.resolve(sourceDirectory);
19025
+ const resolvedOpenApi = path56.resolve(openApiPath);
18911
19026
  const input3 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
18912
19027
  const validation = await validateOpenApiFile(resolvedOpenApi);
18913
19028
  if (!validation.valid) {
@@ -18932,7 +19047,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
18932
19047
  "utf8"
18933
19048
  );
18934
19049
  } else {
18935
- const tsxConfigPath = path54.join(resolvedSource, "apitogo.config.tsx");
19050
+ const tsxConfigPath = path56.join(resolvedSource, "apitogo.config.tsx");
18936
19051
  const configContent = await readFile14(tsxConfigPath, "utf8");
18937
19052
  try {
18938
19053
  const patched = patchApitogoConfigOpenApiToFile(configContent, input3);
@@ -19020,10 +19135,10 @@ async function discoverAndWireOpenApi(siteDirectory, mode) {
19020
19135
  // src/cli/make-config/interactive.ts
19021
19136
  import { createInterface } from "node:readline/promises";
19022
19137
  import { stdin as input, stdout as output } from "node:process";
19023
- import path56 from "node:path";
19138
+ import path58 from "node:path";
19024
19139
 
19025
19140
  // src/cli/make-config/json-config.ts
19026
- import path55 from "node:path";
19141
+ import path57 from "node:path";
19027
19142
  var APITOGO_JSON_FILENAME = "apitogo.config.json";
19028
19143
  var DOCUMENTATION_NAV_LABEL2 = "Documentation";
19029
19144
  var API_REFERENCE_PATH = "/api";
@@ -19382,9 +19497,9 @@ function openapiInputForConfig(specRelativePosix) {
19382
19497
  return `./${specRelativePosix}`;
19383
19498
  }
19384
19499
  function toRelativeOpenApiInput(projectDir, inputPath) {
19385
- const resolved = path55.isAbsolute(inputPath) ? inputPath : path55.resolve(projectDir, inputPath);
19386
- const relative = path55.relative(projectDir, resolved);
19387
- const posix = relative.split(path55.sep).join(path55.posix.sep);
19500
+ const resolved = path57.isAbsolute(inputPath) ? inputPath : path57.resolve(projectDir, inputPath);
19501
+ const relative = path57.relative(projectDir, resolved);
19502
+ const posix = relative.split(path57.sep).join(path57.posix.sep);
19388
19503
  if (!posix) {
19389
19504
  throw new Error("OpenAPI path must point to a file.");
19390
19505
  }
@@ -19757,7 +19872,7 @@ async function promptMakeConfigInteractive(options) {
19757
19872
  continue;
19758
19873
  }
19759
19874
  const routePath = `/${slug}`;
19760
- const relativePath = path56.posix.join(options.pagesDir, `${slug}.tsx`);
19875
+ const relativePath = path58.posix.join(options.pagesDir, `${slug}.tsx`);
19761
19876
  const page = {
19762
19877
  slug,
19763
19878
  title: pageTitle.trim(),
@@ -19850,7 +19965,7 @@ export default function ${componentName}() {
19850
19965
  init_package_json();
19851
19966
  import { constants } from "node:fs";
19852
19967
  import { access as access7, mkdir as mkdir11, readFile as readFile15, writeFile as writeFile14 } from "node:fs/promises";
19853
- import path57 from "node:path";
19968
+ import path59 from "node:path";
19854
19969
  import { glob as glob4 } from "glob";
19855
19970
 
19856
19971
  // src/cli/make-config/branding-assets.ts
@@ -19874,9 +19989,9 @@ var OPENAPI_GLOBS = [
19874
19989
  "openapi.yaml",
19875
19990
  "openapi.yml"
19876
19991
  ];
19877
- var toPosix = (p) => p.split(path57.sep).join("/");
19992
+ var toPosix = (p) => p.split(path59.sep).join("/");
19878
19993
  var sanitizePackageName = (dir) => {
19879
- const base = path57.basename(path57.resolve(dir));
19994
+ const base = path59.basename(path59.resolve(dir));
19880
19995
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
19881
19996
  return s || "apitogo-site";
19882
19997
  };
@@ -19886,7 +20001,7 @@ var apitogoVersionRange = () => {
19886
20001
  };
19887
20002
  async function findOpenApiSpecPath(dir) {
19888
20003
  for (const rel of OPENAPI_GLOBS) {
19889
- const full = path57.join(dir, rel);
20004
+ const full = path59.join(dir, rel);
19890
20005
  try {
19891
20006
  await access7(full, constants.R_OK);
19892
20007
  return toPosix(rel);
@@ -19901,7 +20016,7 @@ async function findOpenApiSpecPath(dir) {
19901
20016
  return extra[0] ? toPosix(extra[0]) : null;
19902
20017
  }
19903
20018
  async function ensurePackageJson(dir) {
19904
- const pkgPath = path57.join(dir, "package.json");
20019
+ const pkgPath = path59.join(dir, "package.json");
19905
20020
  const apitogoVer = apitogoVersionRange();
19906
20021
  const baseDeps = {
19907
20022
  react: ">=19.0.0",
@@ -19968,7 +20083,7 @@ async function ensurePackageJson(dir) {
19968
20083
  return false;
19969
20084
  }
19970
20085
  async function ensureTsconfigJson(dir) {
19971
- const tsPath = path57.join(dir, "tsconfig.json");
20086
+ const tsPath = path59.join(dir, "tsconfig.json");
19972
20087
  try {
19973
20088
  await access7(tsPath, constants.R_OK);
19974
20089
  return false;
@@ -20017,28 +20132,28 @@ var fileExists2 = async (filePath) => {
20017
20132
  }
20018
20133
  };
20019
20134
  async function ensurePortalStubFiles(dir) {
20020
- const landingPath = path57.join(dir, "landing", "LandingPage.tsx");
20135
+ const landingPath = path59.join(dir, "landing", "LandingPage.tsx");
20021
20136
  if (!await fileExists2(landingPath)) {
20022
- await mkdir11(path57.join(dir, "landing"), { recursive: true });
20137
+ await mkdir11(path59.join(dir, "landing"), { recursive: true });
20023
20138
  await writeFile14(landingPath, LANDING_PAGE_SOURCE, "utf8");
20024
20139
  }
20025
- const plansPath = path57.join(dir, "user-panel", "AccountPlansPage.tsx");
20140
+ const plansPath = path59.join(dir, "user-panel", "AccountPlansPage.tsx");
20026
20141
  if (!await fileExists2(plansPath)) {
20027
- await mkdir11(path57.join(dir, "user-panel"), { recursive: true });
20142
+ await mkdir11(path59.join(dir, "user-panel"), { recursive: true });
20028
20143
  await writeFile14(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20029
20144
  }
20030
- const dashboardPath = path57.join(dir, "user-panel", "DashboardPage.tsx");
20145
+ const dashboardPath = path59.join(dir, "user-panel", "DashboardPage.tsx");
20031
20146
  if (!await fileExists2(dashboardPath)) {
20032
- await mkdir11(path57.join(dir, "user-panel"), { recursive: true });
20147
+ await mkdir11(path59.join(dir, "user-panel"), { recursive: true });
20033
20148
  await writeFile14(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20034
20149
  }
20035
20150
  await ensurePublicBrandingFiles(dir);
20036
20151
  }
20037
20152
  async function ensurePublicBrandingFiles(dir) {
20038
- const destDir = path57.join(dir, "public");
20153
+ const destDir = path59.join(dir, "public");
20039
20154
  await mkdir11(destDir, { recursive: true });
20040
20155
  for (const { name, content } of BRANDING_ASSETS) {
20041
- const dest = path57.join(destDir, name);
20156
+ const dest = path59.join(destDir, name);
20042
20157
  if (await fileExists2(dest)) {
20043
20158
  continue;
20044
20159
  }
@@ -20046,7 +20161,7 @@ async function ensurePublicBrandingFiles(dir) {
20046
20161
  }
20047
20162
  }
20048
20163
  async function ensureThinConfigTsx(dir) {
20049
- const tsxPath = path57.join(dir, "apitogo.config.tsx");
20164
+ const tsxPath = path59.join(dir, "apitogo.config.tsx");
20050
20165
  if (await fileExists2(tsxPath)) {
20051
20166
  return false;
20052
20167
  }
@@ -20055,7 +20170,7 @@ async function ensureThinConfigTsx(dir) {
20055
20170
  }
20056
20171
 
20057
20172
  // src/cli/make-config/handler.ts
20058
- var toPosixPath2 = (value) => value.split(path58.sep).join(path58.posix.sep);
20173
+ var toPosixPath2 = (value) => value.split(path60.sep).join(path60.posix.sep);
20059
20174
  var fileExists3 = async (filePath) => {
20060
20175
  try {
20061
20176
  await access8(filePath, constants2.F_OK);
@@ -20113,7 +20228,7 @@ async function persistConfig(config2, ctx) {
20113
20228
  };
20114
20229
  await writeFile15(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20115
20230
  `, "utf8");
20116
- const tsxPath = path58.join(ctx.dir, "apitogo.config.tsx");
20231
+ const tsxPath = path60.join(ctx.dir, "apitogo.config.tsx");
20117
20232
  if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
20118
20233
  const tsxSource = await readFile16(tsxPath, "utf8");
20119
20234
  if (isManagedConfigWrapper(tsxSource)) {
@@ -20140,7 +20255,7 @@ function mergeBackendFlag(config2, backend) {
20140
20255
  return next;
20141
20256
  }
20142
20257
  async function makeConfig(argv) {
20143
- const dir = path58.resolve(process.cwd(), argv.dir);
20258
+ const dir = path60.resolve(process.cwd(), argv.dir);
20144
20259
  const pagesDir = toPosixPath2(
20145
20260
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
20146
20261
  );
@@ -20160,14 +20275,14 @@ async function makeConfig(argv) {
20160
20275
  printDiagnosticsToConsole("Created tsconfig.json.");
20161
20276
  }
20162
20277
  await ensurePortalStubFiles(dir);
20163
- const jsonPath = path58.join(dir, APITOGO_JSON_FILENAME);
20278
+ const jsonPath = path60.join(dir, APITOGO_JSON_FILENAME);
20164
20279
  let createdJson = false;
20165
20280
  let config2;
20166
20281
  if (await fileExists3(jsonPath)) {
20167
20282
  config2 = await readJsonConfig(jsonPath);
20168
20283
  } else {
20169
20284
  config2 = createDefaultApitogoJsonConfig({
20170
- title: titleFromDirectoryName(path58.basename(dir)),
20285
+ title: titleFromDirectoryName(path60.basename(dir)),
20171
20286
  pagesDir
20172
20287
  });
20173
20288
  createdJson = true;
@@ -20216,8 +20331,8 @@ async function makeConfig(argv) {
20216
20331
  return;
20217
20332
  }
20218
20333
  if (action2.kind === "page") {
20219
- const pagePath = path58.join(dir, action2.page.relativePath);
20220
- await mkdir12(path58.dirname(pagePath), { recursive: true });
20334
+ const pagePath = path60.join(dir, action2.page.relativePath);
20335
+ await mkdir12(path60.dirname(pagePath), { recursive: true });
20221
20336
  await writeFile15(
20222
20337
  pagePath,
20223
20338
  buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
@@ -20270,7 +20385,7 @@ async function makeConfig(argv) {
20270
20385
  if (argv.openapi) {
20271
20386
  const wire = await wireDevPortalOpenApi(
20272
20387
  dir,
20273
- path58.resolve(dir, argv.openapi)
20388
+ path60.resolve(dir, argv.openapi)
20274
20389
  );
20275
20390
  if (wire.status !== "succeeded") {
20276
20391
  throw new Error(
@@ -20299,7 +20414,7 @@ async function makeConfig(argv) {
20299
20414
  const slug = normalizePageSlug(argv.pageSlug);
20300
20415
  const pageTemplate = normalizePageTemplate(argv.pageTemplate);
20301
20416
  const relativePagePath = pageComponentRelativePath(slug);
20302
- const filePath = path58.join(dir, relativePagePath);
20417
+ const filePath = path60.join(dir, relativePagePath);
20303
20418
  const isUpdate = argv.pageUpdate === true;
20304
20419
  if (isUpdate) {
20305
20420
  if (!await fileExists3(filePath)) {
@@ -20332,7 +20447,7 @@ async function makeConfig(argv) {
20332
20447
  argv.pageContent,
20333
20448
  pageTemplate
20334
20449
  );
20335
- await mkdir12(path58.dirname(filePath), { recursive: true });
20450
+ await mkdir12(path60.dirname(filePath), { recursive: true });
20336
20451
  await writeFile15(filePath, tsx, "utf8");
20337
20452
  const configResult = await wireNewDevPortalPageInConfig(
20338
20453
  dir,
@@ -20345,7 +20460,7 @@ async function makeConfig(argv) {
20345
20460
  pagePath: relativePagePath,
20346
20461
  pageTemplate,
20347
20462
  configUpdated: configResult.updated,
20348
- configPath: configResult.configPath ? path58.relative(dir, configResult.configPath) : null
20463
+ configPath: configResult.configPath ? path60.relative(dir, configResult.configPath) : null
20349
20464
  };
20350
20465
  changes.push("page_add");
20351
20466
  }
@@ -20499,14 +20614,14 @@ var deploy_default = {
20499
20614
 
20500
20615
  // src/cli/dev/handler.ts
20501
20616
  init_joinUrl();
20502
- import path61 from "node:path";
20617
+ import path63 from "node:path";
20503
20618
 
20504
20619
  // src/vite/dev-server.ts
20505
20620
  init_logger();
20506
- import fs10 from "node:fs/promises";
20621
+ import fs11 from "node:fs/promises";
20507
20622
  import http from "node:http";
20508
20623
  import https from "node:https";
20509
- import path60 from "node:path";
20624
+ import path62 from "node:path";
20510
20625
  import { createHttpTerminator } from "http-terminator";
20511
20626
  import {
20512
20627
  createServer as createViteServer,
@@ -20539,7 +20654,7 @@ init_loader();
20539
20654
  // src/vite/pagefind-dev-index.ts
20540
20655
  init_invariant();
20541
20656
  init_joinUrl();
20542
- import path59 from "node:path";
20657
+ import path61 from "node:path";
20543
20658
  import { createIndex as createIndex2 } from "pagefind";
20544
20659
  import { isRunnableDevEnvironment } from "vite";
20545
20660
  async function* buildPagefindDevIndex(vite, config2) {
@@ -20592,7 +20707,7 @@ async function* buildPagefindDevIndex(vite, config2) {
20592
20707
  path: urlPath
20593
20708
  };
20594
20709
  }
20595
- const outputPath = path59.join(vite.config.publicDir, "pagefind");
20710
+ const outputPath = path61.join(vite.config.publicDir, "pagefind");
20596
20711
  await pagefindIndex.writeFiles({ outputPath });
20597
20712
  yield { type: "complete", success: true, indexed };
20598
20713
  }
@@ -20611,9 +20726,9 @@ var DevServer = class {
20611
20726
  this.protocol = "https";
20612
20727
  const { dir } = this.options;
20613
20728
  const [key, cert, ca] = await Promise.all([
20614
- fs10.readFile(path60.resolve(dir, config2.https.key)),
20615
- fs10.readFile(path60.resolve(dir, config2.https.cert)),
20616
- config2.https.ca ? fs10.readFile(path60.resolve(dir, config2.https.ca)) : void 0
20729
+ fs11.readFile(path62.resolve(dir, config2.https.key)),
20730
+ fs11.readFile(path62.resolve(dir, config2.https.cert)),
20731
+ config2.https.ca ? fs11.readFile(path62.resolve(dir, config2.https.ca)) : void 0
20617
20732
  ]);
20618
20733
  return https.createServer({ key, cert, ca });
20619
20734
  }
@@ -20630,7 +20745,7 @@ var DevServer = class {
20630
20745
  );
20631
20746
  const server = await this.createNodeServer(config2);
20632
20747
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
20633
- const publicRoot = path60.resolve(
20748
+ const publicRoot = path62.resolve(
20634
20749
  this.options.dir,
20635
20750
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
20636
20751
  );
@@ -20647,7 +20762,7 @@ var DevServer = class {
20647
20762
  // built-in transform middleware which would treat the path as a static asset.
20648
20763
  name: "apitogo:entry-client",
20649
20764
  configureServer(server2) {
20650
- const entryPath = path60.posix.join(
20765
+ const entryPath = path62.posix.join(
20651
20766
  server2.config.base,
20652
20767
  "/__z/entry.client.tsx"
20653
20768
  );
@@ -20812,7 +20927,7 @@ init_package_json();
20812
20927
  async function dev(argv) {
20813
20928
  const packageJson2 = getZudokuPackageJson();
20814
20929
  process.env.NODE_ENV = "development";
20815
- const dir = path61.resolve(process.cwd(), argv.dir);
20930
+ const dir = path63.resolve(process.cwd(), argv.dir);
20816
20931
  const server = new DevServer({
20817
20932
  dir,
20818
20933
  argPort: argv.port,
@@ -20895,7 +21010,11 @@ var dev_default = {
20895
21010
  };
20896
21011
 
20897
21012
  // src/cli/init/handler.ts
20898
- import path63 from "node:path";
21013
+ import path66 from "node:path";
21014
+
21015
+ // src/cli/scaffold/run-scaffold-discovery.ts
21016
+ import { access as access10, readFile as readFile18, writeFile as writeFile17 } from "node:fs/promises";
21017
+ import path65 from "node:path";
20899
21018
 
20900
21019
  // src/cli/scaffold/wire-docs.ts
20901
21020
  import {
@@ -20908,7 +21027,7 @@ import {
20908
21027
  symlink,
20909
21028
  writeFile as writeFile16
20910
21029
  } from "node:fs/promises";
20911
- import path62 from "node:path";
21030
+ import path64 from "node:path";
20912
21031
  var DOCS_DIR_WHITELIST = [
20913
21032
  "docs",
20914
21033
  "documents",
@@ -20945,14 +21064,14 @@ async function isDirectory(filePath) {
20945
21064
  }
20946
21065
  }
20947
21066
  function toPosix2(value) {
20948
- return value.split(path62.sep).join(path62.posix.sep);
21067
+ return value.split(path64.sep).join(path64.posix.sep);
20949
21068
  }
20950
21069
  function isWhitelistedDirName(name) {
20951
21070
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
20952
21071
  }
20953
- function isInside(parent, child) {
20954
- const relative = path62.relative(parent, child);
20955
- return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
21072
+ function isInside2(parent, child) {
21073
+ const relative = path64.relative(parent, child);
21074
+ return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
20956
21075
  }
20957
21076
  async function collectMarkdownFiles(dir) {
20958
21077
  const files = [];
@@ -20966,7 +21085,7 @@ async function collectMarkdownFiles(dir) {
20966
21085
  if (entry.name.startsWith(".")) {
20967
21086
  continue;
20968
21087
  }
20969
- const full = path62.join(dir, entry.name);
21088
+ const full = path64.join(dir, entry.name);
20970
21089
  if (entry.isDirectory()) {
20971
21090
  if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink()) {
20972
21091
  continue;
@@ -20981,11 +21100,11 @@ async function collectMarkdownFiles(dir) {
20981
21100
  return files;
20982
21101
  }
20983
21102
  async function collectSearchRoots(siteDirectory) {
20984
- const site = path62.resolve(siteDirectory);
20985
- const parent = path62.dirname(site);
21103
+ const site = path64.resolve(siteDirectory);
21104
+ const parent = path64.dirname(site);
20986
21105
  const roots = [];
20987
21106
  const add = (dir) => {
20988
- const resolved = path62.resolve(dir);
21107
+ const resolved = path64.resolve(dir);
20989
21108
  if (!roots.includes(resolved)) {
20990
21109
  roots.push(resolved);
20991
21110
  }
@@ -20998,7 +21117,7 @@ async function collectSearchRoots(siteDirectory) {
20998
21117
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
20999
21118
  continue;
21000
21119
  }
21001
- add(path62.join(parent, entry.name));
21120
+ add(path64.join(parent, entry.name));
21002
21121
  }
21003
21122
  } catch {
21004
21123
  }
@@ -21007,14 +21126,14 @@ async function collectSearchRoots(siteDirectory) {
21007
21126
  return roots;
21008
21127
  }
21009
21128
  async function discoverNearbyDocsDirectories(siteDirectory) {
21010
- const site = path62.resolve(siteDirectory);
21011
- const sitePages = path62.join(site, PAGES_DIR);
21129
+ const site = path64.resolve(siteDirectory);
21130
+ const sitePages = path64.join(site, PAGES_DIR);
21012
21131
  const searchedDirectories = await collectSearchRoots(site);
21013
21132
  const directories = [];
21014
21133
  const seen = /* @__PURE__ */ new Set();
21015
21134
  const consider = async (dir) => {
21016
- const resolved = path62.resolve(dir);
21017
- if (resolved === site || seen.has(resolved) || isInside(sitePages, resolved)) {
21135
+ const resolved = path64.resolve(dir);
21136
+ if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
21018
21137
  return;
21019
21138
  }
21020
21139
  if (!await isDirectory(resolved)) {
@@ -21030,7 +21149,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21030
21149
  directories.push({ sourceDirectory: resolved, files });
21031
21150
  };
21032
21151
  for (const root of searchedDirectories) {
21033
- if (isWhitelistedDirName(path62.basename(root))) {
21152
+ if (isWhitelistedDirName(path64.basename(root))) {
21034
21153
  await consider(root);
21035
21154
  }
21036
21155
  try {
@@ -21042,7 +21161,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21042
21161
  if (!isWhitelistedDirName(entry.name)) {
21043
21162
  continue;
21044
21163
  }
21045
- await consider(path62.join(root, entry.name));
21164
+ await consider(path64.join(root, entry.name));
21046
21165
  }
21047
21166
  } catch {
21048
21167
  }
@@ -21053,8 +21172,8 @@ function slugifyDirName(name) {
21053
21172
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
21054
21173
  }
21055
21174
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
21056
- const base = slugifyDirName(path62.basename(sourceDirectory));
21057
- const parent = slugifyDirName(path62.basename(path62.dirname(sourceDirectory)));
21175
+ const base = slugifyDirName(path64.basename(sourceDirectory));
21176
+ const parent = slugifyDirName(path64.basename(path64.dirname(sourceDirectory)));
21058
21177
  const candidates = [base, `${parent}-${base}`];
21059
21178
  let index = 2;
21060
21179
  while (true) {
@@ -21062,7 +21181,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
21062
21181
  if (used.has(name)) {
21063
21182
  continue;
21064
21183
  }
21065
- const target = path62.join(pagesDir, name);
21184
+ const target = path64.join(pagesDir, name);
21066
21185
  if (await pathExists5(target)) {
21067
21186
  const stat4 = await lstat(target);
21068
21187
  if (!stat4.isDirectory() || !await isManagedLinkDir(target)) {
@@ -21093,8 +21212,8 @@ async function alreadyLinked(linkPath, sourcePath) {
21093
21212
  return false;
21094
21213
  }
21095
21214
  const current = await readlink(linkPath);
21096
- const resolved = path62.resolve(path62.dirname(linkPath), current);
21097
- return resolved === path62.resolve(sourcePath);
21215
+ const resolved = path64.resolve(path64.dirname(linkPath), current);
21216
+ return resolved === path64.resolve(sourcePath);
21098
21217
  } catch {
21099
21218
  return false;
21100
21219
  }
@@ -21106,8 +21225,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
21106
21225
  if (await pathExists5(linkPath)) {
21107
21226
  return "skipped";
21108
21227
  }
21109
- await mkdir13(path62.dirname(linkPath), { recursive: true });
21110
- const relativeTarget = path62.relative(path62.dirname(linkPath), sourcePath);
21228
+ await mkdir13(path64.dirname(linkPath), { recursive: true });
21229
+ const relativeTarget = path64.relative(path64.dirname(linkPath), sourcePath);
21111
21230
  await symlink(
21112
21231
  relativeTarget,
21113
21232
  linkPath,
@@ -21122,7 +21241,7 @@ async function applyDocsNavigation(siteDirectory, routes) {
21122
21241
  if (routes.length === 0) {
21123
21242
  return;
21124
21243
  }
21125
- const configPath = path62.join(siteDirectory, CONFIG_FILENAME);
21244
+ const configPath = path64.join(siteDirectory, CONFIG_FILENAME);
21126
21245
  if (!await pathExists5(configPath)) {
21127
21246
  return;
21128
21247
  }
@@ -21138,8 +21257,8 @@ async function applyDocsNavigation(siteDirectory, routes) {
21138
21257
  `, "utf8");
21139
21258
  }
21140
21259
  async function discoverAndWireDocs(siteDirectory) {
21141
- const site = path62.resolve(siteDirectory);
21142
- const pagesDir = path62.join(site, PAGES_DIR);
21260
+ const site = path64.resolve(siteDirectory);
21261
+ const pagesDir = path64.join(site, PAGES_DIR);
21143
21262
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
21144
21263
  if (directories.length === 0) {
21145
21264
  return {
@@ -21161,14 +21280,14 @@ async function discoverAndWireDocs(siteDirectory) {
21161
21280
  directory.sourceDirectory,
21162
21281
  usedNames
21163
21282
  );
21164
- const linkDirectory = path62.join(pagesDir, linkName);
21283
+ const linkDirectory = path64.join(pagesDir, linkName);
21165
21284
  const linked = [];
21166
21285
  const skipped = [];
21167
21286
  for (const sourcePath of directory.files) {
21168
21287
  const relativeSource = toPosix2(
21169
- path62.relative(directory.sourceDirectory, sourcePath)
21288
+ path64.relative(directory.sourceDirectory, sourcePath)
21170
21289
  );
21171
- const linkPath = path62.join(linkDirectory, relativeSource);
21290
+ const linkPath = path64.join(linkDirectory, relativeSource);
21172
21291
  const result = await linkMarkdownFile(sourcePath, linkPath);
21173
21292
  if (result === "skipped") {
21174
21293
  skipped.push({
@@ -21177,7 +21296,7 @@ async function discoverAndWireDocs(siteDirectory) {
21177
21296
  });
21178
21297
  continue;
21179
21298
  }
21180
- const relativeLink = toPosix2(path62.relative(site, linkPath));
21299
+ const relativeLink = toPosix2(path64.relative(site, linkPath));
21181
21300
  const route = toRoutePath(relativeLink, PAGES_DIR);
21182
21301
  linked.push({ sourcePath, linkPath, route, relativeSource });
21183
21302
  routes.push(route);
@@ -21210,11 +21329,11 @@ async function discoverAndWireDocs(siteDirectory) {
21210
21329
  };
21211
21330
  }
21212
21331
  function siteRelative(siteDirectory, filePath) {
21213
- const relative = toPosix2(path62.relative(siteDirectory, filePath));
21332
+ const relative = toPosix2(path64.relative(siteDirectory, filePath));
21214
21333
  if (!relative) {
21215
21334
  return ".";
21216
21335
  }
21217
- if (path62.isAbsolute(relative)) {
21336
+ if (path64.isAbsolute(relative)) {
21218
21337
  return toPosix2(filePath);
21219
21338
  }
21220
21339
  if (relative.startsWith("..")) {
@@ -21270,23 +21389,142 @@ function formatInitDiscoveryReport(siteDirectory, openApiDiscovery, docsDiscover
21270
21389
  ];
21271
21390
  }
21272
21391
 
21392
+ // src/cli/scaffold/run-scaffold-discovery.ts
21393
+ async function pathExists6(filePath) {
21394
+ try {
21395
+ await access10(filePath);
21396
+ return true;
21397
+ } catch {
21398
+ return false;
21399
+ }
21400
+ }
21401
+ async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
21402
+ const input3 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
21403
+ const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
21404
+ const raw = await readFile18(jsonConfigPath, "utf8");
21405
+ const siteConfig = JSON.parse(raw);
21406
+ const updated = applyOpenApiToSiteConfig(siteConfig, {
21407
+ input: input3,
21408
+ apiPath: "api"
21409
+ });
21410
+ const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
21411
+ updated.backend = { ...backend, openApiPath: input3 };
21412
+ await writeFile17(
21413
+ jsonConfigPath,
21414
+ `${JSON.stringify(updated, null, 2)}
21415
+ `,
21416
+ "utf8"
21417
+ );
21418
+ return { input: input3 };
21419
+ }
21420
+ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
21421
+ if (mode === "none") {
21422
+ return {
21423
+ openApiDiscovery: { status: "skipped", mode },
21424
+ wired: false
21425
+ };
21426
+ }
21427
+ const search = mode === "site" ? await collectSiteOpenApiFiles(siteDirectory) : await collectNearbyOpenApiFiles(siteDirectory);
21428
+ const invalidCandidates = [];
21429
+ let selected;
21430
+ for (const candidate of search.candidates) {
21431
+ const content = await readFile18(candidate, "utf8");
21432
+ const parsed = liteParseOpenApi(content, candidate);
21433
+ if (parsed.valid) {
21434
+ selected = {
21435
+ path: candidate,
21436
+ version: parsed.version,
21437
+ title: parsed.title
21438
+ };
21439
+ break;
21440
+ }
21441
+ invalidCandidates.push({ path: candidate, errors: parsed.errors });
21442
+ }
21443
+ if (!selected) {
21444
+ return {
21445
+ openApiDiscovery: {
21446
+ status: search.candidates.length > 0 ? "invalid" : "not_found",
21447
+ candidates: search.candidates,
21448
+ searchedDirectories: search.searchedDirectories,
21449
+ ...invalidCandidates.length > 0 ? { invalidCandidates } : {},
21450
+ suggestion: OPENAPI_NOT_FOUND_SUGGESTION
21451
+ },
21452
+ wired: false
21453
+ };
21454
+ }
21455
+ const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
21456
+ if (!await pathExists6(jsonConfigPath)) {
21457
+ return {
21458
+ openApiDiscovery: {
21459
+ status: "wire_failed",
21460
+ openApiPath: selected.path,
21461
+ error: "apitogo.config.json not found",
21462
+ candidates: search.candidates,
21463
+ searchedDirectories: search.searchedDirectories,
21464
+ suggestion: OPENAPI_NOT_FOUND_SUGGESTION
21465
+ },
21466
+ wired: false
21467
+ };
21468
+ }
21469
+ try {
21470
+ const { input: input3 } = await wireOpenApiIntoJsonConfig(
21471
+ siteDirectory,
21472
+ selected.path
21473
+ );
21474
+ return {
21475
+ openApiDiscovery: {
21476
+ status: "wired",
21477
+ openApiPath: selected.path,
21478
+ openApiInput: input3,
21479
+ openApiTitle: selected.title ?? null,
21480
+ openApiVersion: selected.version ?? null,
21481
+ apiReferencePath: "/api",
21482
+ candidates: search.candidates,
21483
+ searchedDirectories: search.searchedDirectories
21484
+ },
21485
+ wired: true
21486
+ };
21487
+ } catch (error) {
21488
+ return {
21489
+ openApiDiscovery: {
21490
+ status: "wire_failed",
21491
+ openApiPath: selected.path,
21492
+ error: error instanceof Error ? error.message : String(error),
21493
+ candidates: search.candidates,
21494
+ searchedDirectories: search.searchedDirectories,
21495
+ suggestion: OPENAPI_NOT_FOUND_SUGGESTION
21496
+ },
21497
+ wired: false
21498
+ };
21499
+ }
21500
+ }
21501
+ async function runScaffoldDiscovery(siteDirectory, options) {
21502
+ const openapiSearch = options?.openapiSearch ?? "nearby";
21503
+ const { openApiDiscovery } = await discoverAndWireOpenApiLite(
21504
+ siteDirectory,
21505
+ openapiSearch
21506
+ );
21507
+ const docsDiscovery = await discoverAndWireDocs(siteDirectory);
21508
+ return { openApiDiscovery, docsDiscovery };
21509
+ }
21510
+
21273
21511
  // src/cli/init/handler.ts
21274
21512
  function slugifyName2(name) {
21275
21513
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
21276
21514
  }
21277
21515
  function resolveInitOutputDirectory(dirArg, name) {
21278
- const resolved = path63.resolve(process.cwd(), dirArg);
21279
- const base = path63.basename(resolved);
21516
+ const resolved = path66.resolve(process.cwd(), dirArg);
21517
+ const base = path66.basename(resolved);
21280
21518
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
21281
21519
  if (isDot) {
21282
21520
  const fromName = name?.trim();
21283
21521
  if (!fromName) {
21284
21522
  throw new Error(
21285
- "apitogo init requires a named directory (e.g. apitogo init my-portal), or pass --name when using `.`."
21523
+ "apitogo init requires a named directory (e.g. apitogo init dev-portal), or pass --name when using `.`."
21286
21524
  );
21287
21525
  }
21288
21526
  return {
21289
- outputDirectory: path63.resolve(process.cwd(), slugifyName2(fromName)),
21527
+ outputDirectory: path66.resolve(process.cwd(), slugifyName2(fromName)),
21290
21528
  siteName: fromName
21291
21529
  };
21292
21530
  }
@@ -21331,11 +21569,10 @@ async function init2(argv) {
21331
21569
  }
21332
21570
  npmInstall = await runNpmInstall(result.outputDirectory);
21333
21571
  }
21334
- const { openApiDiscovery } = await discoverAndWireOpenApi(
21572
+ const { openApiDiscovery, docsDiscovery } = await runScaffoldDiscovery(
21335
21573
  result.outputDirectory,
21336
- openapiSearch
21574
+ { openapiSearch }
21337
21575
  );
21338
- const docsDiscovery = await discoverAndWireDocs(result.outputDirectory);
21339
21576
  const siteValidation = await validateDevPortalSiteConfig(
21340
21577
  result.outputDirectory
21341
21578
  );
@@ -21531,9 +21768,9 @@ var remove_default = {
21531
21768
  };
21532
21769
 
21533
21770
  // src/cli/status/handler.ts
21534
- import path64 from "node:path";
21771
+ import path67 from "node:path";
21535
21772
  async function status(argv) {
21536
- const sourceDirectory = path64.resolve(process.cwd(), argv.dir);
21773
+ const sourceDirectory = path67.resolve(process.cwd(), argv.dir);
21537
21774
  const config2 = loadConfig();
21538
21775
  const client = new PlatformApiClient(config2);
21539
21776
  let whoamiJson;
@@ -21613,7 +21850,7 @@ var status_default = {
21613
21850
  };
21614
21851
 
21615
21852
  // src/cli/teardown/handler.ts
21616
- import path65 from "node:path";
21853
+ import path68 from "node:path";
21617
21854
  function resultLooksFailed3(payload) {
21618
21855
  try {
21619
21856
  const parsed = JSON.parse(payload);
@@ -21629,7 +21866,7 @@ async function teardown(argv) {
21629
21866
  );
21630
21867
  return;
21631
21868
  }
21632
- const sourceDirectory = path65.resolve(process.cwd(), argv.dir);
21869
+ const sourceDirectory = path68.resolve(process.cwd(), argv.dir);
21633
21870
  const config2 = loadConfig();
21634
21871
  const client = new PlatformApiClient(config2);
21635
21872
  let projectId = argv.projectId?.trim();
@@ -21695,7 +21932,7 @@ var teardown_default = {
21695
21932
 
21696
21933
  // src/cli/common/outdated.ts
21697
21934
  import { existsSync as existsSync4, mkdirSync } from "node:fs";
21698
- import { readFile as readFile18, writeFile as writeFile17 } from "node:fs/promises";
21935
+ import { readFile as readFile19, writeFile as writeFile18 } from "node:fs/promises";
21699
21936
  import { join } from "node:path";
21700
21937
  import colors10 from "picocolors";
21701
21938
  import { gt } from "semver";
@@ -21762,12 +21999,12 @@ function box(message, {
21762
21999
 
21763
22000
  // src/cli/common/xdg/lib.ts
21764
22001
  import { homedir } from "node:os";
21765
- import path66 from "node:path";
22002
+ import path69 from "node:path";
21766
22003
  function defineDirectoryWithFallback(xdgName, fallback) {
21767
22004
  if (process.env[xdgName]) {
21768
22005
  return process.env[xdgName];
21769
22006
  } else {
21770
- return path66.join(homedir(), fallback);
22007
+ return path69.join(homedir(), fallback);
21771
22008
  }
21772
22009
  }
21773
22010
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -21782,15 +22019,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
21782
22019
  "XDG_DATA_HOME",
21783
22020
  ".local/state"
21784
22021
  );
21785
- var ZUDOKU_XDG_CONFIG_HOME = path66.join(
22022
+ var ZUDOKU_XDG_CONFIG_HOME = path69.join(
21786
22023
  XDG_CONFIG_HOME,
21787
22024
  CLI_XDG_FOLDER_NAME
21788
22025
  );
21789
- var ZUDOKU_XDG_DATA_HOME = path66.join(
22026
+ var ZUDOKU_XDG_DATA_HOME = path69.join(
21790
22027
  XDG_DATA_HOME,
21791
22028
  CLI_XDG_FOLDER_NAME
21792
22029
  );
21793
- var ZUDOKU_XDG_STATE_HOME = path66.join(
22030
+ var ZUDOKU_XDG_STATE_HOME = path69.join(
21794
22031
  XDG_STATE_HOME,
21795
22032
  CLI_XDG_FOLDER_NAME
21796
22033
  );
@@ -21842,7 +22079,7 @@ async function getVersionCheckInfo() {
21842
22079
  let versionCheckInfo;
21843
22080
  if (existsSync4(versionCheckPath)) {
21844
22081
  try {
21845
- versionCheckInfo = await readFile18(versionCheckPath, "utf-8").then(
22082
+ versionCheckInfo = await readFile19(versionCheckPath, "utf-8").then(
21846
22083
  JSON.parse
21847
22084
  );
21848
22085
  } catch {
@@ -21867,7 +22104,7 @@ async function getVersionCheckInfo() {
21867
22104
  lastCheck: Date.now(),
21868
22105
  latestVersion
21869
22106
  };
21870
- await writeFile17(
22107
+ await writeFile18(
21871
22108
  versionCheckPath,
21872
22109
  JSON.stringify(versionCheckInfo),
21873
22110
  "utf-8"