@lukoweb/apitogo 0.1.101 → 0.1.103

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
@@ -8,23 +8,6 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // src/cli/common/package-json.ts
12
- import { readFileSync } from "node:fs";
13
- import path from "node:path";
14
- import { fileURLToPath } from "node:url";
15
- var getPackageJsonPath, getPackageJson, getZudokuPackageJson, getZudokuRootDir;
16
- var init_package_json = __esm({
17
- "src/cli/common/package-json.ts"() {
18
- getPackageJsonPath = (pkg) => fileURLToPath(import.meta.resolve(`${pkg}/package.json`)).replaceAll(
19
- path.sep,
20
- path.posix.sep
21
- );
22
- getPackageJson = (pkgPath) => JSON.parse(readFileSync(pkgPath, "utf-8"));
23
- getZudokuPackageJson = () => getPackageJson(getPackageJsonPath("@lukoweb/apitogo"));
24
- getZudokuRootDir = () => path.dirname(getPackageJsonPath("@lukoweb/apitogo"));
25
- }
26
- });
27
-
28
11
  // src/cli/common/logger.ts
29
12
  import { createLogger } from "vite";
30
13
  var logger, loggerError, isExpectedWarning, wrapWarnFilter;
@@ -52,6 +35,23 @@ var init_logger = __esm({
52
35
  }
53
36
  });
54
37
 
38
+ // src/cli/common/package-json.ts
39
+ import { readFileSync } from "node:fs";
40
+ import path2 from "node:path";
41
+ import { fileURLToPath } from "node:url";
42
+ var getPackageJsonPath, getPackageJson, getZudokuPackageJson, getZudokuRootDir;
43
+ var init_package_json = __esm({
44
+ "src/cli/common/package-json.ts"() {
45
+ getPackageJsonPath = (pkg) => fileURLToPath(import.meta.resolve(`${pkg}/package.json`)).replaceAll(
46
+ path2.sep,
47
+ path2.posix.sep
48
+ );
49
+ getPackageJson = (pkgPath) => JSON.parse(readFileSync(pkgPath, "utf-8"));
50
+ getZudokuPackageJson = () => getPackageJson(getPackageJsonPath("@lukoweb/apitogo"));
51
+ getZudokuRootDir = () => path2.dirname(getPackageJsonPath("@lukoweb/apitogo"));
52
+ }
53
+ });
54
+
55
55
  // src/lib/authentication/auth-header-nav.ts
56
56
  function withoutLoginNavigation(navigation) {
57
57
  return navigation.filter(
@@ -751,13 +751,13 @@ var init_apitogo_config_core = __esm({
751
751
  });
752
752
 
753
753
  // src/config/apitogo-config-loader.node.ts
754
- import { existsSync, readFileSync as readFileSync2 } from "node:fs";
755
- import path2 from "node:path";
754
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
755
+ import path3 from "node:path";
756
756
  function loadApitogoConfig(rootDir = process.cwd()) {
757
- const configPath = path2.join(path2.resolve(rootDir), APITOGO_CONFIG_FILENAME);
758
- if (!existsSync(configPath)) {
757
+ const configPath = path3.join(path3.resolve(rootDir), APITOGO_CONFIG_FILENAME);
758
+ if (!existsSync2(configPath)) {
759
759
  throw new Error(
760
- `Missing ${APITOGO_CONFIG_FILENAME} in ${path2.resolve(rootDir)}`
760
+ `Missing ${APITOGO_CONFIG_FILENAME} in ${path3.resolve(rootDir)}`
761
761
  );
762
762
  }
763
763
  const raw = readFileSync2(configPath, "utf8");
@@ -1086,7 +1086,7 @@ var init_landing_manifest = __esm({
1086
1086
  });
1087
1087
 
1088
1088
  // src/config/local-manifest.ts
1089
- import path3 from "node:path";
1089
+ import path4 from "node:path";
1090
1090
  import { z as z4 } from "zod";
1091
1091
  function isPricingEnabled(manifest) {
1092
1092
  return manifest?.pricing?.enabled === true;
@@ -1137,8 +1137,8 @@ function resolveManifestEnv(viteMode) {
1137
1137
  return viteMode === "production" ? "production" : "development";
1138
1138
  }
1139
1139
  function manifestPathsForEnv(rootDir, _env) {
1140
- const resolvedRoot = path3.resolve(rootDir);
1141
- const configPath = path3.join(resolvedRoot, APITOGO_CONFIG_FILENAME);
1140
+ const resolvedRoot = path4.resolve(rootDir);
1141
+ const configPath = path4.join(resolvedRoot, APITOGO_CONFIG_FILENAME);
1142
1142
  return {
1143
1143
  basePath: configPath,
1144
1144
  overridePath: configPath,
@@ -1829,7 +1829,7 @@ var init_shadcn_registry = __esm({
1829
1829
 
1830
1830
  // src/vite/plugin-theme.ts
1831
1831
  import { createRequire } from "node:module";
1832
- import path4 from "node:path";
1832
+ import path5 from "node:path";
1833
1833
  import { normalizeTheme } from "shiki";
1834
1834
  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;
1835
1835
  var init_plugin_theme = __esm({
@@ -2008,7 +2008,7 @@ var init_plugin_theme = __esm({
2008
2008
  resolveModuleSourceDirs = (config2) => {
2009
2009
  if (config2.__meta.mode === "internal") {
2010
2010
  return MODULE_SOURCE_PACKAGES.map(
2011
- (pkg) => path4.join(
2011
+ (pkg) => path5.join(
2012
2012
  config2.__meta.moduleDir,
2013
2013
  "..",
2014
2014
  pkg.replace("@lukoweb/apitogo-", ""),
@@ -2017,12 +2017,12 @@ var init_plugin_theme = __esm({
2017
2017
  );
2018
2018
  }
2019
2019
  const require2 = createRequire(
2020
- path4.join(config2.__meta.rootDir, "package.json")
2020
+ path5.join(config2.__meta.rootDir, "package.json")
2021
2021
  );
2022
2022
  const dirs = [];
2023
2023
  for (const pkg of MODULE_SOURCE_PACKAGES) {
2024
2024
  try {
2025
- dirs.push(path4.dirname(require2.resolve(pkg)));
2025
+ dirs.push(path5.dirname(require2.resolve(pkg)));
2026
2026
  } catch {
2027
2027
  }
2028
2028
  }
@@ -2148,7 +2148,7 @@ ${rootVars.join("\n")}
2148
2148
  ...config2.__meta.dependencies,
2149
2149
  ...config2.__pluginDirs ?? [],
2150
2150
  ...resolveModuleSourceDirs(config2)
2151
- ].map((file) => path4.relative(path4.dirname(id), file))
2151
+ ].map((file) => path5.relative(path5.dirname(id), file))
2152
2152
  );
2153
2153
  const code = [...files].map((file) => `@source "${file}";`);
2154
2154
  code.push("@theme inline {");
@@ -4439,7 +4439,7 @@ __export(ZudokuConfig_exports, {
4439
4439
  ZudokuConfig: () => ZudokuConfig,
4440
4440
  validateConfig: () => validateConfig
4441
4441
  });
4442
- import colors from "picocolors";
4442
+ import colors4 from "picocolors";
4443
4443
  import { isValidElement as isValidElement2 } from "react";
4444
4444
  import { z as z9 } from "zod";
4445
4445
  function validateConfig(config2, configPath) {
@@ -4451,8 +4451,8 @@ function validateConfig(config2, configPath) {
4451
4451
  ${z9.prettifyError(validationResult.error)}`
4452
4452
  );
4453
4453
  }
4454
- console.log(colors.yellow("Validation errors:"));
4455
- console.log(colors.yellow(z9.prettifyError(validationResult.error)));
4454
+ console.log(colors4.yellow("Validation errors:"));
4455
+ console.log(colors4.yellow(z9.prettifyError(validationResult.error)));
4456
4456
  }
4457
4457
  }
4458
4458
  var ThemeSchema, ApiCatalogCategorySchema, LanguageOption, AiAssistantCustomSchema, AiAssistantPresets, AiAssistantsSchema, ApiOptionsSchema, ApiConfigSchema, VersionConfigSchema, ApiSchema, ApiKeysSchema, LogoSchema, FooterSocialIcons, FooterSocialSchema, FooterSchema, SiteMapSchema, DEFAULT_DOCS_FILES, LlmsConfigSchema, DocsConfigSchema, Redirect, SearchSchema, AuthenticationSchema, MetadataSchema, FontConfigSchema, FontsConfigSchema, CssObject, ThemeConfigSchema, SiteSchema, PlacementPosition, HeaderConfigSchema, ApiCatalogSchema, CdnUrlSchema, BaseConfigSchema, ZudokuConfig;
@@ -4990,8 +4990,8 @@ var init_ZudokuConfig = __esm({
4990
4990
 
4991
4991
  // src/config/loader.ts
4992
4992
  import { stat as stat2 } from "node:fs/promises";
4993
- import path5 from "node:path";
4994
- import colors2 from "picocolors";
4993
+ import path6 from "node:path";
4994
+ import colors5 from "picocolors";
4995
4995
  import {
4996
4996
  runnerImport,
4997
4997
  loadEnv as viteLoadEnv
@@ -5017,7 +5017,7 @@ function mergeJsonConfigWithRuntimeOverrides(fileConfig, importedConfig) {
5017
5017
  }
5018
5018
  async function getConfigFilePath(rootDir) {
5019
5019
  for (const fileName of zudokuConfigFiles) {
5020
- const filepath = path5.join(rootDir, fileName);
5020
+ const filepath = path6.join(rootDir, fileName);
5021
5021
  if (await fileExists(filepath)) {
5022
5022
  return filepath;
5023
5023
  }
@@ -5181,7 +5181,7 @@ async function loadZudokuConfig(configEnv, rootDir) {
5181
5181
  };
5182
5182
  if (!process.env.APITOGO_JSON_ONLY) {
5183
5183
  logger.info(
5184
- colors2.cyan(`loaded config file `) + colors2.dim(config.__meta.configPath),
5184
+ colors5.cyan(`loaded config file `) + colors5.dim(config.__meta.configPath),
5185
5185
  { timestamp: true }
5186
5186
  );
5187
5187
  }
@@ -5249,9 +5249,9 @@ var llms_exports = {};
5249
5249
  __export(llms_exports, {
5250
5250
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
5251
5251
  });
5252
- import { writeFile as writeFile4 } from "node:fs/promises";
5253
- import path28 from "node:path";
5254
- import colors6 from "picocolors";
5252
+ import { writeFile as writeFile5 } from "node:fs/promises";
5253
+ import path29 from "node:path";
5254
+ import colors9 from "picocolors";
5255
5255
  async function generateLlmsTxtFiles({
5256
5256
  markdownFileInfos,
5257
5257
  outputUrls,
@@ -5284,61 +5284,377 @@ async function generateLlmsTxtFiles({
5284
5284
  llmsTxtParts.push(`- [${linkTitle}](${mdUrl})${description}`);
5285
5285
  }
5286
5286
  }
5287
- const llmsTxt2 = llmsTxtParts.join("\n");
5288
- await writeFile4(path28.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5289
- if (process.env.APITOGO_JSON_ONLY !== "1") {
5290
- console.log(colors6.blue("\u2713 generated llms.txt"));
5287
+ const llmsTxt2 = llmsTxtParts.join("\n");
5288
+ await writeFile5(path29.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5289
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
5290
+ console.log(colors9.blue("\u2713 generated llms.txt"));
5291
+ }
5292
+ }
5293
+ if (llmsTxtFull) {
5294
+ const llmsFullParts = [];
5295
+ llmsFullParts.push(`# ${title}
5296
+ `);
5297
+ llmsFullParts.push("> Complete documentation for Large Language Models\n");
5298
+ for (const info of markdownFileInfos) {
5299
+ llmsFullParts.push(`
5300
+ ---
5301
+ `);
5302
+ llmsFullParts.push(`## Document: ${info.title ?? info.routePath}
5303
+ `);
5304
+ if (info.description) {
5305
+ llmsFullParts.push(`${info.description}
5306
+ `);
5307
+ }
5308
+ llmsFullParts.push(`URL: ${joinUrl(baseUrl, info.routePath)}
5309
+ `);
5310
+ llmsFullParts.push(`
5311
+ ${info.content}
5312
+ `);
5313
+ }
5314
+ const llmsFull = llmsFullParts.join("\n");
5315
+ await writeFile5(
5316
+ path29.join(baseOutputDir, "llms-full.txt"),
5317
+ llmsFull,
5318
+ "utf-8"
5319
+ );
5320
+ if (process.env.APITOGO_JSON_ONLY !== "1") {
5321
+ console.log(colors9.blue("\u2713 generated llms-full.txt"));
5322
+ }
5323
+ }
5324
+ }
5325
+ var init_llms = __esm({
5326
+ "src/vite/llms.ts"() {
5327
+ init_joinUrl();
5328
+ }
5329
+ });
5330
+
5331
+ // src/cli/cli.ts
5332
+ import * as Sentry2 from "@sentry/node";
5333
+ import { hideBin } from "yargs/helpers";
5334
+
5335
+ // src/cli/common/analytics/lib.ts
5336
+ import { PostHog } from "posthog-node";
5337
+
5338
+ // src/cli/common/constants.ts
5339
+ var CLI_XDG_FOLDER_NAME = "apitogo";
5340
+ var VERSION_CHECK_FILE = "version.json";
5341
+ var SENTRY_DSN = void 0;
5342
+ var MAX_WAIT_PENDING_TIME_MS = 1e3;
5343
+ var POST_HOG_CAPTURE_KEY = void 0;
5344
+
5345
+ // src/cli/common/machine-id/lib.ts
5346
+ import { execSync } from "node:child_process";
5347
+ import { createHash } from "node:crypto";
5348
+ var win32RegBinPath = {
5349
+ skipped: "",
5350
+ native: "%windir%\\System32",
5351
+ mixed: "%windir%\\sysnative\\cmd.exe /c %windir%\\System32"
5352
+ };
5353
+ var guid = {
5354
+ darwin: "ioreg -rd1 -c IOPlatformExpertDevice",
5355
+ win32: `${win32RegBinPath[isWindowsProcessMixedOrNativeArchitecture()]}\\REG.exe QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid`,
5356
+ linux: "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :"
5357
+ };
5358
+ function isWindowsProcessMixedOrNativeArchitecture() {
5359
+ if (process.platform !== "win32") {
5360
+ return "skipped";
5361
+ }
5362
+ if (process.arch === "ia32" && process.env.PROCESSOR_ARCHITEW6432) {
5363
+ return "mixed";
5364
+ }
5365
+ return "native";
5366
+ }
5367
+ function hash(guid2) {
5368
+ return createHash("sha256").update(guid2).digest("hex");
5369
+ }
5370
+ function expose(result) {
5371
+ switch (process.platform) {
5372
+ case "darwin":
5373
+ return result.split("IOPlatformUUID")[1].split("\n")[0].replace(/=|\s+]"/gi, "").toLowerCase();
5374
+ case "win32":
5375
+ return result.toString().split("REG_SZ")[1].replace(/\r+|\n+|\s+/gi, "").toLowerCase();
5376
+ case "linux":
5377
+ return result.toString().replace(/\r+|\n+|\s+/gi, "").toLowerCase();
5378
+ case "freebsd":
5379
+ return result.toString().replace(/\r+|\n+|\s+/gi, "").toLowerCase();
5380
+ default:
5381
+ throw new Error(`Unsupported platform: ${process.platform}`);
5382
+ }
5383
+ }
5384
+ function machineId() {
5385
+ switch (process.platform) {
5386
+ case "darwin":
5387
+ case "win32":
5388
+ case "linux":
5389
+ return hash(expose(execSync(guid[process.platform]).toString()));
5390
+ default:
5391
+ return "e16fc483-5593-4d71-b485-a6533693da9b";
5392
+ }
5393
+ }
5394
+
5395
+ // src/cli/common/analytics/lib.ts
5396
+ var _postHog;
5397
+ function init() {
5398
+ if (process.env.ZUDOKU_DO_NOT_TRACK || !POST_HOG_CAPTURE_KEY) {
5399
+ return void 0;
5400
+ }
5401
+ _postHog = new PostHog(POST_HOG_CAPTURE_KEY, {
5402
+ host: "https://app.posthog.com",
5403
+ flushAt: 1,
5404
+ flushInterval: 1
5405
+ });
5406
+ return _postHog;
5407
+ }
5408
+ async function captureEvent({
5409
+ event,
5410
+ properties,
5411
+ groups,
5412
+ sendFeatureFlags,
5413
+ timestamp,
5414
+ disableGeoip
5415
+ }) {
5416
+ if (_postHog === void 0) {
5417
+ init();
5418
+ }
5419
+ if (_postHog) {
5420
+ properties = properties ?? {};
5421
+ properties.$set_once = properties.$set_once ?? {};
5422
+ if (process.env.CI) {
5423
+ properties.ci = process.env.CI;
5424
+ }
5425
+ _postHog.capture({
5426
+ distinctId: machineId(),
5427
+ event,
5428
+ properties,
5429
+ groups,
5430
+ sendFeatureFlags,
5431
+ timestamp,
5432
+ disableGeoip
5433
+ });
5434
+ }
5435
+ }
5436
+ async function shutdownAnalytics() {
5437
+ return _postHog?.shutdown();
5438
+ }
5439
+
5440
+ // src/cli/common/outdated.ts
5441
+ import { existsSync, mkdirSync } from "node:fs";
5442
+ import { readFile, writeFile } from "node:fs/promises";
5443
+ import { join } from "node:path";
5444
+ import colors3 from "picocolors";
5445
+ import { gt } from "semver";
5446
+
5447
+ // src/cli/common/json-only-deploy.ts
5448
+ function isDeployJsonOnlyArgv() {
5449
+ const args = process.argv;
5450
+ let cmdIdx = -1;
5451
+ for (const cmd of ["deploy", "remove"]) {
5452
+ const i = args.indexOf(cmd);
5453
+ if (i !== -1) {
5454
+ cmdIdx = i;
5455
+ break;
5456
+ }
5457
+ }
5458
+ if (cmdIdx === -1) {
5459
+ return false;
5460
+ }
5461
+ return args.slice(cmdIdx).some((a) => a === "--json-only" || a.startsWith("--json-only="));
5462
+ }
5463
+
5464
+ // src/cli/common/output.ts
5465
+ import * as Sentry from "@sentry/node";
5466
+ import colors from "picocolors";
5467
+ function printDiagnosticsToConsole(message) {
5468
+ console.error(colors.bold(colors.blue(message)));
5469
+ }
5470
+ function printWarningToConsole(message) {
5471
+ console.error(message);
5472
+ }
5473
+ async function printCriticalFailureToConsoleAndExit(message) {
5474
+ console.error(colors.bold(colors.red(message)));
5475
+ await Sentry.close(MAX_WAIT_PENDING_TIME_MS).then(() => {
5476
+ process.exit(1);
5477
+ });
5478
+ }
5479
+ function printJsonOnlyErrorAndExit(message) {
5480
+ console.log(JSON.stringify({ error: message }));
5481
+ process.exit(1);
5482
+ }
5483
+ function printResultToConsole(message) {
5484
+ console.log(colors.bold(colors.green(message)));
5485
+ }
5486
+
5487
+ // src/cli/common/utils/box.ts
5488
+ import colors2 from "picocolors";
5489
+ import stripAnsi from "strip-ansi";
5490
+ var border = ["\u2500", "\u256D", "\u256E", "\u2502", "\u2502", "\u2570", "\u256F"];
5491
+ var nothing = ["\u2500", "", "", "", "", "", ""];
5492
+ function box(message, {
5493
+ borderColor,
5494
+ padding = 1,
5495
+ textAlignment = "center",
5496
+ terminalColumns: cols = process.stdout.columns || process.env.COLUMNS && parseInt(process.env.COLUMNS, 10) || 80
5497
+ } = {}) {
5498
+ const lines = message.split(/\r?\n/).map((line) => [line, stripAnsi(line).length]);
5499
+ const maxLine = lines.reduce((p, [, len]) => Math.max(p, len), 0);
5500
+ const borderColorFn = borderColor && colors2[borderColor] || colors2.yellow;
5501
+ const clampedSidePadding = Math.max(1, padding * 3);
5502
+ const narrowMode = maxLine + 2 + clampedSidePadding * 2 > cols;
5503
+ const sidePadding = narrowMode ? 0 : clampedSidePadding;
5504
+ const innerWidth = Math.min(maxLine + sidePadding * 2, cols);
5505
+ const [hr, topLeft, topRight, left, right, bottomLeft, bottomRight] = narrowMode ? nothing : border;
5506
+ const spacerRow = narrowMode ? "\n".repeat(padding) : `${borderColorFn(`${left}${" ".repeat(innerWidth)}${right}`)}
5507
+ `.repeat(
5508
+ padding
5509
+ );
5510
+ const renderLine = ([line, len]) => {
5511
+ let leftPadding = 0;
5512
+ let rightPadding = 0;
5513
+ if (!narrowMode) {
5514
+ leftPadding = sidePadding;
5515
+ rightPadding = sidePadding;
5516
+ if (textAlignment === "center") {
5517
+ leftPadding += Math.floor((maxLine - len) / 2);
5518
+ rightPadding += maxLine - len - leftPadding + sidePadding;
5519
+ } else if (textAlignment === "right") {
5520
+ leftPadding += maxLine - len;
5521
+ } else if (textAlignment === "left") {
5522
+ rightPadding += maxLine - len;
5523
+ }
5524
+ }
5525
+ return borderColorFn(left) + " ".repeat(leftPadding) + line + " ".repeat(rightPadding) + borderColorFn(right);
5526
+ };
5527
+ return borderColorFn(`${topLeft}${hr?.repeat(innerWidth)}${topRight}`) + "\n" + spacerRow + lines.map(renderLine).join("\n") + "\n" + spacerRow + borderColorFn(`${bottomLeft}${hr?.repeat(innerWidth)}${bottomRight}`);
5528
+ }
5529
+
5530
+ // src/cli/common/xdg/lib.ts
5531
+ import { homedir } from "node:os";
5532
+ import path from "node:path";
5533
+ function defineDirectoryWithFallback(xdgName, fallback) {
5534
+ if (process.env[xdgName]) {
5535
+ return process.env[xdgName];
5536
+ } else {
5537
+ return path.join(homedir(), fallback);
5538
+ }
5539
+ }
5540
+ var XDG_CONFIG_HOME = defineDirectoryWithFallback(
5541
+ "XDG_CONFIG_HOME",
5542
+ ".config"
5543
+ );
5544
+ var XDG_DATA_HOME = defineDirectoryWithFallback(
5545
+ "XDG_DATA_HOME",
5546
+ ".local/share"
5547
+ );
5548
+ var XDG_STATE_HOME = defineDirectoryWithFallback(
5549
+ "XDG_DATA_HOME",
5550
+ ".local/state"
5551
+ );
5552
+ var ZUDOKU_XDG_CONFIG_HOME = path.join(
5553
+ XDG_CONFIG_HOME,
5554
+ CLI_XDG_FOLDER_NAME
5555
+ );
5556
+ var ZUDOKU_XDG_DATA_HOME = path.join(
5557
+ XDG_DATA_HOME,
5558
+ CLI_XDG_FOLDER_NAME
5559
+ );
5560
+ var ZUDOKU_XDG_STATE_HOME = path.join(
5561
+ XDG_STATE_HOME,
5562
+ CLI_XDG_FOLDER_NAME
5563
+ );
5564
+
5565
+ // src/cli/common/outdated.ts
5566
+ async function warnIfOutdatedVersion(currentVersion) {
5567
+ if (isDeployJsonOnlyArgv()) {
5568
+ return false;
5569
+ }
5570
+ if (!process.env.ZUDOKU_OVERRIDE_CI_TO_TEST && (process.env.CI || process.env.ZUDOKU_DISABLE_UPDATE_CHECK)) {
5571
+ return false;
5572
+ }
5573
+ const versionCheckInfo = await getVersionCheckInfo();
5574
+ if (!versionCheckInfo.latestVersion) {
5575
+ return false;
5576
+ }
5577
+ const shouldWarn = gt(versionCheckInfo.latestVersion, currentVersion) && !process.env.ZUDOKU_INTERNAL_DEV;
5578
+ if (shouldWarn) {
5579
+ printWarningToConsole(
5580
+ box(
5581
+ `Update available! ${colors3.gray(`v${currentVersion}`)} \u226B ${colors3.green(
5582
+ `v${versionCheckInfo.latestVersion}`
5583
+ )}
5584
+ Run ${colors3.cyan("npm install apitogo@latest")} to update.
5585
+
5586
+ ${colors3.gray("Upgrade to receive the latest features and fixes.")}`
5587
+ )
5588
+ );
5589
+ }
5590
+ return shouldWarn;
5591
+ }
5592
+ async function getLatestVersion() {
5593
+ const response = await fetch(
5594
+ "https://api.github.com/repos/lukoweb/apitogo-doc-tool/releases?per_page=1"
5595
+ );
5596
+ if (response.status === 200) {
5597
+ const result = await response.json();
5598
+ if (Array.isArray(result) && result.length > 0) {
5599
+ return result[0].tag_name.substring(1);
5600
+ }
5601
+ }
5602
+ return void 0;
5603
+ }
5604
+ async function getVersionCheckInfo() {
5605
+ if (!existsSync(ZUDOKU_XDG_STATE_HOME)) {
5606
+ mkdirSync(ZUDOKU_XDG_STATE_HOME, { recursive: true });
5607
+ }
5608
+ const versionCheckPath = join(ZUDOKU_XDG_STATE_HOME, VERSION_CHECK_FILE);
5609
+ let versionCheckInfo;
5610
+ if (existsSync(versionCheckPath)) {
5611
+ try {
5612
+ versionCheckInfo = await readFile(versionCheckPath, "utf-8").then(
5613
+ JSON.parse
5614
+ );
5615
+ } catch {
5616
+ }
5617
+ if (versionCheckInfo) {
5618
+ if (typeof versionCheckInfo.lastCheck !== "number" || typeof versionCheckInfo.latestVersion !== "string") {
5619
+ versionCheckInfo = void 0;
5620
+ }
5291
5621
  }
5292
5622
  }
5293
- if (llmsTxtFull) {
5294
- const llmsFullParts = [];
5295
- llmsFullParts.push(`# ${title}
5296
- `);
5297
- llmsFullParts.push("> Complete documentation for Large Language Models\n");
5298
- for (const info of markdownFileInfos) {
5299
- llmsFullParts.push(`
5300
- ---
5301
- `);
5302
- llmsFullParts.push(`## Document: ${info.title ?? info.routePath}
5303
- `);
5304
- if (info.description) {
5305
- llmsFullParts.push(`${info.description}
5306
- `);
5307
- }
5308
- llmsFullParts.push(`URL: ${joinUrl(baseUrl, info.routePath)}
5309
- `);
5310
- llmsFullParts.push(`
5311
- ${info.content}
5312
- `);
5623
+ let shouldCheck = true;
5624
+ if (versionCheckInfo) {
5625
+ const now = Date.now();
5626
+ const lastCheck = versionCheckInfo.lastCheck;
5627
+ if (now - lastCheck < 1e3 * 60 * 60 * 24) {
5628
+ shouldCheck = false;
5313
5629
  }
5314
- const llmsFull = llmsFullParts.join("\n");
5315
- await writeFile4(
5316
- path28.join(baseOutputDir, "llms-full.txt"),
5317
- llmsFull,
5630
+ }
5631
+ if (!versionCheckInfo || shouldCheck) {
5632
+ const latestVersion = await getLatestVersion();
5633
+ versionCheckInfo = {
5634
+ lastCheck: Date.now(),
5635
+ latestVersion
5636
+ };
5637
+ await writeFile(
5638
+ versionCheckPath,
5639
+ JSON.stringify(versionCheckInfo),
5318
5640
  "utf-8"
5319
5641
  );
5320
- if (process.env.APITOGO_JSON_ONLY !== "1") {
5321
- console.log(colors6.blue("\u2713 generated llms-full.txt"));
5322
- }
5323
5642
  }
5643
+ return versionCheckInfo;
5324
5644
  }
5325
- var init_llms = __esm({
5326
- "src/vite/llms.ts"() {
5327
- init_joinUrl();
5328
- }
5329
- });
5330
5645
 
5331
5646
  // src/cli/cli.ts
5332
- import * as Sentry2 from "@sentry/node";
5333
- import { hideBin } from "yargs/helpers";
5647
+ init_package_json();
5648
+
5649
+ // src/cli/create-cli.ts
5334
5650
  import yargs from "yargs/yargs";
5335
5651
 
5336
5652
  // src/cli/build/handler.ts
5337
- import path32 from "node:path";
5653
+ import path33 from "node:path";
5338
5654
 
5339
5655
  // src/vite/build.ts
5340
- import { mkdir as mkdir5, readFile as readFile3, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
5341
- import path30 from "node:path";
5656
+ import { mkdir as mkdir5, readFile as readFile4, rename, rm as rm2, writeFile as writeFile6 } from "node:fs/promises";
5657
+ import path31 from "node:path";
5342
5658
  import { build as esbuild } from "esbuild";
5343
5659
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
5344
5660
 
@@ -5474,9 +5790,9 @@ init_invariant();
5474
5790
  init_joinUrl();
5475
5791
 
5476
5792
  // src/vite/config.ts
5477
- import path25 from "node:path";
5793
+ import path26 from "node:path";
5478
5794
  import dotenv from "dotenv";
5479
- import colors4 from "picocolors";
5795
+ import colors7 from "picocolors";
5480
5796
  import {
5481
5797
  loadConfigFromFile,
5482
5798
  mergeConfig as mergeConfig2
@@ -5485,7 +5801,7 @@ import {
5485
5801
  // package.json
5486
5802
  var package_default = {
5487
5803
  name: "@lukoweb/apitogo",
5488
- version: "0.1.101",
5804
+ version: "0.1.103",
5489
5805
  type: "module",
5490
5806
  sideEffects: [
5491
5807
  "**/*.css",
@@ -5508,8 +5824,8 @@ var package_default = {
5508
5824
  "docs"
5509
5825
  ],
5510
5826
  bin: {
5511
- zudoku: "./cli.js",
5512
- apitogo: "./cli.js"
5827
+ apitogo: "./cli.js",
5828
+ zudoku: "./cli.js"
5513
5829
  },
5514
5830
  exports: {
5515
5831
  ".": "./src/index.ts",
@@ -5915,24 +6231,24 @@ async function loadDevPortalViteDefines(rootDir, mode) {
5915
6231
 
5916
6232
  // src/vite/package-root.ts
5917
6233
  init_file_exists();
5918
- import path6 from "node:path";
6234
+ import path7 from "node:path";
5919
6235
  var findPackageRoot = async (startDir) => {
5920
6236
  let dir = startDir;
5921
- while (dir !== path6.dirname(dir)) {
5922
- if (await fileExists(path6.join(dir, "package.json"))) return dir;
5923
- dir = path6.dirname(dir);
6237
+ while (dir !== path7.dirname(dir)) {
6238
+ if (await fileExists(path7.join(dir, "package.json"))) return dir;
6239
+ dir = path7.dirname(dir);
5924
6240
  }
5925
6241
  };
5926
6242
 
5927
6243
  // src/vite/pagefind-dev-stub.ts
5928
6244
  import fs from "node:fs/promises";
5929
- import path7 from "node:path";
6245
+ import path8 from "node:path";
5930
6246
  var NOT_BUILT_YET = 'throw new Error("NOT_BUILT_YET");';
5931
6247
  async function ensurePagefindDevStub(publicDir) {
5932
- const pagefindPath = path7.join(publicDir, "pagefind/pagefind.js");
6248
+ const pagefindPath = path8.join(publicDir, "pagefind/pagefind.js");
5933
6249
  const exists = await fs.stat(pagefindPath).catch(() => false);
5934
6250
  if (!exists) {
5935
- await fs.mkdir(path7.dirname(pagefindPath), { recursive: true });
6251
+ await fs.mkdir(path8.dirname(pagefindPath), { recursive: true });
5936
6252
  await fs.writeFile(pagefindPath, NOT_BUILT_YET);
5937
6253
  }
5938
6254
  }
@@ -5944,7 +6260,7 @@ import react from "@vitejs/plugin-react";
5944
6260
  // src/vite/css/plugin.ts
5945
6261
  init_loader();
5946
6262
  init_plugin_theme();
5947
- import path8 from "node:path";
6263
+ import path9 from "node:path";
5948
6264
  import { isCSSRequest as isCSSRequest2 } from "vite";
5949
6265
 
5950
6266
  // src/vite/css/collect.ts
@@ -5979,7 +6295,7 @@ var VIRTUAL_ENTRY = "virtual:ssr-css.css";
5979
6295
  function vitePluginSsrCss(pluginOpts) {
5980
6296
  let server;
5981
6297
  const config2 = getCurrentConfig();
5982
- const virtualHref = path8.join(
6298
+ const virtualHref = path9.join(
5983
6299
  config2.basePath ?? "",
5984
6300
  `/@id/__x00__${VIRTUAL_ENTRY}?direct`
5985
6301
  );
@@ -6116,7 +6432,7 @@ var plugin_api_keys_default = viteApiKeysPlugin;
6116
6432
 
6117
6433
  // src/vite/plugin-api.ts
6118
6434
  import fs3 from "node:fs/promises";
6119
- import path14 from "node:path";
6435
+ import path15 from "node:path";
6120
6436
  import { deepEqual as deepEqual2 } from "fast-equals";
6121
6437
  import { runnerImport as runnerImport3 } from "vite";
6122
6438
  init_package_json();
@@ -6125,7 +6441,7 @@ init_loader();
6125
6441
  // src/config/validators/BuildSchema.ts
6126
6442
  init_file_exists();
6127
6443
  init_loader();
6128
- import path9 from "node:path";
6444
+ import path10 from "node:path";
6129
6445
  import { runnerImport as runnerImport2 } from "vite";
6130
6446
  import { z as z10 } from "zod";
6131
6447
  var BuildProcessorSchema = z10.custom((val) => typeof val === "function");
@@ -6154,7 +6470,7 @@ var buildConfigFiles = [
6154
6470
  ];
6155
6471
  async function getBuildConfigFilePath(rootDir) {
6156
6472
  for (const fileName of buildConfigFiles) {
6157
- const filepath = path9.join(rootDir, fileName);
6473
+ const filepath = path10.join(rootDir, fileName);
6158
6474
  if (await fileExists(filepath)) {
6159
6475
  return filepath;
6160
6476
  }
@@ -7168,7 +7484,7 @@ var ensureArray = (value) => Array.isArray(value) ? value : [value];
7168
7484
 
7169
7485
  // src/vite/api/SchemaManager.ts
7170
7486
  import fs2 from "node:fs/promises";
7171
- import path10 from "node:path";
7487
+ import path11 from "node:path";
7172
7488
  import {
7173
7489
  $RefParser as $RefParser2
7174
7490
  } from "@apidevtools/json-schema-ref-parser";
@@ -7358,18 +7674,18 @@ var SchemaManager = class {
7358
7674
  ];
7359
7675
  }
7360
7676
  getPathForFile = (input3, params) => {
7361
- const filePath = path10.resolve(this.config.__meta.rootDir, input3);
7677
+ const filePath = path11.resolve(this.config.__meta.rootDir, input3);
7362
7678
  const apis = ensureArray(this.config.apis ?? []);
7363
7679
  for (const apiConfig of apis) {
7364
7680
  if (!apiConfig || apiConfig.type !== "file" || !apiConfig.path) continue;
7365
7681
  const match = normalizeInputs(apiConfig.input).some(
7366
- (i) => path10.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
7682
+ (i) => path11.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
7367
7683
  );
7368
7684
  if (match) return apiConfig.path;
7369
7685
  }
7370
7686
  };
7371
7687
  processSchema = async (input3) => {
7372
- const filePath = path10.resolve(this.config.__meta.rootDir, input3.input);
7688
+ const filePath = path11.resolve(this.config.__meta.rootDir, input3.input);
7373
7689
  const params = input3.params;
7374
7690
  const configuredPath = this.getPathForFile(input3.input, params);
7375
7691
  if (!configuredPath) {
@@ -7405,9 +7721,9 @@ var SchemaManager = class {
7405
7721
  const processedTime = Date.now();
7406
7722
  const code = generateCode(processedSchema, filePath);
7407
7723
  const prefixPath = slugify(configuredPath);
7408
- const processedFilePath = path10.posix.join(
7724
+ const processedFilePath = path11.posix.join(
7409
7725
  this.storeDir,
7410
- `${prefixPath}-${path10.basename(filePath)}${paramsSuffix(params)}.js`
7726
+ `${prefixPath}-${path11.basename(filePath)}${paramsSuffix(params)}.js`
7411
7727
  );
7412
7728
  const importKey = processedFilePath;
7413
7729
  await fs2.writeFile(processedFilePath, code);
@@ -7456,7 +7772,7 @@ var SchemaManager = class {
7456
7772
  };
7457
7773
  getAllTrackedFiles = () => Array.from(this.referencedBy.keys());
7458
7774
  getFilesToReprocess = (changedFile) => {
7459
- const resolvedPath = path10.resolve(this.config.__meta.rootDir, changedFile);
7775
+ const resolvedPath = path11.resolve(this.config.__meta.rootDir, changedFile);
7460
7776
  const referencedBy = this.referencedBy.get(resolvedPath);
7461
7777
  if (!referencedBy) return [];
7462
7778
  const filesToProcess = referencedBy.size === 0 ? [resolvedPath] : Array.from(referencedBy);
@@ -7485,7 +7801,7 @@ var SchemaManager = class {
7485
7801
  version: "",
7486
7802
  path: input3.path ?? "",
7487
7803
  label: input3.label,
7488
- inputPath: path10.resolve(this.config.__meta.rootDir, input3.input),
7804
+ inputPath: path11.resolve(this.config.__meta.rootDir, input3.input),
7489
7805
  params: input3.params,
7490
7806
  importKey: "",
7491
7807
  downloadUrl: "",
@@ -7528,7 +7844,7 @@ var SchemaManager = class {
7528
7844
  };
7529
7845
  createSchemaPath = (inputPath, versionPath, apiPath, params) => {
7530
7846
  const suffix = paramsSuffix(params);
7531
- const extension = suffix ? ".json" : path10.extname(inputPath);
7847
+ const extension = suffix ? ".json" : path11.extname(inputPath);
7532
7848
  return joinUrl(
7533
7849
  this.config.basePath,
7534
7850
  apiPath,
@@ -7551,8 +7867,8 @@ var SchemaManager = class {
7551
7867
  // src/vite/plugin-config-reload.ts
7552
7868
  init_logger();
7553
7869
  init_loader();
7554
- import path13 from "node:path";
7555
- import colors3 from "picocolors";
7870
+ import path14 from "node:path";
7871
+ import colors6 from "picocolors";
7556
7872
 
7557
7873
  // src/vite/plugin-navigation.ts
7558
7874
  init_loader();
@@ -7561,14 +7877,14 @@ import { stringify as stringify3 } from "javascript-stringify";
7561
7877
  import { isElement } from "react-is";
7562
7878
 
7563
7879
  // src/config/validators/NavigationSchema.ts
7564
- import path11 from "node:path";
7880
+ import path12 from "node:path";
7565
7881
  import { glob } from "glob";
7566
7882
  import { fromMarkdown } from "mdast-util-from-markdown";
7567
7883
  import { mdxFromMarkdown } from "mdast-util-mdx";
7568
7884
  import { mdxjs } from "micromark-extension-mdxjs";
7569
7885
 
7570
7886
  // src/lib/util/readFrontmatter.ts
7571
- import { readFile } from "node:fs/promises";
7887
+ import { readFile as readFile2 } from "node:fs/promises";
7572
7888
  import matter from "gray-matter";
7573
7889
  import { parse, stringify as stringify2 } from "yaml";
7574
7890
  var yaml = {
@@ -7576,7 +7892,7 @@ var yaml = {
7576
7892
  stringify: (obj) => stringify2(obj)
7577
7893
  };
7578
7894
  var readFrontmatter = async (filePath) => {
7579
- const content = await readFile(filePath, "utf-8");
7895
+ const content = await readFile2(filePath, "utf-8");
7580
7896
  const normalizedContent = content.replace(/\r\n/g, "\n");
7581
7897
  return matter(normalizedContent, { engines: { yaml } });
7582
7898
  };
@@ -7612,7 +7928,7 @@ var extractRichH1 = (content) => {
7612
7928
  }
7613
7929
  };
7614
7930
  var isNavigationItem = (item) => item !== void 0;
7615
- var toPosixPath = (filePath) => filePath.split(path11.win32.sep).join(path11.posix.sep);
7931
+ var toPosixPath = (filePath) => filePath.split(path12.win32.sep).join(path12.posix.sep);
7616
7932
  var NavigationResolver = class {
7617
7933
  rootDir;
7618
7934
  globPatterns;
@@ -7744,14 +8060,14 @@ var NavigationResolver = class {
7744
8060
  init_invariant();
7745
8061
 
7746
8062
  // src/vite/debug.ts
7747
- import { mkdir, writeFile } from "node:fs/promises";
7748
- import path12 from "node:path";
8063
+ import { mkdir, writeFile as writeFile2 } from "node:fs/promises";
8064
+ import path13 from "node:path";
7749
8065
  async function writePluginDebugCode(rootDir, pluginName, code, extension = "js") {
7750
8066
  if (process.env.ZUDOKU_BUILD_DEBUG) {
7751
- const debugDir = path12.join(rootDir, "dist", "debug");
8067
+ const debugDir = path13.join(rootDir, "dist", "debug");
7752
8068
  await mkdir(debugDir, { recursive: true });
7753
- await writeFile(
7754
- path12.join(debugDir, `${pluginName}.${extension}`),
8069
+ await writeFile2(
8070
+ path13.join(debugDir, `${pluginName}.${extension}`),
7755
8071
  typeof code === "string" ? code : code.join("\n")
7756
8072
  );
7757
8073
  }
@@ -7859,8 +8175,8 @@ var viteConfigReloadPlugin = () => ({
7859
8175
  invalidate(server);
7860
8176
  reload(server);
7861
8177
  logger.info(
7862
- colors3.blue(
7863
- `Config ${path13.basename(currentConfig.__meta.configPath)} changed. Reloading...`
8178
+ colors6.blue(
8179
+ `Config ${path14.basename(currentConfig.__meta.configPath)} changed. Reloading...`
7864
8180
  ),
7865
8181
  { timestamp: true }
7866
8182
  );
@@ -7874,11 +8190,11 @@ var viteApiPlugin = async () => {
7874
8190
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
7875
8191
  const initialConfig = getCurrentConfig();
7876
8192
  const zuploProcessors = ZuploEnv.isZuplo ? await runnerImport3(
7877
- path14.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
8193
+ path15.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
7878
8194
  ).then((m) => m.module.default(initialConfig.__meta.rootDir)) : [];
7879
8195
  const buildConfig = await getBuildConfig();
7880
8196
  const buildProcessors = buildConfig?.processors ?? [];
7881
- const tmpStoreDir = path14.posix.join(
8197
+ const tmpStoreDir = path15.posix.join(
7882
8198
  initialConfig.__meta.rootDir,
7883
8199
  "node_modules/.apitogo/processed"
7884
8200
  );
@@ -7910,7 +8226,7 @@ var viteApiPlugin = async () => {
7910
8226
  const inputPath = pathMap.get(req.url);
7911
8227
  if (!inputPath) return next();
7912
8228
  const content = await fs3.readFile(inputPath, "utf-8");
7913
- const mimeType = path14.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
8229
+ const mimeType = path15.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
7914
8230
  res.setHeader("Content-Type", `${mimeType}; charset=utf-8`);
7915
8231
  return res.end(content);
7916
8232
  });
@@ -8098,8 +8414,8 @@ var viteApiPlugin = async () => {
8098
8414
  if (process.env.NODE_ENV !== "production") return;
8099
8415
  for (const [urlPath, inputPath] of pathMap) {
8100
8416
  const content = await fs3.readFile(inputPath, "utf-8");
8101
- const outputPath = path14.join(config2.__meta.rootDir, "dist", urlPath);
8102
- await fs3.mkdir(path14.dirname(outputPath), { recursive: true });
8417
+ const outputPath = path15.join(config2.__meta.rootDir, "dist", urlPath);
8418
+ await fs3.mkdir(path15.dirname(outputPath), { recursive: true });
8103
8419
  await fs3.writeFile(outputPath, content, "utf-8");
8104
8420
  }
8105
8421
  }
@@ -8142,7 +8458,7 @@ var plugin_auth_default = viteAuthPlugin;
8142
8458
 
8143
8459
  // src/vite/plugin-component.ts
8144
8460
  init_loader();
8145
- import path15 from "node:path";
8461
+ import path16 from "node:path";
8146
8462
  var viteAliasPlugin = () => {
8147
8463
  return {
8148
8464
  name: "zudoku-component-plugin",
@@ -8170,7 +8486,7 @@ var viteAliasPlugin = () => {
8170
8486
  ];
8171
8487
  const aliases = replacements.map(([find, replacement]) => ({
8172
8488
  find,
8173
- replacement: path15.posix.join(config2.__meta.moduleDir, replacement)
8489
+ replacement: path16.posix.join(config2.__meta.moduleDir, replacement)
8174
8490
  }));
8175
8491
  return config2.__meta.mode === "internal" || config2.__meta.mode === "standalone" ? { resolve: { alias: aliases } } : void 0;
8176
8492
  }
@@ -8181,11 +8497,11 @@ var plugin_component_default = viteAliasPlugin;
8181
8497
  // src/vite/plugin-config.ts
8182
8498
  init_package_json();
8183
8499
  init_loader();
8184
- import path16 from "node:path";
8500
+ import path17 from "node:path";
8185
8501
  import { normalizePath } from "vite";
8186
8502
  var virtualModuleId3 = "virtual:zudoku-config";
8187
8503
  var resolvedVirtualModuleId3 = `\0${virtualModuleId3}`;
8188
- var browserConfigLoaderPath = path16.join(
8504
+ var browserConfigLoaderPath = path17.join(
8189
8505
  getZudokuRootDir(),
8190
8506
  "src/config/apitogo-config-loader.browser.ts"
8191
8507
  );
@@ -8356,7 +8672,7 @@ var viteDocMetadataPlugin = () => ({
8356
8672
 
8357
8673
  // src/vite/plugin-docs.ts
8358
8674
  init_loader();
8359
- import path17 from "node:path";
8675
+ import path18 from "node:path";
8360
8676
  import { glob as glob3 } from "glob";
8361
8677
  import globParent from "glob-parent";
8362
8678
  init_ZudokuConfig();
@@ -8425,7 +8741,7 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
8425
8741
  if (process.env.NODE_ENV !== "development") {
8426
8742
  const draftStatuses = await Promise.all(
8427
8743
  globbedFiles.map(async (file) => {
8428
- const absolutePath = path17.resolve(config2.__meta.rootDir, file);
8744
+ const absolutePath = path18.resolve(config2.__meta.rootDir, file);
8429
8745
  const { data } = await readFrontmatter(absolutePath);
8430
8746
  return { file, isDraft: data.draft === true };
8431
8747
  })
@@ -8438,9 +8754,9 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
8438
8754
  if (draftFiles.has(file)) {
8439
8755
  continue;
8440
8756
  }
8441
- const relativePath = path17.posix.relative(parent, file);
8757
+ const relativePath = path18.posix.relative(parent, file);
8442
8758
  const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
8443
- const filePath = options.absolute ? path17.resolve(config2.__meta.rootDir, file) : file;
8759
+ const filePath = options.absolute ? path18.resolve(config2.__meta.rootDir, file) : file;
8444
8760
  fileMapping[routePath] = filePath;
8445
8761
  }
8446
8762
  }
@@ -8504,7 +8820,7 @@ var viteDocsPlugin = () => {
8504
8820
  const globbedDocuments = {};
8505
8821
  for (const [routePath, file] of Object.entries(fileMapping)) {
8506
8822
  const importPath = ensureLeadingSlash(
8507
- path17.posix.join(globImportBasePath, file)
8823
+ path18.posix.join(globImportBasePath, file)
8508
8824
  );
8509
8825
  globbedDocuments[routePath] = importPath;
8510
8826
  }
@@ -8530,7 +8846,7 @@ var plugin_docs_default = viteDocsPlugin;
8530
8846
  // src/vite/plugin-local-manifest.ts
8531
8847
  init_apitogo_config_loader();
8532
8848
  init_local_manifest();
8533
- import path18 from "node:path";
8849
+ import path19 from "node:path";
8534
8850
  var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
8535
8851
  var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
8536
8852
  var viteLocalManifestPlugin = () => {
@@ -8580,8 +8896,8 @@ var viteLocalManifestPlugin = () => {
8580
8896
  server.watcher.add(watchPath);
8581
8897
  }
8582
8898
  server.watcher.on("change", async (changedPath) => {
8583
- const resolvedChanged = path18.resolve(changedPath);
8584
- if (!watchPaths.some((p) => path18.resolve(p) === resolvedChanged)) {
8899
+ const resolvedChanged = path19.resolve(changedPath);
8900
+ if (!watchPaths.some((p) => path19.resolve(p) === resolvedChanged)) {
8585
8901
  return;
8586
8902
  }
8587
8903
  const module = server.moduleGraph.getModuleById(
@@ -8607,8 +8923,8 @@ var plugin_local_manifest_default = viteLocalManifestPlugin;
8607
8923
  init_loader();
8608
8924
  init_ProtectedRoutesSchema();
8609
8925
  init_joinUrl();
8610
- import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
8611
- import path19 from "node:path";
8926
+ import { mkdir as mkdir2, writeFile as writeFile3 } from "node:fs/promises";
8927
+ import path20 from "node:path";
8612
8928
  import { matchPath } from "react-router";
8613
8929
  var processMarkdownFile = async (filePath) => {
8614
8930
  const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
@@ -8696,7 +9012,7 @@ var viteMarkdownExportPlugin = () => {
8696
9012
  if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
8697
9013
  return;
8698
9014
  }
8699
- const distDir = path19.join(
9015
+ const distDir = path20.join(
8700
9016
  config2.__meta.rootDir,
8701
9017
  "dist",
8702
9018
  config2.basePath ?? ""
@@ -8717,19 +9033,19 @@ var viteMarkdownExportPlugin = () => {
8717
9033
  content: finalMarkdown
8718
9034
  });
8719
9035
  const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
8720
- const outputPath = `${path19.join(distDir, ...segments)}.md`;
8721
- await mkdir2(path19.dirname(outputPath), { recursive: true });
8722
- await writeFile2(outputPath, finalMarkdown, "utf-8");
9036
+ const outputPath = `${path20.join(distDir, ...segments)}.md`;
9037
+ await mkdir2(path20.dirname(outputPath), { recursive: true });
9038
+ await writeFile3(outputPath, finalMarkdown, "utf-8");
8723
9039
  } catch (error) {
8724
9040
  console.warn(`Failed to export markdown for ${routePath}:`, error);
8725
9041
  }
8726
9042
  }
8727
9043
  if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
8728
- const markdownInfoPath = path19.join(
9044
+ const markdownInfoPath = path20.join(
8729
9045
  config2.__meta.rootDir,
8730
9046
  "node_modules/.apitogo/markdown-info.json"
8731
9047
  );
8732
- await writeFile2(
9048
+ await writeFile3(
8733
9049
  markdownInfoPath,
8734
9050
  JSON.stringify(markdownFileInfos, null, 2),
8735
9051
  "utf-8"
@@ -8877,9 +9193,9 @@ var remarkCodeTabs = () => (tree) => {
8877
9193
  };
8878
9194
 
8879
9195
  // src/vite/mdx/remark-inject-filepath.ts
8880
- import path20 from "node:path";
9196
+ import path21 from "node:path";
8881
9197
  var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
8882
- const relativePath = path20.relative(rootDir, vfile.path).split(path20.sep).join(path20.posix.sep);
9198
+ const relativePath = path21.relative(rootDir, vfile.path).split(path21.sep).join(path21.posix.sep);
8883
9199
  tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
8884
9200
  };
8885
9201
 
@@ -8966,18 +9282,18 @@ var remarkLastModified = () => {
8966
9282
  };
8967
9283
 
8968
9284
  // src/vite/mdx/remark-link-rewrite.ts
8969
- import path21 from "node:path";
9285
+ import path22 from "node:path";
8970
9286
  import { visit as visit5 } from "unist-util-visit";
8971
9287
  var remarkLinkRewrite = (basePath = "") => (tree) => {
8972
9288
  visit5(tree, "link", (node) => {
8973
9289
  if (!node.url) return;
8974
9290
  if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
8975
9291
  node.url = node.url.replace(/\\/g, "/");
8976
- const base = path21.posix.join(basePath);
9292
+ const base = path22.posix.join(basePath);
8977
9293
  if (basePath && node.url.startsWith(base)) {
8978
9294
  node.url = node.url.slice(base.length);
8979
9295
  } else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
8980
- node.url = path21.posix.join("..", node.url);
9296
+ node.url = path22.posix.join("..", node.url);
8981
9297
  }
8982
9298
  node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
8983
9299
  });
@@ -9197,14 +9513,14 @@ var plugin_mdx_default = viteMdxPlugin;
9197
9513
 
9198
9514
  // src/vite/plugin-modules.ts
9199
9515
  init_loader();
9200
- import path22 from "node:path";
9516
+ import path23 from "node:path";
9201
9517
  import { normalizePath as normalizePath2 } from "vite";
9202
- var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path22.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
9203
- var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path22.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
9518
+ var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path23.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
9519
+ var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path23.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
9204
9520
  var getBillingPluginImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(
9205
- path22.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
9521
+ path23.join(moduleDir, "../plugin-dev-portal-billing/src/index.ts")
9206
9522
  ) : "@lukoweb/apitogo-plugin-dev-portal-billing";
9207
- var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path22.resolve(rootDir, pagePath));
9523
+ var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path23.resolve(rootDir, pagePath));
9208
9524
  var viteModulesPlugin = () => {
9209
9525
  const virtualModuleId4 = "virtual:zudoku-modules-plugin";
9210
9526
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -9344,20 +9660,20 @@ var plugin_modules_default = viteModulesPlugin;
9344
9660
 
9345
9661
  // src/vite/plugin-offroot-resolve.ts
9346
9662
  init_loader();
9347
- import path23 from "node:path";
9663
+ import path24 from "node:path";
9348
9664
  function stripQuery(id) {
9349
9665
  const query = id.indexOf("?");
9350
9666
  return query === -1 ? id : id.slice(0, query);
9351
9667
  }
9352
9668
  function isInside(parent, child) {
9353
- const relative = path23.relative(path23.resolve(parent), path23.resolve(child));
9354
- return relative === "" || !relative.startsWith("..") && !path23.isAbsolute(relative);
9669
+ const relative = path24.relative(path24.resolve(parent), path24.resolve(child));
9670
+ return relative === "" || !relative.startsWith("..") && !path24.isAbsolute(relative);
9355
9671
  }
9356
9672
  function isBareSpecifier(source) {
9357
- return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path23.isAbsolute(source);
9673
+ return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path24.isAbsolute(source);
9358
9674
  }
9359
9675
  function isInsideNodeModules(filePath) {
9360
- return filePath.split(path23.sep).includes("node_modules");
9676
+ return filePath.split(path24.sep).includes("node_modules");
9361
9677
  }
9362
9678
  function shouldResolveFromSiteRoot(source, importer, rootDir) {
9363
9679
  if (!importer || !isBareSpecifier(source)) {
@@ -9378,7 +9694,7 @@ function viteOffrootResolvePlugin() {
9378
9694
  if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
9379
9695
  return;
9380
9696
  }
9381
- return this.resolve(source, path23.join(rootDir, "package.json"), {
9697
+ return this.resolve(source, path24.join(rootDir, "package.json"), {
9382
9698
  ...options,
9383
9699
  skipSelf: true
9384
9700
  });
@@ -9388,7 +9704,7 @@ function viteOffrootResolvePlugin() {
9388
9704
 
9389
9705
  // src/vite/plugin-search.ts
9390
9706
  init_loader();
9391
- import path24 from "node:path";
9707
+ import path25 from "node:path";
9392
9708
  var viteSearchPlugin = () => {
9393
9709
  const virtualModuleId4 = "virtual:zudoku-search-plugin";
9394
9710
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -9406,7 +9722,7 @@ var viteSearchPlugin = () => {
9406
9722
  return resolvedVirtualModuleId5;
9407
9723
  }
9408
9724
  if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
9409
- return path24.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
9725
+ return path25.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
9410
9726
  }
9411
9727
  },
9412
9728
  async load(id) {
@@ -9546,17 +9862,17 @@ function vitePlugin() {
9546
9862
  }
9547
9863
 
9548
9864
  // src/vite/config.ts
9549
- var browserConfigLoaderPath2 = path25.join(
9865
+ var browserConfigLoaderPath2 = path26.join(
9550
9866
  getZudokuRootDir(),
9551
9867
  "src/config/apitogo-config-loader.browser.ts"
9552
9868
  );
9553
9869
  var resolveMergedPublicDir = (rootDir, merged) => {
9554
9870
  if (merged.publicDir === false) return void 0;
9555
9871
  const rel = typeof merged.publicDir === "string" ? merged.publicDir : "public";
9556
- return path25.resolve(rootDir, rel);
9872
+ return path26.resolve(rootDir, rel);
9557
9873
  };
9558
- var getAppClientEntryPath = () => path25.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
9559
- var getAppServerEntryPath = () => path25.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
9874
+ var getAppClientEntryPath = () => path26.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
9875
+ var getAppServerEntryPath = () => path26.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
9560
9876
  var hasLoggedCdnInfo = false;
9561
9877
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
9562
9878
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -9573,9 +9889,9 @@ async function getViteConfig(dir, configEnv) {
9573
9889
  const cdnUrl = CdnUrlSchema.parse(config2.cdnUrl);
9574
9890
  const base = cdnUrl?.base ? joinUrl(cdnUrl.base, config2.basePath) : config2.basePath;
9575
9891
  if (cdnUrl && !hasLoggedCdnInfo) {
9576
- logger.info(colors4.blue(`Using CDN URL:`));
9577
- logger.info(colors4.blue(` base: `) + colors4.dim(cdnUrl.base));
9578
- logger.info(colors4.blue(` media: `) + colors4.dim(cdnUrl.media));
9892
+ logger.info(colors7.blue(`Using CDN URL:`));
9893
+ logger.info(colors7.blue(` base: `) + colors7.dim(cdnUrl.base));
9894
+ logger.info(colors7.blue(` media: `) + colors7.dim(cdnUrl.media));
9579
9895
  hasLoggedCdnInfo = true;
9580
9896
  }
9581
9897
  const publicVarsProcessEnvDefine = Object.fromEntries(
@@ -9586,7 +9902,7 @@ async function getViteConfig(dir, configEnv) {
9586
9902
  );
9587
9903
  if (ZuploEnv.isZuplo) {
9588
9904
  dotenv.config({
9589
- path: path25.resolve(config2.__meta.rootDir, "../.env.zuplo"),
9905
+ path: path26.resolve(config2.__meta.rootDir, "../.env.zuplo"),
9590
9906
  quiet: true
9591
9907
  });
9592
9908
  }
@@ -9611,11 +9927,11 @@ async function getViteConfig(dir, configEnv) {
9611
9927
  client: {
9612
9928
  resolve: {
9613
9929
  alias: {
9614
- [path25.join(
9930
+ [path26.join(
9615
9931
  getZudokuRootDir(),
9616
9932
  "src/config/apitogo-config-loader.node.ts"
9617
9933
  )]: browserConfigLoaderPath2,
9618
- [path25.join(
9934
+ [path26.join(
9619
9935
  getZudokuRootDir(),
9620
9936
  "src/config/apitogo-config-loader.node.js"
9621
9937
  )]: browserConfigLoaderPath2
@@ -9648,7 +9964,7 @@ async function getViteConfig(dir, configEnv) {
9648
9964
  middlewareMode: true,
9649
9965
  open: true,
9650
9966
  fs: {
9651
- allow: [dir, path25.dirname(dir)]
9967
+ allow: [dir, path26.dirname(dir)]
9652
9968
  },
9653
9969
  watch: {
9654
9970
  ignored: [
@@ -9664,8 +9980,8 @@ async function getViteConfig(dir, configEnv) {
9664
9980
  ssr: configEnv.isSsrBuild,
9665
9981
  sourcemap: true,
9666
9982
  target: "es2022",
9667
- outDir: path25.resolve(
9668
- path25.join(
9983
+ outDir: path26.resolve(
9984
+ path26.join(
9669
9985
  dir,
9670
9986
  "dist",
9671
9987
  config2.basePath ?? "",
@@ -9684,7 +10000,7 @@ async function getViteConfig(dir, configEnv) {
9684
10000
  },
9685
10001
  experimental: {
9686
10002
  renderBuiltUrl(filename) {
9687
- if (cdnUrl?.base && [".js", ".css"].includes(path25.extname(filename))) {
10003
+ if (cdnUrl?.base && [".js", ".css"].includes(path26.extname(filename))) {
9688
10004
  return joinUrl(cdnUrl.base, filename);
9689
10005
  }
9690
10006
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -9697,7 +10013,7 @@ async function getViteConfig(dir, configEnv) {
9697
10013
  esbuildOptions: {
9698
10014
  target: "es2022"
9699
10015
  },
9700
- entries: [path25.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
10016
+ entries: [path26.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
9701
10017
  exclude: [
9702
10018
  "@lukoweb/apitogo",
9703
10019
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -9741,7 +10057,7 @@ async function getViteConfig(dir, configEnv) {
9741
10057
  if (!loaded) continue;
9742
10058
  mergedViteConfig = mergeConfig2(mergedViteConfig, loaded.config, true);
9743
10059
  if (root === dir) {
9744
- logger.info(colors4.blue(`merged with custom user Vite config`), {
10060
+ logger.info(colors7.blue(`merged with custom user Vite config`), {
9745
10061
  timestamp: true
9746
10062
  });
9747
10063
  }
@@ -9802,8 +10118,8 @@ ${cssLinks}
9802
10118
  init_package_json();
9803
10119
  init_joinUrl();
9804
10120
  import assert from "node:assert";
9805
- import { cp, mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
9806
- import path26 from "node:path";
10121
+ import { cp, mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
10122
+ import path27 from "node:path";
9807
10123
  var pkgJson = getZudokuPackageJson();
9808
10124
  function generateOutput({
9809
10125
  config: config2,
@@ -9860,10 +10176,10 @@ async function writeOutput(dir, {
9860
10176
  rewrites
9861
10177
  }) {
9862
10178
  const output2 = generateOutput({ config: config2, redirects, rewrites });
9863
- const outputDir = process.env.VERCEL ? path26.join(dir, ".vercel/output") : path26.join(dir, "dist/.output");
10179
+ const outputDir = process.env.VERCEL ? path27.join(dir, ".vercel/output") : path27.join(dir, "dist/.output");
9864
10180
  await mkdir3(outputDir, { recursive: true });
9865
- const outputFile = path26.join(outputDir, "config.json");
9866
- await writeFile3(outputFile, JSON.stringify(output2, null, 2), "utf-8");
10181
+ const outputFile = path27.join(outputDir, "config.json");
10182
+ await writeFile4(outputFile, JSON.stringify(output2, null, 2), "utf-8");
9867
10183
  if (process.env.VERCEL) {
9868
10184
  console.log("Wrote Vercel output to", outputDir);
9869
10185
  }
@@ -9872,12 +10188,12 @@ async function writeOutput(dir, {
9872
10188
  // src/vite/prerender/prerender.ts
9873
10189
  init_logger();
9874
10190
  init_file_exists();
9875
- import { readFile as readFile2, rm } from "node:fs/promises";
10191
+ import { readFile as readFile3, rm } from "node:fs/promises";
9876
10192
  import os from "node:os";
9877
- import path29 from "node:path";
10193
+ import path30 from "node:path";
9878
10194
  import { pathToFileURL } from "node:url";
9879
10195
  import { createIndex } from "pagefind";
9880
- import colors7 from "picocolors";
10196
+ import colors10 from "picocolors";
9881
10197
  import PiscinaImport from "piscina";
9882
10198
  init_transform_config();
9883
10199
  init_invariant();
@@ -9914,10 +10230,10 @@ function throttle(fn) {
9914
10230
 
9915
10231
  // src/vite/sitemap.ts
9916
10232
  init_joinUrl();
9917
- import { createWriteStream, existsSync as existsSync2 } from "node:fs";
10233
+ import { createWriteStream, existsSync as existsSync3 } from "node:fs";
9918
10234
  import { mkdir as mkdir4 } from "node:fs/promises";
9919
- import path27 from "node:path";
9920
- import colors5 from "picocolors";
10235
+ import path28 from "node:path";
10236
+ import colors8 from "picocolors";
9921
10237
  import { SitemapStream } from "sitemap";
9922
10238
  async function generateSitemap({
9923
10239
  outputUrls,
@@ -9930,11 +10246,11 @@ async function generateSitemap({
9930
10246
  return;
9931
10247
  }
9932
10248
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
9933
- const outputDir = path27.resolve(baseOutputDir, config2.outDir ?? "");
9934
- if (!existsSync2(outputDir)) {
10249
+ const outputDir = path28.resolve(baseOutputDir, config2.outDir ?? "");
10250
+ if (!existsSync3(outputDir)) {
9935
10251
  await mkdir4(outputDir, { recursive: true });
9936
10252
  }
9937
- const sitemapOutputPath = path27.join(outputDir, "sitemap.xml");
10253
+ const sitemapOutputPath = path28.join(outputDir, "sitemap.xml");
9938
10254
  const writeStream = createWriteStream(sitemapOutputPath);
9939
10255
  sitemap.pipe(writeStream);
9940
10256
  let lastmod;
@@ -9958,7 +10274,7 @@ async function generateSitemap({
9958
10274
  writeStream.on("error", reject);
9959
10275
  });
9960
10276
  console.debug(
9961
- colors5.blue(`\u2713 wrote sitemap to ${colors5.bold(sitemapOutputPath)}`)
10277
+ colors8.blue(`\u2713 wrote sitemap to ${colors8.bold(sitemapOutputPath)}`)
9962
10278
  );
9963
10279
  }
9964
10280
 
@@ -10020,12 +10336,12 @@ var prerender = async ({
10020
10336
  serverConfigFilename,
10021
10337
  writeRedirects = true
10022
10338
  }) => {
10023
- const distDir = path29.join(dir, "dist", basePath);
10339
+ const distDir = path30.join(dir, "dist", basePath);
10024
10340
  const serverConfigPath = pathToFileURL(
10025
- path29.join(distDir, "server", serverConfigFilename)
10341
+ path30.join(distDir, "server", serverConfigFilename)
10026
10342
  ).href;
10027
10343
  const entryServerPath = pathToFileURL(
10028
- path29.join(distDir, "server/entry.server.js")
10344
+ path30.join(distDir, "server/entry.server.js")
10029
10345
  ).href;
10030
10346
  const rawConfig = await import(serverConfigPath).then(
10031
10347
  (m) => m.default
@@ -10050,12 +10366,12 @@ var prerender = async ({
10050
10366
  const writeProgress = throttle(
10051
10367
  (count, total, urlPath) => {
10052
10368
  if (quietDeployJson) return;
10053
- writeLine(`prerendering (${count}/${total}) ${colors7.dim(urlPath)}`);
10369
+ writeLine(`prerendering (${count}/${total}) ${colors10.dim(urlPath)}`);
10054
10370
  }
10055
10371
  );
10056
10372
  if (!isTTY() && !quietDeployJson) {
10057
10373
  logger.info(
10058
- colors7.dim(
10374
+ colors10.dim(
10059
10375
  `prerendering ${paths.length} routes using ${maxThreads} workers...`
10060
10376
  )
10061
10377
  );
@@ -10099,7 +10415,7 @@ var prerender = async ({
10099
10415
  const now = performance.now();
10100
10416
  if (now - lastLogTime >= LOG_INTERVAL_MS) {
10101
10417
  logger.info(
10102
- colors7.blue(
10418
+ colors10.blue(
10103
10419
  `prerendered ${completedCount}/${paths.length} routes using ${maxThreads} workers`
10104
10420
  )
10105
10421
  );
@@ -10110,20 +10426,20 @@ var prerender = async ({
10110
10426
  })
10111
10427
  );
10112
10428
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
10113
- outputPath: path29.join(distDir, "pagefind")
10429
+ outputPath: path30.join(distDir, "pagefind")
10114
10430
  });
10115
10431
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
10116
10432
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
10117
10433
  if (!quietDeployJson) {
10118
10434
  if (isTTY()) {
10119
- writeLine(colors7.blue(`${message}
10435
+ writeLine(colors10.blue(`${message}
10120
10436
  `));
10121
10437
  } else {
10122
- logger.info(colors7.blue(message));
10438
+ logger.info(colors10.blue(message));
10123
10439
  }
10124
10440
  if (pagefindWriteResult?.outputPath) {
10125
10441
  logger.info(
10126
- colors7.blue(
10442
+ colors10.blue(
10127
10443
  `\u2713 pagefind index built: ${pagefindWriteResult.outputPath}`
10128
10444
  )
10129
10445
  );
@@ -10142,13 +10458,13 @@ var prerender = async ({
10142
10458
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
10143
10459
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
10144
10460
  const llmsConfig = docsConfig.llms ?? {};
10145
- const markdownInfoPath = path29.join(
10461
+ const markdownInfoPath = path30.join(
10146
10462
  dir,
10147
10463
  "node_modules/.apitogo/markdown-info.json"
10148
10464
  );
10149
10465
  let markdownFileInfos = [];
10150
10466
  if (await fileExists(markdownInfoPath)) {
10151
- const markdownInfoContent = await readFile2(markdownInfoPath, "utf-8");
10467
+ const markdownInfoContent = await readFile3(markdownInfoPath, "utf-8");
10152
10468
  markdownFileInfos = JSON.parse(markdownInfoContent);
10153
10469
  }
10154
10470
  if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
@@ -10233,7 +10549,7 @@ async function runBuild(options) {
10233
10549
  html,
10234
10550
  basePath: config2.basePath
10235
10551
  });
10236
- await rm2(path30.join(clientOutDir, "index.html"), { force: true });
10552
+ await rm2(path31.join(clientOutDir, "index.html"), { force: true });
10237
10553
  } else {
10238
10554
  await runPrerender({
10239
10555
  dir,
@@ -10257,9 +10573,9 @@ var runPrerender = async (options) => {
10257
10573
  serverConfigFilename,
10258
10574
  writeRedirects: process.env.VERCEL === void 0
10259
10575
  });
10260
- const indexHtml = path30.join(clientOutDir, "index.html");
10576
+ const indexHtml = path31.join(clientOutDir, "index.html");
10261
10577
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
10262
- await writeFile5(indexHtml, html, "utf-8");
10578
+ await writeFile6(indexHtml, html, "utf-8");
10263
10579
  }
10264
10580
  const statusPages = workerResults.flatMap(
10265
10581
  (r) => /400|404|500\.html$/.test(r.outputPath) ? r.outputPath : []
@@ -10267,15 +10583,15 @@ var runPrerender = async (options) => {
10267
10583
  for (const statusPage of statusPages) {
10268
10584
  await rename(
10269
10585
  statusPage,
10270
- path30.join(dir, DIST_DIR, path30.basename(statusPage))
10586
+ path31.join(dir, DIST_DIR, path31.basename(statusPage))
10271
10587
  );
10272
10588
  }
10273
10589
  await rm2(serverOutDir, { recursive: true, force: true });
10274
10590
  if (process.env.VERCEL) {
10275
- await mkdir5(path30.join(dir, ".vercel/output/static"), { recursive: true });
10591
+ await mkdir5(path31.join(dir, ".vercel/output/static"), { recursive: true });
10276
10592
  await rename(
10277
- path30.join(dir, DIST_DIR),
10278
- path30.join(dir, ".vercel/output/static")
10593
+ path31.join(dir, DIST_DIR),
10594
+ path31.join(dir, ".vercel/output/static")
10279
10595
  );
10280
10596
  }
10281
10597
  await writeOutput(dir, {
@@ -10284,8 +10600,8 @@ var runPrerender = async (options) => {
10284
10600
  rewrites
10285
10601
  });
10286
10602
  if (ZuploEnv.isZuplo && issuer) {
10287
- await writeFile5(
10288
- path30.join(dir, DIST_DIR, ".output/zuplo.json"),
10603
+ await writeFile6(
10604
+ path31.join(dir, DIST_DIR, ".output/zuplo.json"),
10289
10605
  JSON.stringify({ issuer }, null, 2),
10290
10606
  "utf-8"
10291
10607
  );
@@ -10297,17 +10613,17 @@ var runPrerender = async (options) => {
10297
10613
  };
10298
10614
  var bundleSSREntry = async (options) => {
10299
10615
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
10300
- const tempEntryPath = path30.join(dir, "__ssr-entry.ts");
10616
+ const tempEntryPath = path31.join(dir, "__ssr-entry.ts");
10301
10617
  const packageRoot = getZudokuRootDir();
10302
- const templateContent = await readFile3(
10303
- path30.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
10618
+ const templateContent = await readFile4(
10619
+ path31.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
10304
10620
  "utf-8"
10305
10621
  );
10306
10622
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
10307
10623
  '"__BASE_PATH__"',
10308
10624
  basePath ? JSON.stringify(basePath) : "undefined"
10309
10625
  );
10310
- await writeFile5(tempEntryPath, entryContent, "utf-8");
10626
+ await writeFile6(tempEntryPath, entryContent, "utf-8");
10311
10627
  try {
10312
10628
  await esbuild({
10313
10629
  entryPoints: [tempEntryPath],
@@ -10315,9 +10631,9 @@ var bundleSSREntry = async (options) => {
10315
10631
  platform: adapter === "node" ? "node" : "neutral",
10316
10632
  target: "es2022",
10317
10633
  format: "esm",
10318
- outfile: path30.join(serverOutDir, "entry.js"),
10634
+ outfile: path31.join(serverOutDir, "entry.js"),
10319
10635
  external: ["./entry.server.js", `./${serverConfigFilename}`],
10320
- nodePaths: [path30.join(packageRoot, "node_modules")],
10636
+ nodePaths: [path31.join(packageRoot, "node_modules")],
10321
10637
  banner: { js: "// Bundled SSR entry" }
10322
10638
  });
10323
10639
  } finally {
@@ -10327,48 +10643,14 @@ var bundleSSREntry = async (options) => {
10327
10643
 
10328
10644
  // src/cli/build/handler.ts
10329
10645
  init_logger();
10330
-
10331
- // src/cli/common/output.ts
10332
- import * as Sentry from "@sentry/node";
10333
- import colors8 from "picocolors";
10334
-
10335
- // src/cli/common/constants.ts
10336
- var CLI_XDG_FOLDER_NAME = "apitogo";
10337
- var VERSION_CHECK_FILE = "version.json";
10338
- var SENTRY_DSN = void 0;
10339
- var MAX_WAIT_PENDING_TIME_MS = 1e3;
10340
- var POST_HOG_CAPTURE_KEY = void 0;
10341
-
10342
- // src/cli/common/output.ts
10343
- function printDiagnosticsToConsole(message) {
10344
- console.error(colors8.bold(colors8.blue(message)));
10345
- }
10346
- function printWarningToConsole(message) {
10347
- console.error(message);
10348
- }
10349
- async function printCriticalFailureToConsoleAndExit(message) {
10350
- console.error(colors8.bold(colors8.red(message)));
10351
- await Sentry.close(MAX_WAIT_PENDING_TIME_MS).then(() => {
10352
- process.exit(1);
10353
- });
10354
- }
10355
- function printJsonOnlyErrorAndExit(message) {
10356
- console.log(JSON.stringify({ error: message }));
10357
- process.exit(1);
10358
- }
10359
- function printResultToConsole(message) {
10360
- console.log(colors8.bold(colors8.green(message)));
10361
- }
10362
-
10363
- // src/cli/build/handler.ts
10364
10646
  init_package_json();
10365
10647
 
10366
10648
  // src/cli/preview/handler.ts
10367
- import path31 from "node:path";
10649
+ import path32 from "node:path";
10368
10650
  import { preview as vitePreview } from "vite";
10369
10651
  var DEFAULT_PREVIEW_PORT = 4e3;
10370
10652
  async function preview(argv) {
10371
- const dir = path31.resolve(process.cwd(), argv.dir);
10653
+ const dir = path32.resolve(process.cwd(), argv.dir);
10372
10654
  const viteConfig = await getViteConfig(dir, {
10373
10655
  command: "serve",
10374
10656
  mode: "production",
@@ -10402,14 +10684,14 @@ async function preview(argv) {
10402
10684
 
10403
10685
  // src/cli/build/handler.ts
10404
10686
  async function build(argv) {
10405
- const packageJson2 = getZudokuPackageJson();
10687
+ const packageJson3 = getZudokuPackageJson();
10406
10688
  const jsonOnly = argv.jsonOnly === true || process.env.APITOGO_JSON_ONLY === "1";
10407
10689
  if (!jsonOnly) {
10408
- printDiagnosticsToConsole(`Starting API ToGo build v${packageJson2.version}`);
10690
+ printDiagnosticsToConsole(`Starting API ToGo build v${packageJson3.version}`);
10409
10691
  printDiagnosticsToConsole("");
10410
10692
  printDiagnosticsToConsole("");
10411
10693
  }
10412
- const dir = path32.resolve(process.cwd(), argv.dir);
10694
+ const dir = path33.resolve(process.cwd(), argv.dir);
10413
10695
  try {
10414
10696
  await runBuild({
10415
10697
  dir,
@@ -10434,107 +10716,9 @@ async function build(argv) {
10434
10716
  }
10435
10717
  }
10436
10718
 
10437
- // src/cli/common/analytics/lib.ts
10438
- import { PostHog } from "posthog-node";
10439
-
10440
- // src/cli/common/machine-id/lib.ts
10441
- import { execSync } from "node:child_process";
10442
- import { createHash } from "node:crypto";
10443
- var win32RegBinPath = {
10444
- skipped: "",
10445
- native: "%windir%\\System32",
10446
- mixed: "%windir%\\sysnative\\cmd.exe /c %windir%\\System32"
10447
- };
10448
- var guid = {
10449
- darwin: "ioreg -rd1 -c IOPlatformExpertDevice",
10450
- win32: `${win32RegBinPath[isWindowsProcessMixedOrNativeArchitecture()]}\\REG.exe QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid`,
10451
- linux: "( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :"
10452
- };
10453
- function isWindowsProcessMixedOrNativeArchitecture() {
10454
- if (process.platform !== "win32") {
10455
- return "skipped";
10456
- }
10457
- if (process.arch === "ia32" && process.env.PROCESSOR_ARCHITEW6432) {
10458
- return "mixed";
10459
- }
10460
- return "native";
10461
- }
10462
- function hash(guid2) {
10463
- return createHash("sha256").update(guid2).digest("hex");
10464
- }
10465
- function expose(result) {
10466
- switch (process.platform) {
10467
- case "darwin":
10468
- return result.split("IOPlatformUUID")[1].split("\n")[0].replace(/=|\s+]"/gi, "").toLowerCase();
10469
- case "win32":
10470
- return result.toString().split("REG_SZ")[1].replace(/\r+|\n+|\s+/gi, "").toLowerCase();
10471
- case "linux":
10472
- return result.toString().replace(/\r+|\n+|\s+/gi, "").toLowerCase();
10473
- case "freebsd":
10474
- return result.toString().replace(/\r+|\n+|\s+/gi, "").toLowerCase();
10475
- default:
10476
- throw new Error(`Unsupported platform: ${process.platform}`);
10477
- }
10478
- }
10479
- function machineId() {
10480
- switch (process.platform) {
10481
- case "darwin":
10482
- case "win32":
10483
- case "linux":
10484
- return hash(expose(execSync(guid[process.platform]).toString()));
10485
- default:
10486
- return "e16fc483-5593-4d71-b485-a6533693da9b";
10487
- }
10488
- }
10489
-
10490
- // src/cli/common/analytics/lib.ts
10491
- var _postHog;
10492
- function init() {
10493
- if (process.env.ZUDOKU_DO_NOT_TRACK || !POST_HOG_CAPTURE_KEY) {
10494
- return void 0;
10495
- }
10496
- _postHog = new PostHog(POST_HOG_CAPTURE_KEY, {
10497
- host: "https://app.posthog.com",
10498
- flushAt: 1,
10499
- flushInterval: 1
10500
- });
10501
- return _postHog;
10502
- }
10503
- async function captureEvent({
10504
- event,
10505
- properties,
10506
- groups,
10507
- sendFeatureFlags,
10508
- timestamp,
10509
- disableGeoip
10510
- }) {
10511
- if (_postHog === void 0) {
10512
- init();
10513
- }
10514
- if (_postHog) {
10515
- properties = properties ?? {};
10516
- properties.$set_once = properties.$set_once ?? {};
10517
- if (process.env.CI) {
10518
- properties.ci = process.env.CI;
10519
- }
10520
- _postHog.capture({
10521
- distinctId: machineId(),
10522
- event,
10523
- properties,
10524
- groups,
10525
- sendFeatureFlags,
10526
- timestamp,
10527
- disableGeoip
10528
- });
10529
- }
10530
- }
10531
- async function shutdownAnalytics() {
10532
- return _postHog?.shutdown();
10533
- }
10534
-
10535
10719
  // src/cli/cmds/build.ts
10536
10720
  var build_default = {
10537
- desc: "Build",
10721
+ desc: "Build the local portal for production",
10538
10722
  command: "build",
10539
10723
  builder: (yargs2) => yargs2.option("dir", {
10540
10724
  type: "string",
@@ -10567,14 +10751,14 @@ var build_default = {
10567
10751
  };
10568
10752
 
10569
10753
  // src/cli/check/handler.ts
10570
- import path39 from "node:path";
10754
+ import path40 from "node:path";
10571
10755
 
10572
10756
  // src/cli/platform/client/platform-api.ts
10573
10757
  import { basename } from "node:path";
10574
10758
 
10575
10759
  // src/cli/platform/client/deploy-server.ts
10576
- import { readFile as readFile4 } from "node:fs/promises";
10577
- import path33 from "node:path";
10760
+ import { readFile as readFile5 } from "node:fs/promises";
10761
+ import path34 from "node:path";
10578
10762
  var UPLOAD_TIMEOUT_MS = 5 * 60 * 1e3;
10579
10763
  var DeployServerError = class extends Error {
10580
10764
  statusCode;
@@ -10586,8 +10770,8 @@ var DeployServerError = class extends Error {
10586
10770
  };
10587
10771
  async function uploadDevPortalArchive(params) {
10588
10772
  const { endpointUrl, apiKey, deploymentToken, env, archivePath } = params;
10589
- const fileBuffer = await readFile4(archivePath);
10590
- const fileName = path33.basename(archivePath);
10773
+ const fileBuffer = await readFile5(archivePath);
10774
+ const fileName = path34.basename(archivePath);
10591
10775
  const form = new FormData();
10592
10776
  form.append("deploymentToken", deploymentToken);
10593
10777
  form.append("env", env);
@@ -11191,7 +11375,7 @@ function resolveDevPortalDeployConfig(config2) {
11191
11375
  }
11192
11376
 
11193
11377
  // src/cli/platform/tools/check-publish-readiness.ts
11194
- import path38 from "node:path";
11378
+ import path39 from "node:path";
11195
11379
 
11196
11380
  // src/cli/platform/helpers/dev-portal-backend.ts
11197
11381
  function deriveProvisioningState(backend) {
@@ -11273,9 +11457,9 @@ function formatDevPortalBackendResponse(projectId, backend) {
11273
11457
  }
11274
11458
 
11275
11459
  // src/cli/platform/helpers/dev-portal-manifest.ts
11276
- import { existsSync as existsSync3 } from "node:fs";
11277
- import { access, mkdir as mkdir6, readFile as readFile5, writeFile as writeFile6 } from "node:fs/promises";
11278
- import path34 from "node:path";
11460
+ import { existsSync as existsSync4 } from "node:fs";
11461
+ import { access, mkdir as mkdir6, readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
11462
+ import path35 from "node:path";
11279
11463
 
11280
11464
  // src/cli/make-config/header-pricing-nav.ts
11281
11465
  var HEADER_PRICING_PATH = "/pricing";
@@ -11335,7 +11519,7 @@ function isPlanFree(plan) {
11335
11519
  return (plan.priceAmount ?? 0) <= 0;
11336
11520
  }
11337
11521
  function manifestFilePath(siteDirectory) {
11338
- return path34.join(path34.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
11522
+ return path35.join(path35.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
11339
11523
  }
11340
11524
  var STORED_MANIFEST_KEYS = [
11341
11525
  "authentication",
@@ -11796,29 +11980,29 @@ function resolveBackendOpenApiPath(openApiPath, options) {
11796
11980
  if (!trimmed) {
11797
11981
  return void 0;
11798
11982
  }
11799
- if (path34.isAbsolute(trimmed)) {
11983
+ if (path35.isAbsolute(trimmed)) {
11800
11984
  return trimmed;
11801
11985
  }
11802
- const siteResolved = path34.resolve(options.siteDirectory, trimmed);
11803
- if (existsSync3(siteResolved)) {
11986
+ const siteResolved = path35.resolve(options.siteDirectory, trimmed);
11987
+ if (existsSync4(siteResolved)) {
11804
11988
  return siteResolved;
11805
11989
  }
11806
11990
  const backendDir = options.backendSourceDirectory?.trim();
11807
11991
  if (backendDir) {
11808
- const backendResolved = path34.resolve(backendDir, trimmed);
11809
- if (existsSync3(backendResolved)) {
11992
+ const backendResolved = path35.resolve(backendDir, trimmed);
11993
+ if (existsSync4(backendResolved)) {
11810
11994
  return backendResolved;
11811
11995
  }
11812
11996
  }
11813
11997
  return siteResolved;
11814
11998
  }
11815
11999
  function toSiteRelativeOpenApiInput(siteDirectory, openApiAbsolutePath) {
11816
- const relative = path34.relative(path34.resolve(siteDirectory), path34.resolve(openApiAbsolutePath));
11817
- const posix = relative.split(path34.sep).join("/");
12000
+ const relative = path35.relative(path35.resolve(siteDirectory), path35.resolve(openApiAbsolutePath));
12001
+ const posix = relative.split(path35.sep).join("/");
11818
12002
  if (!posix || posix === ".") {
11819
12003
  return "./";
11820
12004
  }
11821
- if (path34.isAbsolute(posix) || posix.startsWith("..")) {
12005
+ if (path35.isAbsolute(posix) || posix.startsWith("..")) {
11822
12006
  return posix;
11823
12007
  }
11824
12008
  return posix.startsWith("./") ? posix : `./${posix}`;
@@ -11857,7 +12041,7 @@ function applyOpenApiToSiteConfig(config2, options) {
11857
12041
  async function readManifest(siteDirectory) {
11858
12042
  const filePath = manifestFilePath(siteDirectory);
11859
12043
  if (await pathExists(filePath)) {
11860
- const raw = await readFile5(filePath, "utf8");
12044
+ const raw = await readFile6(filePath, "utf8");
11861
12045
  const config2 = JSON.parse(raw);
11862
12046
  return extractManifestFromConfig(config2);
11863
12047
  }
@@ -11865,22 +12049,22 @@ async function readManifest(siteDirectory) {
11865
12049
  }
11866
12050
  async function writeManifest(siteDirectory, manifest) {
11867
12051
  const filePath = manifestFilePath(siteDirectory);
11868
- await mkdir6(path34.dirname(filePath), { recursive: true });
12052
+ await mkdir6(path35.dirname(filePath), { recursive: true });
11869
12053
  let config2 = {};
11870
12054
  if (await pathExists(filePath)) {
11871
- const raw = await readFile5(filePath, "utf8");
12055
+ const raw = await readFile6(filePath, "utf8");
11872
12056
  config2 = JSON.parse(raw);
11873
12057
  }
11874
12058
  const { oidc: _oidc, stripe: _stripe, ...safeManifest } = manifest;
11875
12059
  config2 = applyManifestToConfig(config2, safeManifest);
11876
- await writeFile6(filePath, `${JSON.stringify(config2, null, 2)}
12060
+ await writeFile7(filePath, `${JSON.stringify(config2, null, 2)}
11877
12061
  `, "utf8");
11878
12062
  return filePath;
11879
12063
  }
11880
12064
 
11881
12065
  // src/cli/platform/helpers/dev-portal-secrets.ts
11882
- import { access as access2, appendFile, mkdir as mkdir7, readFile as readFile6, unlink, writeFile as writeFile7 } from "node:fs/promises";
11883
- import path35 from "node:path";
12066
+ import { access as access2, appendFile, mkdir as mkdir7, readFile as readFile7, unlink, writeFile as writeFile8 } from "node:fs/promises";
12067
+ import path36 from "node:path";
11884
12068
  var ENV_FILENAME = ".env";
11885
12069
  var COLLAPSED_UPPERCASE_ALIASES2 = {
11886
12070
  SECRETKEY: "secretKey",
@@ -11982,7 +12166,7 @@ function applyEnvOverrides2(config2, env) {
11982
12166
  }
11983
12167
  async function readEnvFile(filePath) {
11984
12168
  try {
11985
- const raw = await readFile6(filePath, "utf8");
12169
+ const raw = await readFile7(filePath, "utf8");
11986
12170
  const env = {};
11987
12171
  for (const line of raw.split("\n")) {
11988
12172
  const trimmed = line.trim();
@@ -11999,10 +12183,10 @@ async function readEnvFile(filePath) {
11999
12183
  }
12000
12184
  }
12001
12185
  async function loadSiteEnv(siteDirectory) {
12002
- const resolvedDirectory = path35.resolve(siteDirectory);
12186
+ const resolvedDirectory = path36.resolve(siteDirectory);
12003
12187
  const merged = { ...process.env };
12004
12188
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
12005
- Object.assign(merged, await readEnvFile(path35.join(resolvedDirectory, fileName)));
12189
+ Object.assign(merged, await readEnvFile(path36.join(resolvedDirectory, fileName)));
12006
12190
  }
12007
12191
  return merged;
12008
12192
  }
@@ -12038,7 +12222,7 @@ function buildAuthSecretsJson(secrets, options) {
12038
12222
  return payload;
12039
12223
  }
12040
12224
  function envFilePath(siteDirectory) {
12041
- return path35.join(path35.resolve(siteDirectory), ENV_FILENAME);
12225
+ return path36.join(path36.resolve(siteDirectory), ENV_FILENAME);
12042
12226
  }
12043
12227
  function createEnvContent() {
12044
12228
  return [
@@ -12098,7 +12282,7 @@ function validateSecretsForPublish(manifest, secrets, emailOptions) {
12098
12282
  }
12099
12283
  async function siteEnvFileHasEntries(siteDirectory) {
12100
12284
  for (const fileName of [ENV_FILENAME, ".env.local"]) {
12101
- const loaded = await readEnvFile(path35.join(siteDirectory, fileName));
12285
+ const loaded = await readEnvFile(path36.join(siteDirectory, fileName));
12102
12286
  if (Object.keys(loaded).length > 0) {
12103
12287
  return true;
12104
12288
  }
@@ -12106,7 +12290,7 @@ async function siteEnvFileHasEntries(siteDirectory) {
12106
12290
  return false;
12107
12291
  }
12108
12292
  async function resolvePublishConfig(siteDirectory, emailOptions) {
12109
- const resolvedDirectory = path35.resolve(siteDirectory);
12293
+ const resolvedDirectory = path36.resolve(siteDirectory);
12110
12294
  const manifestRaw = await readManifest(resolvedDirectory);
12111
12295
  if (!manifestRaw) {
12112
12296
  throw new Error("apitogo.config.json not found in sourceDirectory.");
@@ -12135,20 +12319,20 @@ function envFileHasActiveAssignments(content) {
12135
12319
  });
12136
12320
  }
12137
12321
  async function writeScaffoldEnv(siteDirectory) {
12138
- const resolvedDirectory = path35.resolve(siteDirectory);
12322
+ const resolvedDirectory = path36.resolve(siteDirectory);
12139
12323
  const filesWritten = [];
12140
12324
  const envPath = envFilePath(resolvedDirectory);
12141
12325
  try {
12142
12326
  await access2(envPath);
12143
12327
  } catch {
12144
12328
  await mkdir7(resolvedDirectory, { recursive: true });
12145
- await writeFile7(envPath, createEnvContent(), "utf8");
12329
+ await writeFile8(envPath, createEnvContent(), "utf8");
12146
12330
  filesWritten.push(ENV_FILENAME);
12147
12331
  }
12148
12332
  for (const legacyName of [".env.example"]) {
12149
- const legacyPath = path35.join(resolvedDirectory, legacyName);
12333
+ const legacyPath = path36.join(resolvedDirectory, legacyName);
12150
12334
  try {
12151
- const legacy = await readFile6(legacyPath, "utf8");
12335
+ const legacy = await readFile7(legacyPath, "utf8");
12152
12336
  if (!envFileHasActiveAssignments(legacy)) {
12153
12337
  await unlink(legacyPath);
12154
12338
  filesWritten.push(`removed:${legacyName}`);
@@ -12156,10 +12340,10 @@ async function writeScaffoldEnv(siteDirectory) {
12156
12340
  } catch {
12157
12341
  }
12158
12342
  }
12159
- const gitignorePath = path35.join(resolvedDirectory, ".gitignore");
12343
+ const gitignorePath = path36.join(resolvedDirectory, ".gitignore");
12160
12344
  let gitignore = "";
12161
12345
  try {
12162
- gitignore = await readFile6(gitignorePath, "utf8");
12346
+ gitignore = await readFile7(gitignorePath, "utf8");
12163
12347
  } catch {
12164
12348
  gitignore = "";
12165
12349
  }
@@ -12171,7 +12355,7 @@ async function writeScaffoldEnv(siteDirectory) {
12171
12355
  if (!hasEntry) {
12172
12356
  const suffix = gitignore.length === 0 ? "" : gitignore.endsWith("\n") ? "" : "\n";
12173
12357
  if (gitignore.length === 0) {
12174
- await writeFile7(gitignorePath, `${entry}
12358
+ await writeFile8(gitignorePath, `${entry}
12175
12359
  `, "utf8");
12176
12360
  } else {
12177
12361
  await appendFile(gitignorePath, `${suffix}${entry}
@@ -12190,13 +12374,13 @@ var writeScaffoldSecretsArtifacts = writeScaffoldEnv;
12190
12374
  var SECRETS_COLLECTION_INSTRUCTION = "For go-live, plans must already be in apitogo.config.json \u2014 ask the user what plans they want before calling update_dev_portal_manifest; never add Free+Pro defaults unless they explicitly request them. The user must save auth secrets (OIDC provider secrets, and Stripe if paid plans) in .env using APITOGO_CONFIG_AUTHENTICATION__* keys. Native auth email is provisioned by the platform \u2014 do not ask for an ACS connection string. Share .env and required fields from publishPrerequisites.missingFields. Never ask for or accept secret values in chat. When the user confirms secrets are saved locally, call check_dev_portal_publish_readiness, then publish_dev_portal.";
12191
12375
 
12192
12376
  // src/cli/platform/helpers/dev-portal-site-validation.ts
12193
- import { readFile as readFile7 } from "node:fs/promises";
12377
+ import { readFile as readFile8 } from "node:fs/promises";
12194
12378
  import { createRequire as createRequire2 } from "node:module";
12195
- import path36 from "node:path";
12379
+ import path37 from "node:path";
12196
12380
  init_gateway_limits();
12197
12381
  var cachedFallbackTs;
12198
12382
  async function loadTypeScriptForSite(sourceDirectory) {
12199
- const require2 = createRequire2(path36.join(path36.resolve(sourceDirectory), "package.json"));
12383
+ const require2 = createRequire2(path37.join(path37.resolve(sourceDirectory), "package.json"));
12200
12384
  try {
12201
12385
  return require2("typescript");
12202
12386
  } catch {
@@ -12240,7 +12424,7 @@ async function referencedFileExists(sourceDirectory, reference) {
12240
12424
  if (/^https?:\/\//i.test(reference)) {
12241
12425
  return true;
12242
12426
  }
12243
- return pathExists(path36.resolve(sourceDirectory, reference.replace(/^\.\//, "")));
12427
+ return pathExists(path37.resolve(sourceDirectory, reference.replace(/^\.\//, "")));
12244
12428
  }
12245
12429
  async function validateSiteConfigStructure(config2, sourceDirectory) {
12246
12430
  const errors = [];
@@ -12346,17 +12530,17 @@ var DEFAULT_TSX_CANDIDATES = [
12346
12530
  "landing/LandingPage.tsx"
12347
12531
  ];
12348
12532
  async function validateDevPortalSiteConfig(sourceDirectory, options) {
12349
- const resolvedDir = path36.resolve(sourceDirectory);
12533
+ const resolvedDir = path37.resolve(sourceDirectory);
12350
12534
  const issues = [];
12351
12535
  const checkedFiles = [];
12352
12536
  const skippedChecks = [];
12353
- const jsonPath = path36.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
12537
+ const jsonPath = path37.join(resolvedDir, APITOGO_CONFIG_FILENAME2);
12354
12538
  if (await pathExists(jsonPath)) {
12355
12539
  checkedFiles.push(APITOGO_CONFIG_FILENAME2);
12356
12540
  let parsed;
12357
12541
  let parseFailed = false;
12358
12542
  try {
12359
- parsed = JSON.parse(await readFile7(jsonPath, "utf8"));
12543
+ parsed = JSON.parse(await readFile8(jsonPath, "utf8"));
12360
12544
  } catch (error) {
12361
12545
  parseFailed = true;
12362
12546
  issues.push({
@@ -12379,7 +12563,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
12379
12563
  );
12380
12564
  const existingTsxFiles = [];
12381
12565
  for (const relativeFile of tsxFiles) {
12382
- if (await pathExists(path36.join(resolvedDir, relativeFile))) {
12566
+ if (await pathExists(path37.join(resolvedDir, relativeFile))) {
12383
12567
  existingTsxFiles.push(relativeFile);
12384
12568
  }
12385
12569
  }
@@ -12392,7 +12576,7 @@ async function validateDevPortalSiteConfig(sourceDirectory, options) {
12392
12576
  } else {
12393
12577
  for (const relativeFile of existingTsxFiles) {
12394
12578
  checkedFiles.push(relativeFile);
12395
- const content = await readFile7(path36.join(resolvedDir, relativeFile), "utf8");
12579
+ const content = await readFile8(path37.join(resolvedDir, relativeFile), "utf8");
12396
12580
  issues.push(
12397
12581
  ...checkTsxSyntax(ts, relativeFile, content).map((message) => ({
12398
12582
  file: relativeFile,
@@ -12427,8 +12611,8 @@ function buildSiteValidationResponseFields(result) {
12427
12611
 
12428
12612
  // src/cli/platform/helpers/npm-build.ts
12429
12613
  import { spawn } from "node:child_process";
12430
- import { access as access3, readFile as readFile8 } from "node:fs/promises";
12431
- import path37 from "node:path";
12614
+ import { access as access3, readFile as readFile9 } from "node:fs/promises";
12615
+ import path38 from "node:path";
12432
12616
  var BUILD_LOG_TAIL_BYTES = 8192;
12433
12617
  var MIN_NODE_MAJOR = 20;
12434
12618
  var NpmBuildError = class extends Error {
@@ -12473,9 +12657,9 @@ async function pathExists2(filePath) {
12473
12657
  return false;
12474
12658
  }
12475
12659
  }
12476
- function runCommand(command, args, cwd, env) {
12660
+ function runCommand(command2, args, cwd, env) {
12477
12661
  return new Promise((resolve, reject) => {
12478
- const child = spawn(command, args, {
12662
+ const child = spawn(command2, args, {
12479
12663
  cwd,
12480
12664
  env: env ? { ...process.env, ...env } : process.env,
12481
12665
  shell: process.platform === "win32"
@@ -12493,13 +12677,13 @@ function runCommand(command, args, cwd, env) {
12493
12677
  }
12494
12678
  async function runNpmInstall(sourceDirectory, options) {
12495
12679
  assertNodeVersion(options?.nodeVersion);
12496
- const cwd = path37.resolve(sourceDirectory);
12497
- const packageJsonPath = path37.join(cwd, "package.json");
12680
+ const cwd = path38.resolve(sourceDirectory);
12681
+ const packageJsonPath = path38.join(cwd, "package.json");
12498
12682
  if (!await pathExists2(packageJsonPath)) {
12499
12683
  throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
12500
12684
  }
12501
12685
  const startedAt = Date.now();
12502
- const lockPath = path37.join(cwd, "package-lock.json");
12686
+ const lockPath = path38.join(cwd, "package-lock.json");
12503
12687
  const installArgs = await pathExists2(lockPath) ? ["ci"] : ["install"];
12504
12688
  const install = await runCommand("npm", installArgs, cwd);
12505
12689
  const installLog = install.output;
@@ -12517,8 +12701,8 @@ async function runNpmInstall(sourceDirectory, options) {
12517
12701
  }
12518
12702
  async function runNpmBuild(sourceDirectory, options) {
12519
12703
  assertNodeVersion(options?.nodeVersion);
12520
- const cwd = path37.resolve(sourceDirectory);
12521
- const packageJsonPath = path37.join(cwd, "package.json");
12704
+ const cwd = path38.resolve(sourceDirectory);
12705
+ const packageJsonPath = path38.join(cwd, "package.json");
12522
12706
  if (!await pathExists2(packageJsonPath)) {
12523
12707
  throw new Error(`package.json not found in sourceDirectory: ${cwd}`);
12524
12708
  }
@@ -12535,8 +12719,8 @@ async function runNpmBuild(sourceDirectory, options) {
12535
12719
  build2.exitCode
12536
12720
  );
12537
12721
  }
12538
- const distPath = path37.join(cwd, "dist");
12539
- const indexPath = path37.join(distPath, "index.html");
12722
+ const distPath = path38.join(cwd, "dist");
12723
+ const indexPath = path38.join(distPath, "index.html");
12540
12724
  if (!await pathExists2(indexPath)) {
12541
12725
  throw new NpmBuildError(
12542
12726
  `Build completed but dist/index.html was not found at ${indexPath}`,
@@ -12888,7 +13072,7 @@ function validateManifestForPlatformPublish(manifest) {
12888
13072
 
12889
13073
  // src/cli/platform/tools/check-publish-readiness.ts
12890
13074
  async function checkPublishReadiness(client, _config, args) {
12891
- const sourceDirectory = path38.resolve(args.sourceDirectory);
13075
+ const sourceDirectory = path39.resolve(args.sourceDirectory);
12892
13076
  const manifest = await readManifest(sourceDirectory) ?? createScaffoldManifest();
12893
13077
  const emailOptions = await resolveEmailOptionsForPublish(
12894
13078
  client,
@@ -12966,7 +13150,7 @@ async function checkPublishReadiness(client, _config, args) {
12966
13150
 
12967
13151
  // src/cli/check/handler.ts
12968
13152
  async function check(argv) {
12969
- const sourceDirectory = path39.resolve(process.cwd(), argv.dir);
13153
+ const sourceDirectory = path40.resolve(process.cwd(), argv.dir);
12970
13154
  const config2 = loadConfig();
12971
13155
  const client = new PlatformApiClient(config2);
12972
13156
  let result;
@@ -13010,18 +13194,18 @@ var check_default = {
13010
13194
 
13011
13195
  // src/cli/make-config/handler.ts
13012
13196
  import { constants as constants2 } from "node:fs";
13013
- import { access as access8, mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "node:fs/promises";
13014
- import path50 from "node:path";
13197
+ import { access as access8, mkdir as mkdir10, readFile as readFile14, writeFile as writeFile13 } from "node:fs/promises";
13198
+ import path51 from "node:path";
13015
13199
  import { stdin as input2 } from "node:process";
13016
13200
  import { glob as glob5 } from "glob";
13017
13201
 
13018
13202
  // src/cli/scaffold/dev-portal-config-pages.ts
13019
- import { access as access4, readFile as readFile9, rename as rename2, rm as rm3, writeFile as writeFile8 } from "node:fs/promises";
13020
- import path40 from "node:path";
13203
+ import { access as access4, readFile as readFile10, rename as rename2, rm as rm3, writeFile as writeFile9 } from "node:fs/promises";
13204
+ import path41 from "node:path";
13021
13205
  async function writeConfigAtomically(filePath, content) {
13022
13206
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
13023
13207
  try {
13024
- await writeFile8(temporaryPath, content, "utf8");
13208
+ await writeFile9(temporaryPath, content, "utf8");
13025
13209
  await rename2(temporaryPath, filePath);
13026
13210
  } catch (error) {
13027
13211
  await rm3(temporaryPath, { force: true });
@@ -13030,7 +13214,7 @@ async function writeConfigAtomically(filePath, content) {
13030
13214
  }
13031
13215
  async function resolveApitogoConfigPath(sourceDirectory) {
13032
13216
  for (const filename of ["apitogo.config.tsx", "apitogo.config.jsx"]) {
13033
- const configPath = path40.join(sourceDirectory, filename);
13217
+ const configPath = path41.join(sourceDirectory, filename);
13034
13218
  try {
13035
13219
  await access4(configPath);
13036
13220
  return configPath;
@@ -13754,7 +13938,7 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
13754
13938
  if (!configPath) {
13755
13939
  return { updated: false };
13756
13940
  }
13757
- const original = await readFile9(configPath, "utf8");
13941
+ const original = await readFile10(configPath, "utf8");
13758
13942
  const patched = patchApitogoConfigForNewPage(original, slug, label, {
13759
13943
  typescript: configPath.endsWith(".tsx")
13760
13944
  });
@@ -13766,18 +13950,18 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
13766
13950
  }
13767
13951
 
13768
13952
  // src/cli/scaffold/wire-openapi.ts
13769
- import { access as access6, readFile as readFile11, writeFile as writeFile10 } from "node:fs/promises";
13770
- import path45 from "node:path";
13953
+ import { access as access6, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
13954
+ import path46 from "node:path";
13771
13955
 
13772
13956
  // src/cli/platform/helpers/openapi.ts
13773
13957
  import { promises as fs5 } from "node:fs";
13774
- import path42 from "node:path";
13958
+ import path43 from "node:path";
13775
13959
  import SwaggerParser from "@apidevtools/swagger-parser";
13776
13960
  import YAML from "yaml";
13777
13961
 
13778
13962
  // src/cli/scaffold/discover-openapi-files.ts
13779
13963
  import { promises as fs4 } from "node:fs";
13780
- import path41 from "node:path";
13964
+ import path42 from "node:path";
13781
13965
  var OPENAPI_BASENAMES = [
13782
13966
  "openapi.yaml",
13783
13967
  "openapi.yml",
@@ -13799,13 +13983,13 @@ var SKIP_OPENAPI_SEARCH_DIRS = /* @__PURE__ */ new Set([
13799
13983
  ".apitogo"
13800
13984
  ]);
13801
13985
  async function collectFromDir(dir, searchedDirectories, candidates) {
13802
- const resolved = path41.resolve(dir);
13986
+ const resolved = path42.resolve(dir);
13803
13987
  if (searchedDirectories.includes(resolved)) {
13804
13988
  return;
13805
13989
  }
13806
13990
  searchedDirectories.push(resolved);
13807
13991
  for (const name of OPENAPI_BASENAMES) {
13808
- const candidate = path41.join(resolved, name);
13992
+ const candidate = path42.join(resolved, name);
13809
13993
  try {
13810
13994
  await fs4.access(candidate);
13811
13995
  candidates.push(candidate);
@@ -13820,8 +14004,8 @@ async function collectSiteOpenApiFiles(siteDirectory) {
13820
14004
  return { candidates: [...new Set(candidates)], searchedDirectories };
13821
14005
  }
13822
14006
  async function collectNearbyOpenApiFiles(siteDirectory) {
13823
- const site = path41.resolve(siteDirectory);
13824
- const parent = path41.dirname(site);
14007
+ const site = path42.resolve(siteDirectory);
14008
+ const parent = path42.dirname(site);
13825
14009
  const searchedDirectories = [];
13826
14010
  const candidates = [];
13827
14011
  if (parent && parent !== site) {
@@ -13832,8 +14016,8 @@ async function collectNearbyOpenApiFiles(siteDirectory) {
13832
14016
  if (!entry.isDirectory() || SKIP_OPENAPI_SEARCH_DIRS.has(entry.name)) {
13833
14017
  continue;
13834
14018
  }
13835
- const sibling = path41.join(parent, entry.name);
13836
- if (path41.resolve(sibling) === site) {
14019
+ const sibling = path42.join(parent, entry.name);
14020
+ if (path42.resolve(sibling) === site) {
13837
14021
  continue;
13838
14022
  }
13839
14023
  await collectFromDir(sibling, searchedDirectories, candidates);
@@ -13861,7 +14045,7 @@ function parseOpenApiObject(doc) {
13861
14045
  };
13862
14046
  }
13863
14047
  function liteParseOpenApi(content, filePath) {
13864
- const ext = path41.extname(filePath).toLowerCase();
14048
+ const ext = path42.extname(filePath).toLowerCase();
13865
14049
  if (ext === ".json") {
13866
14050
  try {
13867
14051
  const parsed = JSON.parse(content);
@@ -13926,9 +14110,9 @@ async function discoverNearbyOpenApi(siteDirectory) {
13926
14110
  };
13927
14111
  }
13928
14112
  async function validateOpenApiFile(filePath) {
13929
- const resolved = path42.resolve(filePath);
14113
+ const resolved = path43.resolve(filePath);
13930
14114
  const content = await fs5.readFile(resolved, "utf8");
13931
- const ext = path42.extname(resolved).toLowerCase();
14115
+ const ext = path43.extname(resolved).toLowerCase();
13932
14116
  let parsed;
13933
14117
  try {
13934
14118
  parsed = ext === ".json" ? JSON.parse(content) : YAML.parse(content);
@@ -13970,13 +14154,13 @@ async function validateOpenApiFile(filePath) {
13970
14154
  }
13971
14155
 
13972
14156
  // src/cli/scaffold/scaffold-dev-portal-site.ts
13973
- import { mkdir as mkdir8, readFile as readFile10, writeFile as writeFile9 } from "node:fs/promises";
13974
- import path44 from "node:path";
14157
+ import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile10 } from "node:fs/promises";
14158
+ import path45 from "node:path";
13975
14159
 
13976
14160
  // src/cli/scaffold/create-apitogo-cli.ts
13977
14161
  import { spawn as spawn2 } from "node:child_process";
13978
14162
  import { access as access5, rm as rm4 } from "node:fs/promises";
13979
- import path43 from "node:path";
14163
+ import path44 from "node:path";
13980
14164
 
13981
14165
  // src/cli/scaffold/apitogo-npm-packages.ts
13982
14166
  var DEFAULT_CREATE_APITOGO_PACKAGE2 = "@lukoweb/create-apitogo@latest";
@@ -14077,9 +14261,9 @@ function resolveDocToolPath(explicit) {
14077
14261
  return value || void 0;
14078
14262
  }
14079
14263
  function splitOutputDirectory(outputDirectory) {
14080
- const resolvedOutputDirectory = path43.resolve(outputDirectory);
14081
- const projectName = path43.basename(resolvedOutputDirectory);
14082
- const parentDirectory = path43.dirname(resolvedOutputDirectory);
14264
+ const resolvedOutputDirectory = path44.resolve(outputDirectory);
14265
+ const projectName = path44.basename(resolvedOutputDirectory);
14266
+ const parentDirectory = path44.dirname(resolvedOutputDirectory);
14083
14267
  if (!projectName || projectName === "." || projectName === "..") {
14084
14268
  throw new Error(
14085
14269
  "outputDirectory must be a named folder (e.g. ./dev-portal-site), not the current directory."
@@ -14105,7 +14289,7 @@ async function directoryHasEntries(dir) {
14105
14289
  }
14106
14290
  }
14107
14291
  function resolveLocalCreateApitogoEntry(docToolPath) {
14108
- return path43.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
14292
+ return path44.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
14109
14293
  }
14110
14294
  async function resolveCreateApitogoInvocation(options) {
14111
14295
  const docToolPath = resolveDocToolPath(options.docToolPath);
@@ -14130,9 +14314,9 @@ async function resolveCreateApitogoInvocation(options) {
14130
14314
  args: [pkg]
14131
14315
  };
14132
14316
  }
14133
- function runCommand2(command, args, cwd) {
14317
+ function runCommand2(command2, args, cwd) {
14134
14318
  return new Promise((resolve, reject) => {
14135
- const child = spawn2(command, args, {
14319
+ const child = spawn2(command2, args, {
14136
14320
  cwd,
14137
14321
  env: process.env,
14138
14322
  shell: process.platform === "win32"
@@ -14187,7 +14371,7 @@ async function runCreateApitogoDevPortal(options) {
14187
14371
  result.exitCode
14188
14372
  );
14189
14373
  }
14190
- if (!await pathExists3(path43.join(resolvedOutputDirectory, "package.json"))) {
14374
+ if (!await pathExists3(path44.join(resolvedOutputDirectory, "package.json"))) {
14191
14375
  throw new CreateApitogoCliError(
14192
14376
  `create-apitogo completed but package.json was not found at ${resolvedOutputDirectory}`,
14193
14377
  result.output,
@@ -14243,7 +14427,7 @@ function ensureRequiredApitogoModules(pkg, options) {
14243
14427
  ]
14244
14428
  ]) {
14245
14429
  if (options.docToolPath) {
14246
- deps[moduleName] = `file:${path44.join(options.docToolPath, localPath)}`;
14430
+ deps[moduleName] = `file:${path45.join(options.docToolPath, localPath)}`;
14247
14431
  continue;
14248
14432
  }
14249
14433
  deps[moduleName] = `npm:${moduleName}@${moduleAliasVersion}`;
@@ -14272,7 +14456,7 @@ function rewritePackageJson(raw, options) {
14272
14456
  if (!deps) continue;
14273
14457
  for (const [dep, relativePath] of Object.entries(DOC_TOOL_LOCAL_PACKAGE_PATHS)) {
14274
14458
  if (dep in deps) {
14275
- deps[dep] = `file:${path44.join(options.docToolPath, relativePath)}`;
14459
+ deps[dep] = `file:${path45.join(options.docToolPath, relativePath)}`;
14276
14460
  linkedWorkspacePackage = true;
14277
14461
  }
14278
14462
  }
@@ -14369,24 +14553,24 @@ function patchDashboardPageConfig(content) {
14369
14553
  );
14370
14554
  }
14371
14555
  async function ensureAccountPlansPage(outputDirectory) {
14372
- const pagePath = path44.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
14556
+ const pagePath = path45.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
14373
14557
  try {
14374
- await readFile10(pagePath, "utf8");
14558
+ await readFile11(pagePath, "utf8");
14375
14559
  return void 0;
14376
14560
  } catch {
14377
- await mkdir8(path44.dirname(pagePath), { recursive: true });
14378
- await writeFile9(pagePath, ACCOUNT_PLANS_PAGE);
14561
+ await mkdir8(path45.dirname(pagePath), { recursive: true });
14562
+ await writeFile10(pagePath, ACCOUNT_PLANS_PAGE);
14379
14563
  return ACCOUNT_PLANS_PAGE_PATH;
14380
14564
  }
14381
14565
  }
14382
14566
  async function ensureDashboardPage(outputDirectory) {
14383
- const pagePath = path44.join(outputDirectory, DASHBOARD_PAGE_PATH);
14567
+ const pagePath = path45.join(outputDirectory, DASHBOARD_PAGE_PATH);
14384
14568
  try {
14385
- await readFile10(pagePath, "utf8");
14569
+ await readFile11(pagePath, "utf8");
14386
14570
  return void 0;
14387
14571
  } catch {
14388
- await mkdir8(path44.dirname(pagePath), { recursive: true });
14389
- await writeFile9(pagePath, DASHBOARD_PAGE);
14572
+ await mkdir8(path45.dirname(pagePath), { recursive: true });
14573
+ await writeFile10(pagePath, DASHBOARD_PAGE);
14390
14574
  return DASHBOARD_PAGE_PATH;
14391
14575
  }
14392
14576
  }
@@ -14436,12 +14620,12 @@ function patchApitogoConfig(content, options) {
14436
14620
  async function patchScaffoldedSite(outputDirectory, options) {
14437
14621
  const title = options.branding?.title ?? options.siteName;
14438
14622
  const filesWritten = [];
14439
- const packageJsonPath = path44.join(outputDirectory, "package.json");
14623
+ const packageJsonPath = path45.join(outputDirectory, "package.json");
14440
14624
  if (options.patchPackageJson !== false) {
14441
- const packageJson2 = await readFile10(packageJsonPath, "utf8");
14442
- await writeFile9(
14625
+ const packageJson3 = await readFile11(packageJsonPath, "utf8");
14626
+ await writeFile10(
14443
14627
  packageJsonPath,
14444
- rewritePackageJson(packageJson2, {
14628
+ rewritePackageJson(packageJson3, {
14445
14629
  siteName: options.siteName,
14446
14630
  docToolPath: options.docToolPath,
14447
14631
  createApitogoPackage: options.createApitogoPackage
@@ -14449,9 +14633,9 @@ async function patchScaffoldedSite(outputDirectory, options) {
14449
14633
  );
14450
14634
  filesWritten.push("package.json");
14451
14635
  }
14452
- const configPath = path44.join(outputDirectory, "apitogo.config.tsx");
14453
- const configContent = await readFile10(configPath, "utf8");
14454
- await writeFile9(
14636
+ const configPath = path45.join(outputDirectory, "apitogo.config.tsx");
14637
+ const configContent = await readFile11(configPath, "utf8");
14638
+ await writeFile10(
14455
14639
  configPath,
14456
14640
  patchDashboardPageConfig(
14457
14641
  patchAccountPlansPageConfig(
@@ -14544,8 +14728,8 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
14544
14728
  return discoverNearbyOpenApi(siteDirectory);
14545
14729
  }
14546
14730
  async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
14547
- const resolvedSource = path45.resolve(sourceDirectory);
14548
- const resolvedOpenApi = path45.resolve(openApiPath);
14731
+ const resolvedSource = path46.resolve(sourceDirectory);
14732
+ const resolvedOpenApi = path46.resolve(openApiPath);
14549
14733
  const input3 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
14550
14734
  const validation = await validateOpenApiFile(resolvedOpenApi);
14551
14735
  if (!validation.valid) {
@@ -14557,24 +14741,24 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
14557
14741
  }
14558
14742
  const jsonConfigPath = manifestFilePath(resolvedSource);
14559
14743
  if (await pathExists4(jsonConfigPath)) {
14560
- const raw = await readFile11(jsonConfigPath, "utf8");
14744
+ const raw = await readFile12(jsonConfigPath, "utf8");
14561
14745
  const siteConfig = JSON.parse(raw);
14562
14746
  const updated = applyOpenApiToSiteConfig(siteConfig, {
14563
14747
  input: input3,
14564
14748
  apiPath: "api"
14565
14749
  });
14566
- await writeFile10(
14750
+ await writeFile11(
14567
14751
  jsonConfigPath,
14568
14752
  `${JSON.stringify(updated, null, 2)}
14569
14753
  `,
14570
14754
  "utf8"
14571
14755
  );
14572
14756
  } else {
14573
- const tsxConfigPath = path45.join(resolvedSource, "apitogo.config.tsx");
14574
- const configContent = await readFile11(tsxConfigPath, "utf8");
14757
+ const tsxConfigPath = path46.join(resolvedSource, "apitogo.config.tsx");
14758
+ const configContent = await readFile12(tsxConfigPath, "utf8");
14575
14759
  try {
14576
14760
  const patched = patchApitogoConfigOpenApiToFile(configContent, input3);
14577
- await writeFile10(tsxConfigPath, patched);
14761
+ await writeFile11(tsxConfigPath, patched);
14578
14762
  } catch (error) {
14579
14763
  return {
14580
14764
  status: "failed",
@@ -14658,10 +14842,10 @@ async function discoverAndWireOpenApi(siteDirectory, mode) {
14658
14842
  // src/cli/make-config/interactive.ts
14659
14843
  import { createInterface } from "node:readline/promises";
14660
14844
  import { stdin as input, stdout as output } from "node:process";
14661
- import path47 from "node:path";
14845
+ import path48 from "node:path";
14662
14846
 
14663
14847
  // src/cli/make-config/json-config.ts
14664
- import path46 from "node:path";
14848
+ import path47 from "node:path";
14665
14849
  var APITOGO_JSON_FILENAME = "apitogo.config.json";
14666
14850
  var DOCUMENTATION_NAV_LABEL2 = "Documentation";
14667
14851
  var API_REFERENCE_PATH = "/api";
@@ -15029,9 +15213,9 @@ function openapiInputForConfig(specRelativePosix) {
15029
15213
  return `./${specRelativePosix}`;
15030
15214
  }
15031
15215
  function toRelativeOpenApiInput(projectDir, inputPath) {
15032
- const resolved = path46.isAbsolute(inputPath) ? inputPath : path46.resolve(projectDir, inputPath);
15033
- const relative = path46.relative(projectDir, resolved);
15034
- const posix = relative.split(path46.sep).join(path46.posix.sep);
15216
+ const resolved = path47.isAbsolute(inputPath) ? inputPath : path47.resolve(projectDir, inputPath);
15217
+ const relative = path47.relative(projectDir, resolved);
15218
+ const posix = relative.split(path47.sep).join(path47.posix.sep);
15035
15219
  if (!posix) {
15036
15220
  throw new Error("OpenAPI path must point to a file.");
15037
15221
  }
@@ -15404,7 +15588,7 @@ async function promptMakeConfigInteractive(options) {
15404
15588
  continue;
15405
15589
  }
15406
15590
  const routePath = `/${slug}`;
15407
- const relativePath = path47.posix.join(options.pagesDir, `${slug}.tsx`);
15591
+ const relativePath = path48.posix.join(options.pagesDir, `${slug}.tsx`);
15408
15592
  const page = {
15409
15593
  slug,
15410
15594
  title: pageTitle.trim(),
@@ -15496,8 +15680,8 @@ export default function ${componentName}() {
15496
15680
  // src/cli/make-config/scaffold-project.ts
15497
15681
  init_package_json();
15498
15682
  import { constants } from "node:fs";
15499
- import { access as access7, mkdir as mkdir9, readFile as readFile12, writeFile as writeFile11 } from "node:fs/promises";
15500
- import path48 from "node:path";
15683
+ import { access as access7, mkdir as mkdir9, readFile as readFile13, writeFile as writeFile12 } from "node:fs/promises";
15684
+ import path49 from "node:path";
15501
15685
  import { glob as glob4 } from "glob";
15502
15686
 
15503
15687
  // src/cli/make-config/branding-assets.ts
@@ -15521,9 +15705,9 @@ var OPENAPI_GLOBS = [
15521
15705
  "openapi.yaml",
15522
15706
  "openapi.yml"
15523
15707
  ];
15524
- var toPosix = (p) => p.split(path48.sep).join("/");
15708
+ var toPosix = (p) => p.split(path49.sep).join("/");
15525
15709
  var sanitizePackageName = (dir) => {
15526
- const base = path48.basename(path48.resolve(dir));
15710
+ const base = path49.basename(path49.resolve(dir));
15527
15711
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
15528
15712
  return s || "apitogo-site";
15529
15713
  };
@@ -15533,7 +15717,7 @@ var apitogoVersionRange = () => {
15533
15717
  };
15534
15718
  async function findOpenApiSpecPath(dir) {
15535
15719
  for (const rel of OPENAPI_GLOBS) {
15536
- const full = path48.join(dir, rel);
15720
+ const full = path49.join(dir, rel);
15537
15721
  try {
15538
15722
  await access7(full, constants.R_OK);
15539
15723
  return toPosix(rel);
@@ -15548,7 +15732,7 @@ async function findOpenApiSpecPath(dir) {
15548
15732
  return extra[0] ? toPosix(extra[0]) : null;
15549
15733
  }
15550
15734
  async function ensurePackageJson(dir) {
15551
- const pkgPath = path48.join(dir, "package.json");
15735
+ const pkgPath = path49.join(dir, "package.json");
15552
15736
  const apitogoVer = apitogoVersionRange();
15553
15737
  const baseDeps = {
15554
15738
  react: ">=19.0.0",
@@ -15583,11 +15767,11 @@ async function ensurePackageJson(dir) {
15583
15767
  typescript: "^5"
15584
15768
  }
15585
15769
  };
15586
- await writeFile11(pkgPath, `${JSON.stringify(pkg2, null, 2)}
15770
+ await writeFile12(pkgPath, `${JSON.stringify(pkg2, null, 2)}
15587
15771
  `, "utf8");
15588
15772
  return true;
15589
15773
  }
15590
- const raw = await readFile12(pkgPath, "utf8");
15774
+ const raw = await readFile13(pkgPath, "utf8");
15591
15775
  let pkg;
15592
15776
  try {
15593
15777
  pkg = JSON.parse(raw);
@@ -15610,12 +15794,12 @@ async function ensurePackageJson(dir) {
15610
15794
  for (const [k, v] of Object.entries(baseDeps)) {
15611
15795
  if (!deps[k]) deps[k] = v;
15612
15796
  }
15613
- await writeFile11(pkgPath, `${JSON.stringify(pkg, null, 2)}
15797
+ await writeFile12(pkgPath, `${JSON.stringify(pkg, null, 2)}
15614
15798
  `, "utf8");
15615
15799
  return false;
15616
15800
  }
15617
15801
  async function ensureTsconfigJson(dir) {
15618
- const tsPath = path48.join(dir, "tsconfig.json");
15802
+ const tsPath = path49.join(dir, "tsconfig.json");
15619
15803
  try {
15620
15804
  await access7(tsPath, constants.R_OK);
15621
15805
  return false;
@@ -15645,12 +15829,12 @@ async function ensureTsconfigJson(dir) {
15645
15829
  "user-panel"
15646
15830
  ]
15647
15831
  };
15648
- await writeFile11(tsPath, `${JSON.stringify(tsconfig, null, 2)}
15832
+ await writeFile12(tsPath, `${JSON.stringify(tsconfig, null, 2)}
15649
15833
  `, "utf8");
15650
15834
  return true;
15651
15835
  }
15652
15836
  }
15653
- var LANDING_PAGE_SOURCE = 'import {\n ApiShowcaseSection,\n FeaturesSection,\n HeroSection,\n LandingShell,\n PlansPreviewSection,\n PricingCtaSection,\n StepsSection,\n} from "@lukoweb/apitogo-module-landing";\n\nexport default function LandingPage() {\n return (\n <LandingShell\n title="Test against a real API before you build one"\n description="Sample API gives you realistic endpoints, authentication, rate limits, and webhooks \u2014 a fully working backend for prototypes, demos, and QA."\n >\n <HeroSection\n hero={{\n badge: "SANDBOX API",\n title: "Test against a real API before you build one",\n description:\n "Sample API gives you realistic endpoints, authentication, rate limits, and webhooks \u2014 a fully working backend for prototypes, demos, and QA. No setup, no infrastructure.",\n }}\n primaryAction={{ label: "Start for free", href: "/signup" }}\n secondaryAction={{ label: "Read the docs", href: "/introduction" }}\n codeExamples={[\n {\n filename: "Create a key",\n language: "bash",\n code: `$ curl -X POST https://api.sampleapi.dev/v1/keys\n# sk_live_9f2c7a1e...`,\n },\n {\n filename: "Call an endpoint",\n language: "bash",\n code: `$ curl https://api.sampleapi.dev/v1/users/42 \\\\\n -H "Authorization: Bearer sk_live_9f2c..."\n# { "id": 42, "name": "Priya Shah", "plan": "pro" }`,\n },\n ]}\n />\n <FeaturesSection\n section={{\n label: "Everything a real API has",\n title: "Built for testing, not just browsing",\n description:\n "Realistic data, live auth, rate limits, and webhooks \u2014 so you can ship with confidence.",\n }}\n features={[\n {\n title: "Realistic mock data",\n description:\n "Users, orders, products, and posts with relationships and pagination, not lorem ipsum.",\n icon: "boxes",\n },\n {\n title: "Real auth flow",\n description:\n "Every request checks a live API key, so you can test error handling and expiry.",\n icon: "shield-check",\n },\n {\n title: "Rate limiting",\n description:\n "Per-plan request limits and 429 responses, so you can build and test backoff logic.",\n icon: "gauge",\n },\n {\n title: "Webhooks",\n description:\n "Trigger test events and inspect delivered payloads and retries.",\n icon: "webhook",\n },\n {\n title: "OpenAPI & docs",\n description:\n "A full OpenAPI spec and reference docs for every endpoint.",\n icon: "book-open",\n },\n {\n title: "Usage analytics",\n description:\n "Track requests, latency, and errors per key from your dashboard.",\n icon: "activity",\n },\n ]}\n />\n <StepsSection\n steps={[\n {\n step: "01",\n title: "Create an account",\n description:\n "Sign up and land straight in your dashboard \u2014 no approval queue.",\n },\n {\n step: "02",\n title: "Generate a key",\n description:\n "Every key is scoped and rate-limited to your plan from the moment it\'s created.",\n },\n {\n step: "03",\n title: "Call any endpoint",\n description:\n "Users, orders, products, posts, and webhooks \u2014 all documented, all live.",\n },\n ]}\n />\n <ApiShowcaseSection\n apiShowcase={{\n title: "Sample endpoints",\n subtitle:\n "A slice of what\'s available \u2014 see the full reference in the docs.",\n browseAllHref: "/api",\n browseAllLabel: "Browse all APIs",\n layout: "list",\n items: [\n {\n name: "List paginated users",\n path: "/v1/users",\n method: "GET",\n summary: "List paginated users",\n },\n {\n name: "Create a mock order",\n path: "/v1/orders",\n method: "POST",\n summary: "Create a mock order",\n },\n {\n name: "Fetch one product",\n path: "/v1/products/{id}",\n method: "GET",\n summary: "Fetch one product",\n },\n {\n name: "List posts with comments",\n path: "/v1/posts",\n method: "GET",\n summary: "List posts with comments",\n },\n {\n name: "Fire a test webhook event",\n path: "/v1/webhooks/test",\n method: "POST",\n summary: "Fire a test webhook event",\n },\n {\n name: "Delete a mock order",\n path: "/v1/orders/{id}",\n method: "DELETE",\n summary: "Delete a mock order",\n },\n ],\n }}\n />\n <PlansPreviewSection\n plans={[\n {\n name: "Free",\n price: "$0",\n unit: "per month",\n blurb: "1,000 requests/mo, community support.",\n },\n {\n name: "Developer",\n price: "$19",\n unit: "per month",\n blurb: "50,000 requests/mo, webhooks included.",\n featured: true,\n },\n {\n name: "Team",\n price: "$79",\n unit: "per month",\n blurb: "500,000 requests/mo, 5 team seats.",\n },\n {\n name: "Enterprise",\n price: "Custom",\n unit: "talk to us",\n blurb: "Unlimited requests, SSO, SLA.",\n },\n ]}\n />\n <PricingCtaSection\n variant="banner"\n pricingCta={{\n title: "Start testing in minutes",\n description:\n "Free tier includes 1,000 requests a month \u2014 no card required.",\n primaryAction: { label: "Start for free", href: "/signup" },\n }}\n />\n </LandingShell>\n );\n}\n';
15837
+ var LANDING_PAGE_SOURCE = 'import {\n ApiShowcaseSection,\n FeaturesSection,\n HeroSection,\n LandingShell,\n PlansPreviewSection,\n PricingCtaSection,\n StepsSection,\n} from "@lukoweb/apitogo-module-landing";\n\nexport default function LandingPage() {\n return (\n <LandingShell\n title="Test against a real API before you build one"\n description="Sample API gives you realistic endpoints, authentication, rate limits, and webhooks \u2014 a fully working backend for prototypes, demos, and QA."\n >\n <HeroSection\n hero={{\n badge: "SANDBOX API",\n title: "Test against a real API before you build one",\n description:\n "Sample API gives you realistic endpoints, authentication, rate limits, and webhooks \u2014 a fully working backend for prototypes, demos, and QA. No setup, no infrastructure.",\n }}\n primaryAction={{ label: "Start for free", href: "/signup" }}\n secondaryAction={{ label: "Read the docs", href: "/introduction" }}\n codeExamples={[\n {\n filename: "Create a key",\n language: "bash",\n code: `$ curl -X POST https://api.sampleapi.dev/v1/keys\n# sk_live_9f2c7a1e...`,\n },\n {\n filename: "Call an endpoint",\n language: "bash",\n code: `$ curl https://api.sampleapi.dev/v1/users/42 \\\\\n -H "Authorization: Bearer sk_live_9f2c..."\n# { "id": 42, "name": "Priya Shah", "plan": "pro" }`,\n },\n ]}\n />\n <FeaturesSection\n section={{\n label: "Everything a real API has",\n title: "Built for testing, not just browsing",\n description:\n "Realistic data, live auth, rate limits, and webhooks \u2014 so you can ship with confidence.",\n }}\n features={[\n {\n title: "Realistic mock data",\n description:\n "Users, orders, products, and posts with relationships and pagination, not lorem ipsum.",\n icon: "boxes",\n },\n {\n title: "Real auth flow",\n description:\n "Every request checks a live API key, so you can test error handling and expiry.",\n icon: "shield-check",\n },\n {\n title: "Rate limiting",\n description:\n "Per-plan request limits and 429 responses, so you can build and test backoff logic.",\n icon: "gauge",\n },\n {\n title: "Webhooks",\n description:\n "Trigger test events and inspect delivered payloads and retries.",\n icon: "webhook",\n },\n {\n title: "OpenAPI & docs",\n description:\n "A full OpenAPI spec and reference docs for every endpoint.",\n icon: "book-open",\n },\n {\n title: "Usage analytics",\n description:\n "Track requests, latency, and errors per key from your dashboard.",\n icon: "activity",\n },\n ]}\n />\n <StepsSection\n steps={[\n {\n step: "01",\n title: "Create an account",\n description:\n "Sign up and land straight in your dashboard \u2014 no approval queue.",\n },\n {\n step: "02",\n title: "Generate a key",\n description:\n "Every key is scoped and rate-limited to your plan from the moment it\'s created.",\n },\n {\n step: "03",\n title: "Call any endpoint",\n description:\n "Users, orders, products, posts, and webhooks \u2014 all documented, all live.",\n },\n ]}\n />\n <ApiShowcaseSection\n apiShowcase={{\n title: "Sample endpoints",\n subtitle:\n "A slice of what\'s available \u2014 see the full reference in the docs.",\n browseAllHref: "/api",\n browseAllLabel: "Browse all APIs",\n layout: "list",\n items: [\n {\n name: "List paginated users",\n path: "/v1/users",\n method: "GET",\n summary: "List paginated users",\n },\n {\n name: "Create a mock order",\n path: "/v1/orders",\n method: "POST",\n summary: "Create a mock order",\n },\n {\n name: "Fetch one product",\n path: "/v1/products/{id}",\n method: "GET",\n summary: "Fetch one product",\n },\n {\n name: "List posts with comments",\n path: "/v1/posts",\n method: "GET",\n summary: "List posts with comments",\n },\n {\n name: "Fire a test webhook event",\n path: "/v1/webhooks/test",\n method: "POST",\n summary: "Fire a test webhook event",\n },\n {\n name: "Delete a mock order",\n path: "/v1/orders/{id}",\n method: "DELETE",\n summary: "Delete a mock order",\n },\n ],\n }}\n />\n <PlansPreviewSection\n plans={[\n {\n name: "Free",\n price: "$0",\n unit: "per month",\n blurb: "1,000 requests/mo.",\n },\n {\n name: "Developer",\n price: "$19",\n unit: "per month",\n blurb: "50,000 requests/mo, webhooks included.",\n featured: true,\n },\n {\n name: "Team",\n price: "$79",\n unit: "per month",\n blurb: "500,000 requests/mo, 5 team seats.",\n },\n {\n name: "Enterprise",\n price: "Custom",\n unit: "talk to us",\n blurb: "Unlimited requests, SSO, SLA.",\n },\n ]}\n />\n <PricingCtaSection\n variant="banner"\n pricingCta={{\n title: "Start testing in minutes",\n description:\n "Free tier includes 1,000 requests a month \u2014 no card required.",\n primaryAction: { label: "Start for free", href: "/signup" },\n }}\n />\n </LandingShell>\n );\n}\n';
15654
15838
  var ACCOUNT_PLANS_PAGE_SOURCE = `export { AccountPlansPage as default } from "@lukoweb/apitogo-plugin-dev-portal-billing";
15655
15839
  `;
15656
15840
  var DASHBOARD_PAGE_SOURCE = `export { OverviewDashboardPage as default } from "@lukoweb/apitogo-plugin-dev-portal-billing";
@@ -15664,46 +15848,46 @@ var fileExists2 = async (filePath) => {
15664
15848
  }
15665
15849
  };
15666
15850
  async function ensurePortalStubFiles(dir) {
15667
- const landingPath = path48.join(dir, "landing", "LandingPage.tsx");
15851
+ const landingPath = path49.join(dir, "landing", "LandingPage.tsx");
15668
15852
  if (!await fileExists2(landingPath)) {
15669
- await mkdir9(path48.join(dir, "landing"), { recursive: true });
15670
- await writeFile11(landingPath, LANDING_PAGE_SOURCE, "utf8");
15853
+ await mkdir9(path49.join(dir, "landing"), { recursive: true });
15854
+ await writeFile12(landingPath, LANDING_PAGE_SOURCE, "utf8");
15671
15855
  }
15672
- const plansPath = path48.join(dir, "user-panel", "AccountPlansPage.tsx");
15856
+ const plansPath = path49.join(dir, "user-panel", "AccountPlansPage.tsx");
15673
15857
  if (!await fileExists2(plansPath)) {
15674
- await mkdir9(path48.join(dir, "user-panel"), { recursive: true });
15675
- await writeFile11(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
15858
+ await mkdir9(path49.join(dir, "user-panel"), { recursive: true });
15859
+ await writeFile12(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
15676
15860
  }
15677
- const dashboardPath = path48.join(dir, "user-panel", "DashboardPage.tsx");
15861
+ const dashboardPath = path49.join(dir, "user-panel", "DashboardPage.tsx");
15678
15862
  if (!await fileExists2(dashboardPath)) {
15679
- await mkdir9(path48.join(dir, "user-panel"), { recursive: true });
15680
- await writeFile11(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
15863
+ await mkdir9(path49.join(dir, "user-panel"), { recursive: true });
15864
+ await writeFile12(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
15681
15865
  }
15682
15866
  await ensurePublicBrandingFiles(dir);
15683
15867
  }
15684
15868
  async function ensurePublicBrandingFiles(dir) {
15685
- const destDir = path48.join(dir, "public");
15869
+ const destDir = path49.join(dir, "public");
15686
15870
  await mkdir9(destDir, { recursive: true });
15687
15871
  for (const { name, content } of BRANDING_ASSETS) {
15688
- const dest = path48.join(destDir, name);
15872
+ const dest = path49.join(destDir, name);
15689
15873
  if (await fileExists2(dest)) {
15690
15874
  continue;
15691
15875
  }
15692
- await writeFile11(dest, content, "utf8");
15876
+ await writeFile12(dest, content, "utf8");
15693
15877
  }
15694
15878
  }
15695
15879
  async function ensureThinConfigTsx(dir) {
15696
- const tsxPath = path48.join(dir, "apitogo.config.tsx");
15880
+ const tsxPath = path49.join(dir, "apitogo.config.tsx");
15697
15881
  if (await fileExists2(tsxPath)) {
15698
15882
  return false;
15699
15883
  }
15700
- await writeFile11(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
15884
+ await writeFile12(tsxPath, THIN_WRAPPER_SOURCE, "utf8");
15701
15885
  return true;
15702
15886
  }
15703
15887
 
15704
15888
  // src/cli/platform/helpers/openapi-action-keys.ts
15705
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
15706
- import path49 from "node:path";
15889
+ import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
15890
+ import path50 from "node:path";
15707
15891
  import YAML2 from "yaml";
15708
15892
  var HTTP_METHODS = [
15709
15893
  "get",
@@ -15772,7 +15956,7 @@ function extractGatewayActionKeysFromOpenApiDocument(document) {
15772
15956
  function extractGatewayActionKeysFromOpenApiFile(filePath) {
15773
15957
  try {
15774
15958
  const raw = readFileSync3(filePath, "utf8");
15775
- const ext = path49.extname(filePath).toLowerCase();
15959
+ const ext = path50.extname(filePath).toLowerCase();
15776
15960
  const parsed = ext === ".json" ? JSON.parse(raw) : YAML2.parse(raw);
15777
15961
  return extractGatewayActionKeysFromOpenApiDocument(parsed);
15778
15962
  } catch {
@@ -15793,8 +15977,8 @@ function resolveConfigOpenApiFilePath(siteDirectory, config2) {
15793
15977
  }
15794
15978
  }
15795
15979
  for (const candidate of candidates) {
15796
- const resolved = path49.isAbsolute(candidate) ? candidate : path49.resolve(siteDirectory, candidate);
15797
- if (existsSync4(resolved)) {
15980
+ const resolved = path50.isAbsolute(candidate) ? candidate : path50.resolve(siteDirectory, candidate);
15981
+ if (existsSync5(resolved)) {
15798
15982
  return resolved;
15799
15983
  }
15800
15984
  }
@@ -15808,8 +15992,8 @@ function loadOpenApiActionKeysForSite(siteDirectory, config2) {
15808
15992
  return extractGatewayActionKeysFromOpenApiFile(filePath);
15809
15993
  }
15810
15994
  function loadOpenApiActionKeysFromSiteDirectory(siteDirectory) {
15811
- const configPath = path49.join(siteDirectory, "apitogo.config.json");
15812
- if (!existsSync4(configPath)) {
15995
+ const configPath = path50.join(siteDirectory, "apitogo.config.json");
15996
+ if (!existsSync5(configPath)) {
15813
15997
  return [];
15814
15998
  }
15815
15999
  try {
@@ -15833,7 +16017,7 @@ function withDefaultIncludedActionKeys(plan, actionKeys) {
15833
16017
  }
15834
16018
 
15835
16019
  // src/cli/make-config/handler.ts
15836
- var toPosixPath2 = (value) => value.split(path50.sep).join(path50.posix.sep);
16020
+ var toPosixPath2 = (value) => value.split(path51.sep).join(path51.posix.sep);
15837
16021
  var fileExists3 = async (filePath) => {
15838
16022
  try {
15839
16023
  await access8(filePath, constants2.F_OK);
@@ -15843,7 +16027,7 @@ var fileExists3 = async (filePath) => {
15843
16027
  }
15844
16028
  };
15845
16029
  var readJsonConfig = async (filePath) => {
15846
- const raw = await readFile13(filePath, "utf8");
16030
+ const raw = await readFile14(filePath, "utf8");
15847
16031
  const parsed = JSON.parse(raw);
15848
16032
  if (!isPlainObject3(parsed)) {
15849
16033
  throw new Error(`${APITOGO_JSON_FILENAME} must be a JSON object.`);
@@ -15889,13 +16073,13 @@ async function persistConfig(config2, ctx) {
15889
16073
  force: ctx.force
15890
16074
  })
15891
16075
  };
15892
- await writeFile12(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
16076
+ await writeFile13(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
15893
16077
  `, "utf8");
15894
- const tsxPath = path50.join(ctx.dir, "apitogo.config.tsx");
16078
+ const tsxPath = path51.join(ctx.dir, "apitogo.config.tsx");
15895
16079
  if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
15896
- const tsxSource = await readFile13(tsxPath, "utf8");
16080
+ const tsxSource = await readFile14(tsxPath, "utf8");
15897
16081
  if (isManagedConfigWrapper(tsxSource)) {
15898
- await writeFile12(
16082
+ await writeFile13(
15899
16083
  tsxPath,
15900
16084
  buildThinWrapperWithCustomPages(tsxRoutes),
15901
16085
  "utf8"
@@ -15918,7 +16102,7 @@ function mergeBackendFlag(config2, backend) {
15918
16102
  return next;
15919
16103
  }
15920
16104
  async function makeConfig(argv) {
15921
- const dir = path50.resolve(process.cwd(), argv.dir);
16105
+ const dir = path51.resolve(process.cwd(), argv.dir);
15922
16106
  const pagesDir = toPosixPath2(
15923
16107
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
15924
16108
  );
@@ -15938,14 +16122,14 @@ async function makeConfig(argv) {
15938
16122
  printDiagnosticsToConsole("Created tsconfig.json.");
15939
16123
  }
15940
16124
  await ensurePortalStubFiles(dir);
15941
- const jsonPath = path50.join(dir, APITOGO_JSON_FILENAME);
16125
+ const jsonPath = path51.join(dir, APITOGO_JSON_FILENAME);
15942
16126
  let createdJson = false;
15943
16127
  let config2;
15944
16128
  if (await fileExists3(jsonPath)) {
15945
16129
  config2 = await readJsonConfig(jsonPath);
15946
16130
  } else {
15947
16131
  config2 = createDefaultApitogoJsonConfig({
15948
- title: titleFromDirectoryName(path50.basename(dir)),
16132
+ title: titleFromDirectoryName(path51.basename(dir)),
15949
16133
  pagesDir
15950
16134
  });
15951
16135
  createdJson = true;
@@ -15994,9 +16178,9 @@ async function makeConfig(argv) {
15994
16178
  return;
15995
16179
  }
15996
16180
  if (action2.kind === "page") {
15997
- const pagePath = path50.join(dir, action2.page.relativePath);
15998
- await mkdir10(path50.dirname(pagePath), { recursive: true });
15999
- await writeFile12(
16181
+ const pagePath = path51.join(dir, action2.page.relativePath);
16182
+ await mkdir10(path51.dirname(pagePath), { recursive: true });
16183
+ await writeFile13(
16000
16184
  pagePath,
16001
16185
  buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
16002
16186
  "utf8"
@@ -16062,7 +16246,7 @@ async function makeConfig(argv) {
16062
16246
  if (argv.openapi) {
16063
16247
  const wire = await wireDevPortalOpenApi(
16064
16248
  dir,
16065
- path50.resolve(dir, argv.openapi)
16249
+ path51.resolve(dir, argv.openapi)
16066
16250
  );
16067
16251
  if (wire.status !== "succeeded") {
16068
16252
  throw new Error(
@@ -16091,7 +16275,7 @@ async function makeConfig(argv) {
16091
16275
  const slug = normalizePageSlug(argv.pageSlug);
16092
16276
  const pageTemplate = normalizePageTemplate(argv.pageTemplate);
16093
16277
  const relativePagePath = pageComponentRelativePath(slug);
16094
- const filePath = path50.join(dir, relativePagePath);
16278
+ const filePath = path51.join(dir, relativePagePath);
16095
16279
  const isUpdate = argv.pageUpdate === true;
16096
16280
  if (isUpdate) {
16097
16281
  if (!await fileExists3(filePath)) {
@@ -16105,7 +16289,7 @@ async function makeConfig(argv) {
16105
16289
  argv.pageContent,
16106
16290
  pageTemplate
16107
16291
  );
16108
- await writeFile12(filePath, tsx, "utf8");
16292
+ await writeFile13(filePath, tsx, "utf8");
16109
16293
  pageResult = {
16110
16294
  action: "updated",
16111
16295
  slug,
@@ -16124,8 +16308,8 @@ async function makeConfig(argv) {
16124
16308
  argv.pageContent,
16125
16309
  pageTemplate
16126
16310
  );
16127
- await mkdir10(path50.dirname(filePath), { recursive: true });
16128
- await writeFile12(filePath, tsx, "utf8");
16311
+ await mkdir10(path51.dirname(filePath), { recursive: true });
16312
+ await writeFile13(filePath, tsx, "utf8");
16129
16313
  const configResult = await wireNewDevPortalPageInConfig(
16130
16314
  dir,
16131
16315
  slug,
@@ -16137,7 +16321,7 @@ async function makeConfig(argv) {
16137
16321
  pagePath: relativePagePath,
16138
16322
  pageTemplate,
16139
16323
  configUpdated: configResult.updated,
16140
- configPath: configResult.configPath ? path50.relative(dir, configResult.configPath) : null
16324
+ configPath: configResult.configPath ? path51.relative(dir, configResult.configPath) : null
16141
16325
  };
16142
16326
  changes.push("page_add");
16143
16327
  }
@@ -16265,7 +16449,7 @@ var config_default = {
16265
16449
  // src/cli/cmds/configure-github-workflow.ts
16266
16450
  var REMOVED = "apitogo configure-github-workflow was removed. Multi-env SWA deploy is deprecated; use `apitogo deploy`.";
16267
16451
  var configure_github_workflow_default = {
16268
- desc: "Removed \u2014 multi-env SWA deploy is deprecated",
16452
+ describe: false,
16269
16453
  command: "configure-github-workflow",
16270
16454
  builder: (yargs2) => yargs2,
16271
16455
  handler: async (argv) => {
@@ -16278,7 +16462,7 @@ var configure_github_workflow_default = {
16278
16462
  };
16279
16463
 
16280
16464
  // src/cli/apply/handler.ts
16281
- import path61 from "node:path";
16465
+ import path62 from "node:path";
16282
16466
 
16283
16467
  // src/cli/platform/tools/dev-portal-publish.ts
16284
16468
  init_gateway_limits();
@@ -17437,16 +17621,16 @@ async function validateDevPortalReadiness(client, projectId, options) {
17437
17621
  }
17438
17622
 
17439
17623
  // src/cli/platform/helpers/publish-ledger.ts
17440
- import { mkdir as mkdir11, readFile as readFile14, writeFile as writeFile13 } from "node:fs/promises";
17441
- import path51 from "node:path";
17624
+ import { mkdir as mkdir11, readFile as readFile15, writeFile as writeFile14 } from "node:fs/promises";
17625
+ import path52 from "node:path";
17442
17626
  var PUBLISH_LEDGER_RELATIVE_PATH = ".apitogo/publish-state.json";
17443
17627
  function publishLedgerPath(siteDirectory) {
17444
- return path51.join(path51.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
17628
+ return path52.join(path52.resolve(siteDirectory), PUBLISH_LEDGER_RELATIVE_PATH);
17445
17629
  }
17446
17630
  async function readPublishLedger(siteDirectory) {
17447
17631
  const filePath = publishLedgerPath(siteDirectory);
17448
17632
  try {
17449
- const raw = await readFile14(filePath, "utf8");
17633
+ const raw = await readFile15(filePath, "utf8");
17450
17634
  const parsed = JSON.parse(raw);
17451
17635
  if (parsed?.version !== 1 || !Array.isArray(parsed.steps)) {
17452
17636
  return null;
@@ -17458,13 +17642,13 @@ async function readPublishLedger(siteDirectory) {
17458
17642
  }
17459
17643
  async function writePublishLedger(siteDirectory, ledger) {
17460
17644
  const filePath = publishLedgerPath(siteDirectory);
17461
- await mkdir11(path51.dirname(filePath), { recursive: true });
17645
+ await mkdir11(path52.dirname(filePath), { recursive: true });
17462
17646
  const next = {
17463
17647
  ...ledger,
17464
17648
  version: 1,
17465
17649
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
17466
17650
  };
17467
- await writeFile13(filePath, `${JSON.stringify(next, null, 2)}
17651
+ await writeFile14(filePath, `${JSON.stringify(next, null, 2)}
17468
17652
  `, "utf8");
17469
17653
  return filePath;
17470
17654
  }
@@ -17529,11 +17713,11 @@ async function waitForGatewayActionsRegistered(client, projectId, options) {
17529
17713
  // src/cli/platform/helpers/deploy-artifact-hash.ts
17530
17714
  import { createHash as createHash2 } from "node:crypto";
17531
17715
  import { createReadStream, promises as fs7 } from "node:fs";
17532
- import path53 from "node:path";
17716
+ import path54 from "node:path";
17533
17717
 
17534
17718
  // src/cli/platform/helpers/package-files.ts
17535
17719
  import { promises as fs6 } from "node:fs";
17536
- import path52 from "node:path";
17720
+ import path53 from "node:path";
17537
17721
  import ignore from "ignore";
17538
17722
  var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
17539
17723
  "node_modules",
@@ -17546,7 +17730,7 @@ var DEFAULT_EXCLUDES = /* @__PURE__ */ new Set([
17546
17730
  async function loadGitignore(rootDir) {
17547
17731
  const ig = ignore();
17548
17732
  ig.add(["node_modules/", ".git/", "dist/", "bin/", "obj/"]);
17549
- const gitignorePath = path52.join(rootDir, ".gitignore");
17733
+ const gitignorePath = path53.join(rootDir, ".gitignore");
17550
17734
  try {
17551
17735
  const content = await fs6.readFile(gitignorePath, "utf8");
17552
17736
  ig.add(content);
@@ -17555,11 +17739,11 @@ async function loadGitignore(rootDir) {
17555
17739
  return ig;
17556
17740
  }
17557
17741
  async function collectFiles(rootDir, relativeDir, ig, files) {
17558
- const absDir = path52.join(rootDir, relativeDir);
17742
+ const absDir = path53.join(rootDir, relativeDir);
17559
17743
  const entries = await fs6.readdir(absDir, { withFileTypes: true });
17560
17744
  for (const entry of entries) {
17561
- const rel = relativeDir ? path52.join(relativeDir, entry.name) : entry.name;
17562
- const relPosix = rel.split(path52.sep).join("/");
17745
+ const rel = relativeDir ? path53.join(relativeDir, entry.name) : entry.name;
17746
+ const relPosix = rel.split(path53.sep).join("/");
17563
17747
  if (DEFAULT_EXCLUDES.has(entry.name) && !relativeDir) {
17564
17748
  continue;
17565
17749
  }
@@ -17574,7 +17758,7 @@ async function collectFiles(rootDir, relativeDir, ig, files) {
17574
17758
  }
17575
17759
  }
17576
17760
  async function collectPackageableFiles(sourceDirectory) {
17577
- const resolved = path52.resolve(sourceDirectory);
17761
+ const resolved = path53.resolve(sourceDirectory);
17578
17762
  const stat4 = await fs6.stat(resolved).catch(() => null);
17579
17763
  if (!stat4?.isDirectory()) {
17580
17764
  throw new Error(`sourceDirectory is not a directory: ${resolved}`);
@@ -17600,19 +17784,19 @@ async function sha256File(filePath) {
17600
17784
  return hash2.digest("hex");
17601
17785
  }
17602
17786
  async function hashDirectoryContents(rootDirectory) {
17603
- const resolved = path53.resolve(rootDirectory);
17787
+ const resolved = path54.resolve(rootDirectory);
17604
17788
  const files = (await collectPackageableFiles(resolved)).sort((a, b) => a.localeCompare(b));
17605
17789
  const hash2 = createHash2("sha256");
17606
17790
  for (const rel of files) {
17607
17791
  hash2.update(rel);
17608
17792
  hash2.update("\0");
17609
- hash2.update(await fs7.readFile(path53.join(resolved, rel)));
17793
+ hash2.update(await fs7.readFile(path54.join(resolved, rel)));
17610
17794
  hash2.update("\0");
17611
17795
  }
17612
17796
  return hash2.digest("hex");
17613
17797
  }
17614
17798
  async function hashDevPortalSiteSources(siteDirectory, options) {
17615
- const resolved = path53.resolve(siteDirectory);
17799
+ const resolved = path54.resolve(siteDirectory);
17616
17800
  const hash2 = createHash2("sha256");
17617
17801
  const candidates = [
17618
17802
  "apitogo.config.json",
@@ -17622,7 +17806,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
17622
17806
  "zudoku.config.tsx"
17623
17807
  ];
17624
17808
  for (const name of candidates) {
17625
- const full = path53.join(resolved, name);
17809
+ const full = path54.join(resolved, name);
17626
17810
  try {
17627
17811
  hash2.update(name);
17628
17812
  hash2.update("\0");
@@ -17632,7 +17816,7 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
17632
17816
  }
17633
17817
  }
17634
17818
  for (const dir of ["pages", "landing", "src"]) {
17635
- const full = path53.join(resolved, dir);
17819
+ const full = path54.join(resolved, dir);
17636
17820
  try {
17637
17821
  const st = await fs7.stat(full);
17638
17822
  if (!st.isDirectory()) continue;
@@ -17654,8 +17838,8 @@ async function hashDevPortalSiteSources(siteDirectory, options) {
17654
17838
  }
17655
17839
 
17656
17840
  // src/cli/platform/helpers/openapi-gateway-servers.ts
17657
- import { mkdir as mkdir12, readFile as readFile15, writeFile as writeFile14 } from "node:fs/promises";
17658
- import path54 from "node:path";
17841
+ import { mkdir as mkdir12, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
17842
+ import path55 from "node:path";
17659
17843
  import YAML3 from "yaml";
17660
17844
  var GATEWAY_URL_ENV_KEY = "APITOGO_GATEWAY_URL";
17661
17845
  var PUBLISH_OPENAPI_RELATIVE = ".apitogo/openapi-publish.json";
@@ -17686,8 +17870,8 @@ async function resolveProjectGatewayUrl(client, projectId) {
17686
17870
  return null;
17687
17871
  }
17688
17872
  async function readOpenApiDocument(filePath) {
17689
- const content = await readFile15(filePath, "utf8");
17690
- const ext = path54.extname(filePath).toLowerCase();
17873
+ const content = await readFile16(filePath, "utf8");
17874
+ const ext = path55.extname(filePath).toLowerCase();
17691
17875
  const parsed = ext === ".json" ? JSON.parse(content) : YAML3.parse(content);
17692
17876
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
17693
17877
  throw new Error(`OpenAPI document must be an object: ${filePath}`);
@@ -17695,20 +17879,20 @@ async function readOpenApiDocument(filePath) {
17695
17879
  return parsed;
17696
17880
  }
17697
17881
  async function materializePublishOpenApiWithGateway(siteDirectory, sourceOpenApiPath, gatewayUrl) {
17698
- const site = path54.resolve(siteDirectory);
17699
- const source = path54.resolve(sourceOpenApiPath);
17882
+ const site = path55.resolve(siteDirectory);
17883
+ const source = path55.resolve(sourceOpenApiPath);
17700
17884
  const relativeInput = PUBLISH_OPENAPI_RELATIVE;
17701
- const outputPath = path54.join(site, ...relativeInput.split("/"));
17885
+ const outputPath = path55.join(site, ...relativeInput.split("/"));
17702
17886
  const doc = await readOpenApiDocument(source);
17703
17887
  const rewritten = withGatewayServers(doc, gatewayUrl);
17704
- await mkdir12(path54.dirname(outputPath), { recursive: true });
17705
- await writeFile14(outputPath, `${JSON.stringify(rewritten, null, 2)}
17888
+ await mkdir12(path55.dirname(outputPath), { recursive: true });
17889
+ await writeFile15(outputPath, `${JSON.stringify(rewritten, null, 2)}
17706
17890
  `, "utf8");
17707
17891
  return { outputPath, relativeInput };
17708
17892
  }
17709
17893
  async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
17710
- const configPath = path54.join(path54.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
17711
- const raw = await readFile15(configPath, "utf8");
17894
+ const configPath = path55.join(path55.resolve(siteDirectory), APITOGO_CONFIG_FILENAME2);
17895
+ const raw = await readFile16(configPath, "utf8");
17712
17896
  const config2 = JSON.parse(raw);
17713
17897
  const previousApis = config2.apis;
17714
17898
  const previousBackend = config2.backend;
@@ -17721,11 +17905,11 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
17721
17905
  const backend = config2.backend && typeof config2.backend === "object" ? { ...config2.backend } : {};
17722
17906
  backend.openApiPath = relativeInput;
17723
17907
  config2.backend = backend;
17724
- await writeFile14(configPath, `${JSON.stringify(config2, null, 2)}
17908
+ await writeFile15(configPath, `${JSON.stringify(config2, null, 2)}
17725
17909
  `, "utf8");
17726
17910
  return {
17727
17911
  restore: async () => {
17728
- const currentRaw = await readFile15(configPath, "utf8");
17912
+ const currentRaw = await readFile16(configPath, "utf8");
17729
17913
  const current = JSON.parse(currentRaw);
17730
17914
  if (previousApis === void 0) {
17731
17915
  delete current.apis;
@@ -17737,20 +17921,20 @@ async function pointSiteApisAtPublishOpenApi(siteDirectory, relativeInput) {
17737
17921
  } else {
17738
17922
  current.backend = previousBackend;
17739
17923
  }
17740
- await writeFile14(configPath, `${JSON.stringify(current, null, 2)}
17924
+ await writeFile15(configPath, `${JSON.stringify(current, null, 2)}
17741
17925
  `, "utf8");
17742
17926
  }
17743
17927
  };
17744
17928
  }
17745
17929
  async function prepareOpenApiServersForGatewayBuild(options) {
17746
- const siteDirectory = path54.resolve(options.siteDirectory);
17930
+ const siteDirectory = path55.resolve(options.siteDirectory);
17747
17931
  let openApiPath = resolveBackendOpenApiPath(options.manifest?.backend?.openApiPath, {
17748
17932
  siteDirectory,
17749
17933
  backendSourceDirectory: options.manifest?.backend?.sourceDirectory
17750
17934
  });
17751
17935
  if (!openApiPath) {
17752
17936
  try {
17753
- const raw = await readFile15(path54.join(siteDirectory, APITOGO_CONFIG_FILENAME2), "utf8");
17937
+ const raw = await readFile16(path55.join(siteDirectory, APITOGO_CONFIG_FILENAME2), "utf8");
17754
17938
  const config2 = JSON.parse(raw);
17755
17939
  const input3 = Array.isArray(config2.apis) ? config2.apis[0]?.input?.trim() : void 0;
17756
17940
  openApiPath = resolveBackendOpenApiPath(input3, { siteDirectory });
@@ -17772,7 +17956,7 @@ async function prepareOpenApiServersForGatewayBuild(options) {
17772
17956
  // src/cli/platform/helpers/backend-packaging.ts
17773
17957
  import { mkdtemp, readdir, rm as rm5 } from "node:fs/promises";
17774
17958
  import { tmpdir } from "node:os";
17775
- import path55 from "node:path";
17959
+ import path56 from "node:path";
17776
17960
  import { spawn as spawn3 } from "node:child_process";
17777
17961
  async function directoryHasRuntimeConfig(dir) {
17778
17962
  if (!await pathExists(dir)) {
@@ -17816,20 +18000,20 @@ function runDotnetPublish(projectDir, outputDir) {
17816
18000
  async function findCsproj(projectDir) {
17817
18001
  const entries = await readdir(projectDir);
17818
18002
  const csproj = entries.find((name) => name.endsWith(".csproj"));
17819
- return csproj ? path55.join(projectDir, csproj) : null;
18003
+ return csproj ? path56.join(projectDir, csproj) : null;
17820
18004
  }
17821
18005
  async function prepareBackendPackagingDirectory(args) {
17822
- const sourceDirectory = path55.resolve(args.sourceDirectory);
18006
+ const sourceDirectory = path56.resolve(args.sourceDirectory);
17823
18007
  if (args.publishDirectory?.trim()) {
17824
18008
  return {
17825
- directory: path55.resolve(args.publishDirectory),
18009
+ directory: path56.resolve(args.publishDirectory),
17826
18010
  packagingMode: "published"
17827
18011
  };
17828
18012
  }
17829
18013
  if (await directoryHasRuntimeConfig(sourceDirectory)) {
17830
18014
  return { directory: sourceDirectory, packagingMode: "published" };
17831
18015
  }
17832
- const publishSubdir = path55.join(sourceDirectory, "publish");
18016
+ const publishSubdir = path56.join(sourceDirectory, "publish");
17833
18017
  if (await directoryHasRuntimeConfig(publishSubdir)) {
17834
18018
  return { directory: publishSubdir, packagingMode: "published" };
17835
18019
  }
@@ -17840,8 +18024,8 @@ async function prepareBackendPackagingDirectory(args) {
17840
18024
  if (!csproj) {
17841
18025
  return { directory: sourceDirectory, packagingMode: "source" };
17842
18026
  }
17843
- const tempRoot = await mkdtemp(path55.join(tmpdir(), "apitogo-dotnet-publish-"));
17844
- const outputDir = path55.join(tempRoot, "publish");
18027
+ const tempRoot = await mkdtemp(path56.join(tmpdir(), "apitogo-dotnet-publish-"));
18028
+ const outputDir = path56.join(tempRoot, "publish");
17845
18029
  const result = await runDotnetPublish(sourceDirectory, outputDir);
17846
18030
  if (result.exitCode !== 0) {
17847
18031
  await rm5(tempRoot, { recursive: true, force: true });
@@ -17887,12 +18071,12 @@ function formatJobStatusResponse(options) {
17887
18071
  // src/cli/platform/helpers/zip.ts
17888
18072
  import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, promises as fs8 } from "node:fs";
17889
18073
  import { tmpdir as tmpdir2 } from "node:os";
17890
- import path56 from "node:path";
18074
+ import path57 from "node:path";
17891
18075
  import { ZipArchive } from "archiver";
17892
18076
  async function packageBackendDirectory(sourceDirectory) {
17893
- const resolved = path56.resolve(sourceDirectory);
18077
+ const resolved = path57.resolve(sourceDirectory);
17894
18078
  const files = await collectPackageableFiles(resolved);
17895
- const zipPath = path56.join(
18079
+ const zipPath = path57.join(
17896
18080
  tmpdir2(),
17897
18081
  `apitogo-backend-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`
17898
18082
  );
@@ -17904,7 +18088,7 @@ async function packageBackendDirectory(sourceDirectory) {
17904
18088
  output2.on("error", reject);
17905
18089
  archive.pipe(output2);
17906
18090
  for (const rel of files) {
17907
- archive.append(createReadStream2(path56.join(resolved, rel)), { name: rel.split(path56.sep).join("/") });
18091
+ archive.append(createReadStream2(path57.join(resolved, rel)), { name: rel.split(path57.sep).join("/") });
17908
18092
  }
17909
18093
  void archive.finalize();
17910
18094
  });
@@ -19287,12 +19471,12 @@ async function resolveProjectIdForPublish(client, config2, args, wait, progress,
19287
19471
 
19288
19472
  // src/cli/platform/tools/dev-portal.ts
19289
19473
  import { promises as fs10 } from "node:fs";
19290
- import path59 from "node:path";
19474
+ import path60 from "node:path";
19291
19475
 
19292
19476
  // src/cli/platform/helpers/tarball.ts
19293
19477
  import { createReadStream as createReadStream3, createWriteStream as createWriteStream3, promises as fs9 } from "node:fs";
19294
19478
  import { tmpdir as tmpdir3 } from "node:os";
19295
- import path57 from "node:path";
19479
+ import path58 from "node:path";
19296
19480
  import { TarArchive } from "archiver";
19297
19481
  var DEV_PORTAL_DEPLOY_ARCHIVE_ROOT = "dist";
19298
19482
  function normalizeArchiveRoot(archiveRoot) {
@@ -19303,10 +19487,10 @@ function normalizeArchiveRoot(archiveRoot) {
19303
19487
  return `${trimmed}/`;
19304
19488
  }
19305
19489
  async function packageDirectoryAsTarGz(sourceDirectory, options) {
19306
- const resolved = path57.resolve(sourceDirectory);
19490
+ const resolved = path58.resolve(sourceDirectory);
19307
19491
  const files = await collectPackageableFiles(resolved);
19308
19492
  const entryPrefix = options?.archiveRoot ? normalizeArchiveRoot(options.archiveRoot) : "";
19309
- const archivePath = path57.join(
19493
+ const archivePath = path58.join(
19310
19494
  tmpdir3(),
19311
19495
  `apitogo-docs-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`
19312
19496
  );
@@ -19318,8 +19502,8 @@ async function packageDirectoryAsTarGz(sourceDirectory, options) {
19318
19502
  output2.on("error", reject);
19319
19503
  archive.pipe(output2);
19320
19504
  for (const rel of files) {
19321
- const entryName = entryPrefix + rel.split(path57.sep).join("/");
19322
- archive.append(createReadStream3(path57.join(resolved, rel)), { name: entryName });
19505
+ const entryName = entryPrefix + rel.split(path58.sep).join("/");
19506
+ archive.append(createReadStream3(path58.join(resolved, rel)), { name: entryName });
19323
19507
  }
19324
19508
  void archive.finalize();
19325
19509
  });
@@ -19442,8 +19626,8 @@ async function snapshotBackendUpdateJobIds(client, projectId) {
19442
19626
  }
19443
19627
 
19444
19628
  // src/cli/platform/helpers/dev-portal-site-api-url.ts
19445
- import { readdir as readdir2, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
19446
- import path58 from "node:path";
19629
+ import { readdir as readdir2, readFile as readFile17, writeFile as writeFile16 } from "node:fs/promises";
19630
+ import path59 from "node:path";
19447
19631
  var SITE_API_BASE_URL_ENV_KEY = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
19448
19632
  var PLACEHOLDER_HOST_MARKERS = [
19449
19633
  "dp-example.azurecontainerapps.io",
@@ -19461,10 +19645,10 @@ function isPlaceholderDevPortalApiUrl(apiBaseUrl) {
19461
19645
  return PLACEHOLDER_HOST_MARKERS.some((marker) => normalized.includes(marker));
19462
19646
  }
19463
19647
  async function readSiteApiBaseUrl(sourceDirectory) {
19464
- const resolved = path58.resolve(sourceDirectory);
19648
+ const resolved = path59.resolve(sourceDirectory);
19465
19649
  for (const envFile of [".env", ".env.production"]) {
19466
19650
  try {
19467
- const content = await readFile16(path58.join(resolved, envFile), "utf8");
19651
+ const content = await readFile17(path59.join(resolved, envFile), "utf8");
19468
19652
  const lines = [...content.matchAll(ENV_LINE_GLOBAL_RE)];
19469
19653
  if (lines.length === 0) {
19470
19654
  continue;
@@ -19489,25 +19673,25 @@ async function readSiteApiBaseUrl(sourceDirectory) {
19489
19673
  return null;
19490
19674
  }
19491
19675
  async function patchSiteApiBaseUrl(sourceDirectory, apiBaseUrl) {
19492
- const resolved = path58.resolve(sourceDirectory);
19676
+ const resolved = path59.resolve(sourceDirectory);
19493
19677
  const line = `${SITE_API_BASE_URL_ENV_KEY}=${apiBaseUrl}`;
19494
19678
  let patchedExisting = false;
19495
19679
  for (const envFile of [".env.production", ".env"]) {
19496
- const envPath = path58.join(resolved, envFile);
19680
+ const envPath = path59.join(resolved, envFile);
19497
19681
  try {
19498
- const content = await readFile16(envPath, "utf8");
19682
+ const content = await readFile17(envPath, "utf8");
19499
19683
  const withoutAssignments = content.replace(ENV_LINE_GLOBAL_RE, "").replace(/\n{3,}/g, "\n\n").trimEnd();
19500
19684
  const patched = withoutAssignments ? `${withoutAssignments}
19501
19685
  ${line}
19502
19686
  ` : `${line}
19503
19687
  `;
19504
- await writeFile15(envPath, patched);
19688
+ await writeFile16(envPath, patched);
19505
19689
  patchedExisting = true;
19506
19690
  } catch {
19507
19691
  }
19508
19692
  }
19509
19693
  if (!patchedExisting) {
19510
- await writeFile15(path58.join(resolved, ".env"), `${line}
19694
+ await writeFile16(path59.join(resolved, ".env"), `${line}
19511
19695
  `);
19512
19696
  }
19513
19697
  }
@@ -19515,7 +19699,7 @@ function tryProjectId(explicit, manifestProjectId, config2) {
19515
19699
  return explicit?.trim() || manifestProjectId?.trim() || config2.defaultProjectId?.trim() || void 0;
19516
19700
  }
19517
19701
  async function ensureLiveSiteApiBaseUrlForBuild(_client, config2, args, resolveFromProject) {
19518
- const sourceDirectory = path58.resolve(args.sourceDirectory);
19702
+ const sourceDirectory = path59.resolve(args.sourceDirectory);
19519
19703
  const explicit = args.apiBaseUrl?.trim();
19520
19704
  if (explicit && !isPlaceholderDevPortalApiUrl(explicit)) {
19521
19705
  await patchSiteApiBaseUrl(sourceDirectory, explicit);
@@ -19551,7 +19735,7 @@ async function* walkFiles(root) {
19551
19735
  return;
19552
19736
  }
19553
19737
  for (const entry of entries) {
19554
- const full = path58.join(root, entry.name);
19738
+ const full = path59.join(root, entry.name);
19555
19739
  if (entry.isDirectory()) {
19556
19740
  if (entry.name === "node_modules" || entry.name === ".git") {
19557
19741
  continue;
@@ -19563,8 +19747,8 @@ async function* walkFiles(root) {
19563
19747
  }
19564
19748
  }
19565
19749
  async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiBaseUrl) {
19566
- const dist = path58.resolve(distDirectory);
19567
- const siteRoot = path58.dirname(dist);
19750
+ const dist = path59.resolve(distDirectory);
19751
+ const siteRoot = path59.dirname(dist);
19568
19752
  const fromEnv = expectedApiBaseUrl?.trim() || await readSiteApiBaseUrl(siteRoot) || await readSiteApiBaseUrl(dist);
19569
19753
  if (!fromEnv || isPlaceholderDevPortalApiUrl(fromEnv)) {
19570
19754
  throw new Error(
@@ -19575,7 +19759,7 @@ async function assertDeployableDistHasLiveApiBaseUrl(distDirectory, expectedApiB
19575
19759
  let found = false;
19576
19760
  let foundPlaceholder = false;
19577
19761
  for await (const file of walkFiles(dist)) {
19578
- const content = await readFile16(file, "utf8");
19762
+ const content = await readFile17(file, "utf8");
19579
19763
  if (content.includes(needle)) {
19580
19764
  found = true;
19581
19765
  }
@@ -19819,7 +20003,7 @@ function validateDeployArchiveInput(args) {
19819
20003
  async function resolveDevPortalArchive(args) {
19820
20004
  validateDeployArchiveInput(args);
19821
20005
  if (args.archivePath?.trim()) {
19822
- const archivePath = path59.resolve(args.archivePath.trim());
20006
+ const archivePath = path60.resolve(args.archivePath.trim());
19823
20007
  const stat4 = await fs10.stat(archivePath).catch(() => null);
19824
20008
  if (!stat4?.isFile()) {
19825
20009
  throw new Error(`archivePath is not a file: ${archivePath}`);
@@ -19887,10 +20071,10 @@ async function handleDeployDevPortal(client, config2, args, progress) {
19887
20071
  }
19888
20072
 
19889
20073
  // src/cli/platform/tools/dev-portal-site-build.ts
19890
- import path60 from "node:path";
20074
+ import path61 from "node:path";
19891
20075
  async function handleBuildDevPortalSite(client, config2, args, progress) {
19892
20076
  const buildProgress = progress?.child("Build dev portal site");
19893
- const sourceDirectory = path60.resolve(args.sourceDirectory);
20077
+ const sourceDirectory = path61.resolve(args.sourceDirectory);
19894
20078
  await buildProgress?.onStep("Ensuring live portal API URL");
19895
20079
  const apiBaseUrl = await ensureLiveSiteApiBaseUrlForBuild(
19896
20080
  client,
@@ -20864,7 +21048,7 @@ function resultLooksFailed(payload) {
20864
21048
  }
20865
21049
  }
20866
21050
  async function apply(argv) {
20867
- const sourceDirectory = path61.resolve(process.cwd(), argv.dir);
21051
+ const sourceDirectory = path62.resolve(process.cwd(), argv.dir);
20868
21052
  const config2 = loadConfig();
20869
21053
  const client = new PlatformApiClient(config2);
20870
21054
  let only;
@@ -20950,11 +21134,11 @@ var deploy_default = {
20950
21134
  };
20951
21135
 
20952
21136
  // src/cli/init/handler.ts
20953
- import path64 from "node:path";
21137
+ import path65 from "node:path";
20954
21138
 
20955
21139
  // src/cli/scaffold/run-scaffold-discovery.ts
20956
- import { access as access10, readFile as readFile18, writeFile as writeFile17 } from "node:fs/promises";
20957
- import path63 from "node:path";
21140
+ import { access as access10, readFile as readFile19, writeFile as writeFile18 } from "node:fs/promises";
21141
+ import path64 from "node:path";
20958
21142
 
20959
21143
  // src/cli/scaffold/wire-docs.ts
20960
21144
  import {
@@ -20962,12 +21146,12 @@ import {
20962
21146
  lstat,
20963
21147
  mkdir as mkdir13,
20964
21148
  readdir as readdir3,
20965
- readFile as readFile17,
21149
+ readFile as readFile18,
20966
21150
  readlink,
20967
21151
  symlink,
20968
- writeFile as writeFile16
21152
+ writeFile as writeFile17
20969
21153
  } from "node:fs/promises";
20970
- import path62 from "node:path";
21154
+ import path63 from "node:path";
20971
21155
  var DOCS_DIR_WHITELIST = [
20972
21156
  "docs",
20973
21157
  "documents",
@@ -21004,14 +21188,14 @@ async function isDirectory(filePath) {
21004
21188
  }
21005
21189
  }
21006
21190
  function toPosix2(value) {
21007
- return value.split(path62.sep).join(path62.posix.sep);
21191
+ return value.split(path63.sep).join(path63.posix.sep);
21008
21192
  }
21009
21193
  function isWhitelistedDirName(name) {
21010
21194
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
21011
21195
  }
21012
21196
  function isInside2(parent, child) {
21013
- const relative = path62.relative(parent, child);
21014
- return relative === "" || !relative.startsWith("..") && !path62.isAbsolute(relative);
21197
+ const relative = path63.relative(parent, child);
21198
+ return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
21015
21199
  }
21016
21200
  async function collectMarkdownFiles(dir) {
21017
21201
  const files = [];
@@ -21025,7 +21209,7 @@ async function collectMarkdownFiles(dir) {
21025
21209
  if (entry.name.startsWith(".")) {
21026
21210
  continue;
21027
21211
  }
21028
- const full = path62.join(dir, entry.name);
21212
+ const full = path63.join(dir, entry.name);
21029
21213
  if (entry.isDirectory()) {
21030
21214
  if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink()) {
21031
21215
  continue;
@@ -21040,11 +21224,11 @@ async function collectMarkdownFiles(dir) {
21040
21224
  return files;
21041
21225
  }
21042
21226
  async function collectSearchRoots(siteDirectory) {
21043
- const site = path62.resolve(siteDirectory);
21044
- const parent = path62.dirname(site);
21227
+ const site = path63.resolve(siteDirectory);
21228
+ const parent = path63.dirname(site);
21045
21229
  const roots = [];
21046
21230
  const add = (dir) => {
21047
- const resolved = path62.resolve(dir);
21231
+ const resolved = path63.resolve(dir);
21048
21232
  if (!roots.includes(resolved)) {
21049
21233
  roots.push(resolved);
21050
21234
  }
@@ -21057,7 +21241,7 @@ async function collectSearchRoots(siteDirectory) {
21057
21241
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
21058
21242
  continue;
21059
21243
  }
21060
- add(path62.join(parent, entry.name));
21244
+ add(path63.join(parent, entry.name));
21061
21245
  }
21062
21246
  } catch {
21063
21247
  }
@@ -21066,13 +21250,13 @@ async function collectSearchRoots(siteDirectory) {
21066
21250
  return roots;
21067
21251
  }
21068
21252
  async function discoverNearbyDocsDirectories(siteDirectory) {
21069
- const site = path62.resolve(siteDirectory);
21070
- const sitePages = path62.join(site, PAGES_DIR);
21253
+ const site = path63.resolve(siteDirectory);
21254
+ const sitePages = path63.join(site, PAGES_DIR);
21071
21255
  const searchedDirectories = await collectSearchRoots(site);
21072
21256
  const directories = [];
21073
21257
  const seen = /* @__PURE__ */ new Set();
21074
21258
  const consider = async (dir) => {
21075
- const resolved = path62.resolve(dir);
21259
+ const resolved = path63.resolve(dir);
21076
21260
  if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
21077
21261
  return;
21078
21262
  }
@@ -21089,7 +21273,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21089
21273
  directories.push({ sourceDirectory: resolved, files });
21090
21274
  };
21091
21275
  for (const root of searchedDirectories) {
21092
- if (isWhitelistedDirName(path62.basename(root))) {
21276
+ if (isWhitelistedDirName(path63.basename(root))) {
21093
21277
  await consider(root);
21094
21278
  }
21095
21279
  try {
@@ -21101,7 +21285,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21101
21285
  if (!isWhitelistedDirName(entry.name)) {
21102
21286
  continue;
21103
21287
  }
21104
- await consider(path62.join(root, entry.name));
21288
+ await consider(path63.join(root, entry.name));
21105
21289
  }
21106
21290
  } catch {
21107
21291
  }
@@ -21112,8 +21296,8 @@ function slugifyDirName(name) {
21112
21296
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
21113
21297
  }
21114
21298
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
21115
- const base = slugifyDirName(path62.basename(sourceDirectory));
21116
- const parent = slugifyDirName(path62.basename(path62.dirname(sourceDirectory)));
21299
+ const base = slugifyDirName(path63.basename(sourceDirectory));
21300
+ const parent = slugifyDirName(path63.basename(path63.dirname(sourceDirectory)));
21117
21301
  const candidates = [base, `${parent}-${base}`];
21118
21302
  let index = 2;
21119
21303
  while (true) {
@@ -21121,7 +21305,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
21121
21305
  if (used.has(name)) {
21122
21306
  continue;
21123
21307
  }
21124
- const target = path62.join(pagesDir, name);
21308
+ const target = path63.join(pagesDir, name);
21125
21309
  if (await pathExists5(target)) {
21126
21310
  const stat4 = await lstat(target);
21127
21311
  if (!stat4.isDirectory() || !await isManagedLinkDir(target)) {
@@ -21152,8 +21336,8 @@ async function alreadyLinked(linkPath, sourcePath) {
21152
21336
  return false;
21153
21337
  }
21154
21338
  const current = await readlink(linkPath);
21155
- const resolved = path62.resolve(path62.dirname(linkPath), current);
21156
- return resolved === path62.resolve(sourcePath);
21339
+ const resolved = path63.resolve(path63.dirname(linkPath), current);
21340
+ return resolved === path63.resolve(sourcePath);
21157
21341
  } catch {
21158
21342
  return false;
21159
21343
  }
@@ -21165,8 +21349,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
21165
21349
  if (await pathExists5(linkPath)) {
21166
21350
  return "skipped";
21167
21351
  }
21168
- await mkdir13(path62.dirname(linkPath), { recursive: true });
21169
- const relativeTarget = path62.relative(path62.dirname(linkPath), sourcePath);
21352
+ await mkdir13(path63.dirname(linkPath), { recursive: true });
21353
+ const relativeTarget = path63.relative(path63.dirname(linkPath), sourcePath);
21170
21354
  await symlink(
21171
21355
  relativeTarget,
21172
21356
  linkPath,
@@ -21181,11 +21365,11 @@ async function applyDocsNavigation(siteDirectory, routes) {
21181
21365
  if (routes.length === 0) {
21182
21366
  return;
21183
21367
  }
21184
- const configPath = path62.join(siteDirectory, CONFIG_FILENAME);
21368
+ const configPath = path63.join(siteDirectory, CONFIG_FILENAME);
21185
21369
  if (!await pathExists5(configPath)) {
21186
21370
  return;
21187
21371
  }
21188
- const raw = await readFile17(configPath, "utf8");
21372
+ const raw = await readFile18(configPath, "utf8");
21189
21373
  const parsed = JSON.parse(raw);
21190
21374
  if (!isPlainObject4(parsed)) {
21191
21375
  return;
@@ -21193,12 +21377,12 @@ async function applyDocsNavigation(siteDirectory, routes) {
21193
21377
  parsed.navigation = mergeDocumentationNavigation(parsed.navigation, routes, {
21194
21378
  force: false
21195
21379
  });
21196
- await writeFile16(configPath, `${JSON.stringify(parsed, null, 2)}
21380
+ await writeFile17(configPath, `${JSON.stringify(parsed, null, 2)}
21197
21381
  `, "utf8");
21198
21382
  }
21199
21383
  async function discoverAndWireDocs(siteDirectory) {
21200
- const site = path62.resolve(siteDirectory);
21201
- const pagesDir = path62.join(site, PAGES_DIR);
21384
+ const site = path63.resolve(siteDirectory);
21385
+ const pagesDir = path63.join(site, PAGES_DIR);
21202
21386
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
21203
21387
  if (directories.length === 0) {
21204
21388
  return {
@@ -21220,14 +21404,14 @@ async function discoverAndWireDocs(siteDirectory) {
21220
21404
  directory.sourceDirectory,
21221
21405
  usedNames
21222
21406
  );
21223
- const linkDirectory = path62.join(pagesDir, linkName);
21407
+ const linkDirectory = path63.join(pagesDir, linkName);
21224
21408
  const linked = [];
21225
21409
  const skipped = [];
21226
21410
  for (const sourcePath of directory.files) {
21227
21411
  const relativeSource = toPosix2(
21228
- path62.relative(directory.sourceDirectory, sourcePath)
21412
+ path63.relative(directory.sourceDirectory, sourcePath)
21229
21413
  );
21230
- const linkPath = path62.join(linkDirectory, relativeSource);
21414
+ const linkPath = path63.join(linkDirectory, relativeSource);
21231
21415
  const result = await linkMarkdownFile(sourcePath, linkPath);
21232
21416
  if (result === "skipped") {
21233
21417
  skipped.push({
@@ -21236,7 +21420,7 @@ async function discoverAndWireDocs(siteDirectory) {
21236
21420
  });
21237
21421
  continue;
21238
21422
  }
21239
- const relativeLink = toPosix2(path62.relative(site, linkPath));
21423
+ const relativeLink = toPosix2(path63.relative(site, linkPath));
21240
21424
  const route = toRoutePath(relativeLink, PAGES_DIR);
21241
21425
  linked.push({ sourcePath, linkPath, route, relativeSource });
21242
21426
  routes.push(route);
@@ -21269,11 +21453,11 @@ async function discoverAndWireDocs(siteDirectory) {
21269
21453
  };
21270
21454
  }
21271
21455
  function siteRelative(siteDirectory, filePath) {
21272
- const relative = toPosix2(path62.relative(siteDirectory, filePath));
21456
+ const relative = toPosix2(path63.relative(siteDirectory, filePath));
21273
21457
  if (!relative) {
21274
21458
  return ".";
21275
21459
  }
21276
- if (path62.isAbsolute(relative)) {
21460
+ if (path63.isAbsolute(relative)) {
21277
21461
  return toPosix2(filePath);
21278
21462
  }
21279
21463
  if (relative.startsWith("..")) {
@@ -21340,8 +21524,8 @@ async function pathExists6(filePath) {
21340
21524
  }
21341
21525
  async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
21342
21526
  const input3 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
21343
- const jsonConfigPath = path63.join(siteDirectory, "apitogo.config.json");
21344
- const raw = await readFile18(jsonConfigPath, "utf8");
21527
+ const jsonConfigPath = path64.join(siteDirectory, "apitogo.config.json");
21528
+ const raw = await readFile19(jsonConfigPath, "utf8");
21345
21529
  const siteConfig = JSON.parse(raw);
21346
21530
  const updated = applyOpenApiToSiteConfig(siteConfig, {
21347
21531
  input: input3,
@@ -21349,7 +21533,7 @@ async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
21349
21533
  });
21350
21534
  const backend = updated.backend && typeof updated.backend === "object" && !Array.isArray(updated.backend) ? { ...updated.backend } : {};
21351
21535
  updated.backend = { ...backend, openApiPath: input3 };
21352
- await writeFile17(
21536
+ await writeFile18(
21353
21537
  jsonConfigPath,
21354
21538
  `${JSON.stringify(updated, null, 2)}
21355
21539
  `,
@@ -21368,7 +21552,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
21368
21552
  const invalidCandidates = [];
21369
21553
  let selected;
21370
21554
  for (const candidate of search.candidates) {
21371
- const content = await readFile18(candidate, "utf8");
21555
+ const content = await readFile19(candidate, "utf8");
21372
21556
  const parsed = liteParseOpenApi(content, candidate);
21373
21557
  if (parsed.valid) {
21374
21558
  selected = {
@@ -21392,7 +21576,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
21392
21576
  wired: false
21393
21577
  };
21394
21578
  }
21395
- const jsonConfigPath = path63.join(siteDirectory, "apitogo.config.json");
21579
+ const jsonConfigPath = path64.join(siteDirectory, "apitogo.config.json");
21396
21580
  if (!await pathExists6(jsonConfigPath)) {
21397
21581
  return {
21398
21582
  openApiDiscovery: {
@@ -21453,8 +21637,8 @@ function slugifyName2(name) {
21453
21637
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
21454
21638
  }
21455
21639
  function resolveInitOutputDirectory(dirArg, name) {
21456
- const resolved = path64.resolve(process.cwd(), dirArg);
21457
- const base = path64.basename(resolved);
21640
+ const resolved = path65.resolve(process.cwd(), dirArg);
21641
+ const base = path65.basename(resolved);
21458
21642
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
21459
21643
  if (isDot) {
21460
21644
  const fromName = name?.trim();
@@ -21464,7 +21648,7 @@ function resolveInitOutputDirectory(dirArg, name) {
21464
21648
  );
21465
21649
  }
21466
21650
  return {
21467
- outputDirectory: path64.resolve(process.cwd(), slugifyName2(fromName)),
21651
+ outputDirectory: path65.resolve(process.cwd(), slugifyName2(fromName)),
21468
21652
  siteName: fromName
21469
21653
  };
21470
21654
  }
@@ -21614,7 +21798,7 @@ var init_default = {
21614
21798
  // src/cli/cmds/preview.ts
21615
21799
  var REMOVED2 = "apitogo preview was removed. Use `apitogo build --preview` or `apitogo run`.";
21616
21800
  var preview_default = {
21617
- desc: "Removed \u2014 use apitogo build --preview",
21801
+ describe: false,
21618
21802
  command: "preview",
21619
21803
  builder: (yargs2) => yargs2,
21620
21804
  handler: async (argv) => {
@@ -21698,7 +21882,7 @@ var project_create_default = {
21698
21882
  // src/cli/cmds/remove.ts
21699
21883
  var REMOVED3 = "apitogo remove was removed. Use `apitogo teardown --yes` to delete the platform project.";
21700
21884
  var remove_default = {
21701
- desc: "Removed \u2014 use apitogo teardown",
21885
+ describe: false,
21702
21886
  command: "remove",
21703
21887
  builder: (yargs2) => yargs2,
21704
21888
  handler: async (argv) => {
@@ -21709,14 +21893,14 @@ var remove_default = {
21709
21893
 
21710
21894
  // src/cli/dev/handler.ts
21711
21895
  init_joinUrl();
21712
- import path67 from "node:path";
21896
+ import path68 from "node:path";
21713
21897
 
21714
21898
  // src/vite/dev-server.ts
21715
21899
  init_logger();
21716
21900
  import fs11 from "node:fs/promises";
21717
21901
  import http from "node:http";
21718
21902
  import https from "node:https";
21719
- import path66 from "node:path";
21903
+ import path67 from "node:path";
21720
21904
  import { createHttpTerminator } from "http-terminator";
21721
21905
  import {
21722
21906
  createServer as createViteServer,
@@ -21749,7 +21933,7 @@ init_loader();
21749
21933
  // src/vite/pagefind-dev-index.ts
21750
21934
  init_invariant();
21751
21935
  init_joinUrl();
21752
- import path65 from "node:path";
21936
+ import path66 from "node:path";
21753
21937
  import { createIndex as createIndex2 } from "pagefind";
21754
21938
  import { isRunnableDevEnvironment } from "vite";
21755
21939
  async function* buildPagefindDevIndex(vite, config2) {
@@ -21802,7 +21986,7 @@ async function* buildPagefindDevIndex(vite, config2) {
21802
21986
  path: urlPath
21803
21987
  };
21804
21988
  }
21805
- const outputPath = path65.join(vite.config.publicDir, "pagefind");
21989
+ const outputPath = path66.join(vite.config.publicDir, "pagefind");
21806
21990
  await pagefindIndex.writeFiles({ outputPath });
21807
21991
  yield { type: "complete", success: true, indexed };
21808
21992
  }
@@ -21821,9 +22005,9 @@ var DevServer = class {
21821
22005
  this.protocol = "https";
21822
22006
  const { dir } = this.options;
21823
22007
  const [key, cert, ca] = await Promise.all([
21824
- fs11.readFile(path66.resolve(dir, config2.https.key)),
21825
- fs11.readFile(path66.resolve(dir, config2.https.cert)),
21826
- config2.https.ca ? fs11.readFile(path66.resolve(dir, config2.https.ca)) : void 0
22008
+ fs11.readFile(path67.resolve(dir, config2.https.key)),
22009
+ fs11.readFile(path67.resolve(dir, config2.https.cert)),
22010
+ config2.https.ca ? fs11.readFile(path67.resolve(dir, config2.https.ca)) : void 0
21827
22011
  ]);
21828
22012
  return https.createServer({ key, cert, ca });
21829
22013
  }
@@ -21840,7 +22024,7 @@ var DevServer = class {
21840
22024
  );
21841
22025
  const server = await this.createNodeServer(config2);
21842
22026
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
21843
- const publicRoot = path66.resolve(
22027
+ const publicRoot = path67.resolve(
21844
22028
  this.options.dir,
21845
22029
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
21846
22030
  );
@@ -21857,7 +22041,7 @@ var DevServer = class {
21857
22041
  // built-in transform middleware which would treat the path as a static asset.
21858
22042
  name: "apitogo:entry-client",
21859
22043
  configureServer(server2) {
21860
- const entryPath = path66.posix.join(
22044
+ const entryPath = path67.posix.join(
21861
22045
  server2.config.base,
21862
22046
  "/__z/entry.client.tsx"
21863
22047
  );
@@ -22020,9 +22204,9 @@ var DevServer = class {
22020
22204
  // src/cli/dev/handler.ts
22021
22205
  init_package_json();
22022
22206
  async function dev(argv) {
22023
- const packageJson2 = getZudokuPackageJson();
22207
+ const packageJson3 = getZudokuPackageJson();
22024
22208
  process.env.NODE_ENV = "development";
22025
- const dir = path67.resolve(process.cwd(), argv.dir);
22209
+ const dir = path68.resolve(process.cwd(), argv.dir);
22026
22210
  const server = new DevServer({
22027
22211
  dir,
22028
22212
  argPort: argv.port,
@@ -22037,7 +22221,7 @@ async function dev(argv) {
22037
22221
  printDiagnosticsToConsole("Ctrl+C to exit");
22038
22222
  printDiagnosticsToConsole("");
22039
22223
  printDiagnosticsToConsole(
22040
- `\u{1F680} Running API ToGo v${packageJson2.version}: ${url}`
22224
+ `\u{1F680} Running API ToGo v${packageJson3.version}: ${url}`
22041
22225
  );
22042
22226
  printDiagnosticsToConsole("");
22043
22227
  let hasExited = false;
@@ -22106,9 +22290,9 @@ var run_default = {
22106
22290
  };
22107
22291
 
22108
22292
  // src/cli/status/handler.ts
22109
- import path68 from "node:path";
22293
+ import path69 from "node:path";
22110
22294
  async function status(argv) {
22111
- const sourceDirectory = path68.resolve(process.cwd(), argv.dir);
22295
+ const sourceDirectory = path69.resolve(process.cwd(), argv.dir);
22112
22296
  const config2 = loadConfig();
22113
22297
  const client = new PlatformApiClient(config2);
22114
22298
  let whoamiJson;
@@ -22188,7 +22372,7 @@ var status_default = {
22188
22372
  };
22189
22373
 
22190
22374
  // src/cli/teardown/handler.ts
22191
- import path69 from "node:path";
22375
+ import path70 from "node:path";
22192
22376
  function resultLooksFailed3(payload) {
22193
22377
  try {
22194
22378
  const parsed = JSON.parse(payload);
@@ -22204,7 +22388,7 @@ async function teardown(argv) {
22204
22388
  );
22205
22389
  return;
22206
22390
  }
22207
- const sourceDirectory = path69.resolve(process.cwd(), argv.dir);
22391
+ const sourceDirectory = path70.resolve(process.cwd(), argv.dir);
22208
22392
  const config2 = loadConfig();
22209
22393
  const client = new PlatformApiClient(config2);
22210
22394
  let projectId = argv.projectId?.trim();
@@ -22268,190 +22452,7 @@ var teardown_default = {
22268
22452
  }
22269
22453
  };
22270
22454
 
22271
- // src/cli/common/outdated.ts
22272
- import { existsSync as existsSync5, mkdirSync } from "node:fs";
22273
- import { readFile as readFile19, writeFile as writeFile18 } from "node:fs/promises";
22274
- import { join } from "node:path";
22275
- import colors10 from "picocolors";
22276
- import { gt } from "semver";
22277
-
22278
- // src/cli/common/json-only-deploy.ts
22279
- function isDeployJsonOnlyArgv() {
22280
- const args = process.argv;
22281
- let cmdIdx = -1;
22282
- for (const cmd of ["deploy", "remove"]) {
22283
- const i = args.indexOf(cmd);
22284
- if (i !== -1) {
22285
- cmdIdx = i;
22286
- break;
22287
- }
22288
- }
22289
- if (cmdIdx === -1) {
22290
- return false;
22291
- }
22292
- return args.slice(cmdIdx).some((a) => a === "--json-only" || a.startsWith("--json-only="));
22293
- }
22294
-
22295
- // src/cli/common/utils/box.ts
22296
- import colors9 from "picocolors";
22297
- import stripAnsi from "strip-ansi";
22298
- var border = ["\u2500", "\u256D", "\u256E", "\u2502", "\u2502", "\u2570", "\u256F"];
22299
- var nothing = ["\u2500", "", "", "", "", "", ""];
22300
- function box(message, {
22301
- borderColor,
22302
- padding = 1,
22303
- textAlignment = "center",
22304
- terminalColumns: cols = process.stdout.columns || process.env.COLUMNS && parseInt(process.env.COLUMNS, 10) || 80
22305
- } = {}) {
22306
- const lines = message.split(/\r?\n/).map((line) => [line, stripAnsi(line).length]);
22307
- const maxLine = lines.reduce((p, [, len]) => Math.max(p, len), 0);
22308
- const borderColorFn = borderColor && colors9[borderColor] || colors9.yellow;
22309
- const clampedSidePadding = Math.max(1, padding * 3);
22310
- const narrowMode = maxLine + 2 + clampedSidePadding * 2 > cols;
22311
- const sidePadding = narrowMode ? 0 : clampedSidePadding;
22312
- const innerWidth = Math.min(maxLine + sidePadding * 2, cols);
22313
- const [hr, topLeft, topRight, left, right, bottomLeft, bottomRight] = narrowMode ? nothing : border;
22314
- const spacerRow = narrowMode ? "\n".repeat(padding) : `${borderColorFn(`${left}${" ".repeat(innerWidth)}${right}`)}
22315
- `.repeat(
22316
- padding
22317
- );
22318
- const renderLine = ([line, len]) => {
22319
- let leftPadding = 0;
22320
- let rightPadding = 0;
22321
- if (!narrowMode) {
22322
- leftPadding = sidePadding;
22323
- rightPadding = sidePadding;
22324
- if (textAlignment === "center") {
22325
- leftPadding += Math.floor((maxLine - len) / 2);
22326
- rightPadding += maxLine - len - leftPadding + sidePadding;
22327
- } else if (textAlignment === "right") {
22328
- leftPadding += maxLine - len;
22329
- } else if (textAlignment === "left") {
22330
- rightPadding += maxLine - len;
22331
- }
22332
- }
22333
- return borderColorFn(left) + " ".repeat(leftPadding) + line + " ".repeat(rightPadding) + borderColorFn(right);
22334
- };
22335
- return borderColorFn(`${topLeft}${hr?.repeat(innerWidth)}${topRight}`) + "\n" + spacerRow + lines.map(renderLine).join("\n") + "\n" + spacerRow + borderColorFn(`${bottomLeft}${hr?.repeat(innerWidth)}${bottomRight}`);
22336
- }
22337
-
22338
- // src/cli/common/xdg/lib.ts
22339
- import { homedir } from "node:os";
22340
- import path70 from "node:path";
22341
- function defineDirectoryWithFallback(xdgName, fallback) {
22342
- if (process.env[xdgName]) {
22343
- return process.env[xdgName];
22344
- } else {
22345
- return path70.join(homedir(), fallback);
22346
- }
22347
- }
22348
- var XDG_CONFIG_HOME = defineDirectoryWithFallback(
22349
- "XDG_CONFIG_HOME",
22350
- ".config"
22351
- );
22352
- var XDG_DATA_HOME = defineDirectoryWithFallback(
22353
- "XDG_DATA_HOME",
22354
- ".local/share"
22355
- );
22356
- var XDG_STATE_HOME = defineDirectoryWithFallback(
22357
- "XDG_DATA_HOME",
22358
- ".local/state"
22359
- );
22360
- var ZUDOKU_XDG_CONFIG_HOME = path70.join(
22361
- XDG_CONFIG_HOME,
22362
- CLI_XDG_FOLDER_NAME
22363
- );
22364
- var ZUDOKU_XDG_DATA_HOME = path70.join(
22365
- XDG_DATA_HOME,
22366
- CLI_XDG_FOLDER_NAME
22367
- );
22368
- var ZUDOKU_XDG_STATE_HOME = path70.join(
22369
- XDG_STATE_HOME,
22370
- CLI_XDG_FOLDER_NAME
22371
- );
22372
-
22373
- // src/cli/common/outdated.ts
22374
- async function warnIfOutdatedVersion(currentVersion) {
22375
- if (isDeployJsonOnlyArgv()) {
22376
- return false;
22377
- }
22378
- if (!process.env.ZUDOKU_OVERRIDE_CI_TO_TEST && (process.env.CI || process.env.ZUDOKU_DISABLE_UPDATE_CHECK)) {
22379
- return false;
22380
- }
22381
- const versionCheckInfo = await getVersionCheckInfo();
22382
- if (!versionCheckInfo.latestVersion) {
22383
- return false;
22384
- }
22385
- const shouldWarn = gt(versionCheckInfo.latestVersion, currentVersion) && !process.env.ZUDOKU_INTERNAL_DEV;
22386
- if (shouldWarn) {
22387
- printWarningToConsole(
22388
- box(
22389
- `Update available! ${colors10.gray(`v${currentVersion}`)} \u226B ${colors10.green(
22390
- `v${versionCheckInfo.latestVersion}`
22391
- )}
22392
- Run ${colors10.cyan("npm install apitogo@latest")} to update.
22393
-
22394
- ${colors10.gray("Upgrade to receive the latest features and fixes.")}`
22395
- )
22396
- );
22397
- }
22398
- return shouldWarn;
22399
- }
22400
- async function getLatestVersion() {
22401
- const response = await fetch(
22402
- "https://api.github.com/repos/lukoweb/apitogo-doc-tool/releases?per_page=1"
22403
- );
22404
- if (response.status === 200) {
22405
- const result = await response.json();
22406
- if (Array.isArray(result) && result.length > 0) {
22407
- return result[0].tag_name.substring(1);
22408
- }
22409
- }
22410
- return void 0;
22411
- }
22412
- async function getVersionCheckInfo() {
22413
- if (!existsSync5(ZUDOKU_XDG_STATE_HOME)) {
22414
- mkdirSync(ZUDOKU_XDG_STATE_HOME, { recursive: true });
22415
- }
22416
- const versionCheckPath = join(ZUDOKU_XDG_STATE_HOME, VERSION_CHECK_FILE);
22417
- let versionCheckInfo;
22418
- if (existsSync5(versionCheckPath)) {
22419
- try {
22420
- versionCheckInfo = await readFile19(versionCheckPath, "utf-8").then(
22421
- JSON.parse
22422
- );
22423
- } catch {
22424
- }
22425
- if (versionCheckInfo) {
22426
- if (typeof versionCheckInfo.lastCheck !== "number" || typeof versionCheckInfo.latestVersion !== "string") {
22427
- versionCheckInfo = void 0;
22428
- }
22429
- }
22430
- }
22431
- let shouldCheck = true;
22432
- if (versionCheckInfo) {
22433
- const now = Date.now();
22434
- const lastCheck = versionCheckInfo.lastCheck;
22435
- if (now - lastCheck < 1e3 * 60 * 60 * 24) {
22436
- shouldCheck = false;
22437
- }
22438
- }
22439
- if (!versionCheckInfo || shouldCheck) {
22440
- const latestVersion = await getLatestVersion();
22441
- versionCheckInfo = {
22442
- lastCheck: Date.now(),
22443
- latestVersion
22444
- };
22445
- await writeFile18(
22446
- versionCheckPath,
22447
- JSON.stringify(versionCheckInfo),
22448
- "utf-8"
22449
- );
22450
- }
22451
- return versionCheckInfo;
22452
- }
22453
-
22454
- // src/cli/cli.ts
22455
+ // src/cli/create-cli.ts
22455
22456
  init_package_json();
22456
22457
 
22457
22458
  // src/cli/common/version-check.ts
@@ -22472,10 +22473,10 @@ var warnPackageVersionMismatch = () => {
22472
22473
  if (process.env.ZUDOKU_ENV === "internal") {
22473
22474
  return;
22474
22475
  }
22475
- const packageJson2 = getZudokuPackageJson();
22476
+ const packageJson3 = getZudokuPackageJson();
22476
22477
  const reactPath = getPackageJsonPath("react");
22477
22478
  const reactDomPath = getPackageJsonPath("react-dom");
22478
- const required = packageJson2.peerDependencies;
22479
+ const required = packageJson3.peerDependencies;
22479
22480
  const installed = {
22480
22481
  react: getPackageJson(reactPath).version,
22481
22482
  "react-dom": getPackageJson(reactDomPath).version
@@ -22511,27 +22512,35 @@ To fix, run:
22511
22512
  process.exit(1);
22512
22513
  };
22513
22514
 
22515
+ // src/cli/create-cli.ts
22516
+ var packageJson = getZudokuPackageJson();
22517
+ var command = (module) => module;
22518
+ function createApitogoCli(argv) {
22519
+ return yargs(argv).scriptName("apitogo").option("zuplo", {
22520
+ type: "boolean",
22521
+ description: "Enable Zuplo mode",
22522
+ global: true,
22523
+ hidden: true
22524
+ }).middleware((parsed) => {
22525
+ if (parsed.zuplo) {
22526
+ process.env.ZUPLO = "1";
22527
+ printDiagnosticsToConsole("Running in Zuplo mode");
22528
+ }
22529
+ }).middleware(warnPackageVersionMismatch).command(command(init_default)).command(command(config_default)).command(command(run_default)).command(command(build_default)).command(command(check_default)).command(command(project_create_default)).command(command(deploy_default)).command(command(status_default)).command(command(teardown_default)).command(command(remove_default)).command(command(preview_default)).command(command(configure_github_workflow_default)).demandCommand().strictCommands().version(packageJson?.version).fail(false).help();
22530
+ }
22531
+
22514
22532
  // src/cli/cli.ts
22515
22533
  process.env.ZUDOKU_ENV = process.env.ZUDOKU_INTERNAL_DEV ? "internal" : "module";
22516
- var packageJson = getZudokuPackageJson();
22534
+ var packageJson2 = getZudokuPackageJson();
22517
22535
  if (SENTRY_DSN) {
22518
22536
  Sentry2.init({
22519
22537
  dsn: SENTRY_DSN,
22520
- release: packageJson?.version
22538
+ release: packageJson2?.version
22521
22539
  });
22522
22540
  }
22523
- var cli = yargs(hideBin(process.argv)).option("zuplo", {
22524
- type: "boolean",
22525
- description: "Enable Zuplo mode",
22526
- global: true
22527
- }).middleware((argv) => {
22528
- if (argv.zuplo) {
22529
- process.env.ZUPLO = "1";
22530
- printDiagnosticsToConsole("Running in Zuplo mode");
22531
- }
22532
- }).middleware(warnPackageVersionMismatch).command(init_default).command(config_default).command(run_default).command(build_default).command(check_default).command(project_create_default).command(deploy_default).command(status_default).command(teardown_default).command(remove_default).command(preview_default).command(configure_github_workflow_default).demandCommand().strictCommands().version(packageJson?.version).fail(false).help();
22541
+ var cli = createApitogoCli(hideBin(process.argv));
22533
22542
  try {
22534
- void warnIfOutdatedVersion(packageJson?.version);
22543
+ void warnIfOutdatedVersion(packageJson2?.version);
22535
22544
  await cli.argv;
22536
22545
  void Sentry2.close(MAX_WAIT_PENDING_TIME_MS).then(() => {
22537
22546
  process.exit(0);