@lukoweb/apitogo 0.1.96 → 0.1.98

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,6 +8,88 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/config/gateway-limits.ts
12
+ function isGatewayLimitsObject(value) {
13
+ return value !== null && typeof value === "object" && !Array.isArray(value);
14
+ }
15
+ function parseLimitsJson(limitsJson) {
16
+ if (!limitsJson?.trim()) {
17
+ return void 0;
18
+ }
19
+ try {
20
+ const parsed = JSON.parse(limitsJson);
21
+ return isGatewayLimitsObject(parsed) ? parsed : void 0;
22
+ } catch {
23
+ return void 0;
24
+ }
25
+ }
26
+ function coerceGatewayLimits(source) {
27
+ if (isGatewayLimitsObject(source.limits)) {
28
+ return source.limits;
29
+ }
30
+ return parseLimitsJson(
31
+ typeof source.limitsJson === "string" ? source.limitsJson : void 0
32
+ );
33
+ }
34
+ function stringifyGatewayLimits(limits) {
35
+ if (!isGatewayLimitsObject(limits)) {
36
+ return void 0;
37
+ }
38
+ return JSON.stringify(limits);
39
+ }
40
+ function planForConfig(plan) {
41
+ const limits = coerceGatewayLimits(plan);
42
+ const next = { ...plan };
43
+ delete next.limitsJson;
44
+ if (limits) {
45
+ next.limits = limits;
46
+ } else {
47
+ delete next.limits;
48
+ }
49
+ return next;
50
+ }
51
+ function gatewayForConfig(gateway) {
52
+ return planForConfig(gateway);
53
+ }
54
+ function mergeLimitsSource(prior, patch) {
55
+ const merged = prior ? { ...prior, ...patch } : { ...patch };
56
+ const patchSource = patch;
57
+ if (patchSource.limits === void 0 && patchSource.limitsJson !== void 0) {
58
+ delete merged.limits;
59
+ }
60
+ return planForConfig(merged);
61
+ }
62
+ function planLimitsForPlatform(plan) {
63
+ return stringifyGatewayLimits(coerceGatewayLimits(plan));
64
+ }
65
+ function validateLimitsField(value, field) {
66
+ if (value == null || value === "") {
67
+ return [];
68
+ }
69
+ if (typeof value === "string") {
70
+ if (!value.trim()) {
71
+ return [];
72
+ }
73
+ try {
74
+ const parsed = JSON.parse(value);
75
+ if (!isGatewayLimitsObject(parsed)) {
76
+ return [{ field, message: `${field} must be a JSON object.` }];
77
+ }
78
+ return [];
79
+ } catch {
80
+ return [{ field, message: `${field} is not valid JSON.` }];
81
+ }
82
+ }
83
+ if (isGatewayLimitsObject(value)) {
84
+ return [];
85
+ }
86
+ return [{ field, message: `${field} must be a JSON object.` }];
87
+ }
88
+ var init_gateway_limits = __esm({
89
+ "src/config/gateway-limits.ts"() {
90
+ }
91
+ });
92
+
11
93
  // src/cli/common/package-json.ts
12
94
  import { readFileSync } from "node:fs";
13
95
  import path19 from "node:path";
@@ -328,7 +410,7 @@ function mergePlansBySku2(existing, patch) {
328
410
  continue;
329
411
  }
330
412
  const prior = bySku.get(plan.sku);
331
- bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
413
+ bySku.set(plan.sku, mergeLimitsSource(prior, plan));
332
414
  }
333
415
  return Array.from(bySku.values());
334
416
  }
@@ -355,6 +437,19 @@ function migratePlanCatalog(normalized) {
355
437
  }
356
438
  delete normalized.plans;
357
439
  }
440
+ function migratePlanLimits(normalized) {
441
+ const modules = asRecord2(normalized.modules);
442
+ const plansModule = asRecord2(asRecord2(modules?.userPanel)?.plans);
443
+ if (Array.isArray(plansModule?.items)) {
444
+ plansModule.items = plansModule.items.map(
445
+ (plan) => planForConfig(plan)
446
+ );
447
+ }
448
+ const gateway = asRecord2(normalized.gateway);
449
+ if (gateway) {
450
+ normalized.gateway = gatewayForConfig(gateway);
451
+ }
452
+ }
358
453
  function normalizeApitogoConfig(config2) {
359
454
  const normalized = structuredClone(stripRuntimeConfigFields(config2));
360
455
  const title = readSiteTitle2(normalized);
@@ -401,6 +496,7 @@ function normalizeApitogoConfig(config2) {
401
496
  delete normalized.branding;
402
497
  delete normalized.projectName;
403
498
  migratePlanCatalog(normalized);
499
+ migratePlanLimits(normalized);
404
500
  syncBillingEnabled(normalized);
405
501
  syncAuthentication(normalized);
406
502
  return normalized;
@@ -597,6 +693,7 @@ function extractSiteConfig(config2) {
597
693
  var APITOGO_CONFIG_FILENAME2, ENV_PREFIX, DERIVED_MANIFEST_KEYS, SITE_CONFIG_KEYS, COLLAPSED_UPPERCASE_ALIASES2;
598
694
  var init_apitogo_config_core = __esm({
599
695
  "src/config/apitogo-config-core.ts"() {
696
+ init_gateway_limits();
600
697
  APITOGO_CONFIG_FILENAME2 = "apitogo.config.json";
601
698
  ENV_PREFIX = "APITOGO_CONFIG_";
602
699
  DERIVED_MANIFEST_KEYS = [
@@ -640,6 +737,7 @@ var init_apitogo_config_core = __esm({
640
737
  PRICECURRENCY: "priceCurrency",
641
738
  BILLINGPERIOD: "billingPeriod",
642
739
  LIMITSJSON: "limitsJson",
740
+ LIMITS: "limits",
643
741
  INCLUDEDACTIONKEYS: "includedActionKeys",
644
742
  SOURCEDIRECTORY: "sourceDirectory",
645
743
  PUBLISHDIRECTORY: "publishDirectory",
@@ -734,7 +832,7 @@ import { stat } from "node:fs/promises";
734
832
  var fileExists;
735
833
  var init_file_exists = __esm({
736
834
  "src/config/file-exists.ts"() {
737
- fileExists = (path69) => stat(path69).then(() => true).catch(() => false);
835
+ fileExists = (path70) => stat(path70).then(() => true).catch(() => false);
738
836
  }
739
837
  });
740
838
 
@@ -925,6 +1023,16 @@ var init_ModulesSchema = __esm({
925
1023
  "priceCurrency must be a 3-letter ISO 4217 code (lowercase)"
926
1024
  ).optional(),
927
1025
  billingPeriod: z3.string().optional(),
1026
+ limits: z3.object({
1027
+ rateLimit: z3.object({
1028
+ calls: z3.number(),
1029
+ renewalPeriodSeconds: z3.number().optional()
1030
+ }).passthrough().optional(),
1031
+ quota: z3.object({
1032
+ calls: z3.number(),
1033
+ renewalPeriodDays: z3.number().optional()
1034
+ }).passthrough().optional()
1035
+ }).passthrough().optional(),
928
1036
  limitsJson: z3.string().optional(),
929
1037
  includedActionKeys: z3.array(z3.string()).optional()
930
1038
  });
@@ -1019,7 +1127,8 @@ function plansToPreviewCatalog(plans) {
1019
1127
  priceAmount: plan.priceAmount ?? 0,
1020
1128
  priceCurrency: plan.priceCurrency ?? "usd",
1021
1129
  billingPeriod: normalizeBillingPeriod2(plan.billingPeriod),
1022
- limitsJson: plan.limitsJson ?? null,
1130
+ limits: coerceGatewayLimits(plan) ?? null,
1131
+ limitsJson: planLimitsForPlatform(plan) ?? null,
1023
1132
  includedActionKeys: plan.includedActionKeys ?? []
1024
1133
  }))
1025
1134
  };
@@ -1064,12 +1173,23 @@ async function readEffectiveManifest(rootDir, _env) {
1064
1173
  return null;
1065
1174
  }
1066
1175
  }
1067
- var BillingPeriodSchema, PriceCurrencySchema, ALLOWED_RUNTIME_VERSIONS2, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
1176
+ var BillingPeriodSchema, GatewayLimitsSchema, PriceCurrencySchema, ALLOWED_RUNTIME_VERSIONS2, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
1068
1177
  var init_local_manifest = __esm({
1069
1178
  "src/config/local-manifest.ts"() {
1179
+ init_gateway_limits();
1070
1180
  init_apitogo_config_loader();
1071
1181
  init_landing_manifest();
1072
1182
  BillingPeriodSchema = z4.enum(["month", "year", "monthly", "annual"]);
1183
+ GatewayLimitsSchema = z4.object({
1184
+ rateLimit: z4.object({
1185
+ calls: z4.number(),
1186
+ renewalPeriodSeconds: z4.number().optional()
1187
+ }).passthrough().optional(),
1188
+ quota: z4.object({
1189
+ calls: z4.number(),
1190
+ renewalPeriodDays: z4.number().optional()
1191
+ }).passthrough().optional()
1192
+ }).passthrough();
1073
1193
  PriceCurrencySchema = z4.string().trim().toLowerCase().regex(
1074
1194
  /^[a-z]{3}$/,
1075
1195
  "priceCurrency must be a 3-letter ISO 4217 code (lowercase)"
@@ -1092,6 +1212,8 @@ var init_local_manifest = __esm({
1092
1212
  priceAmount: z4.number().default(0),
1093
1213
  priceCurrency: PriceCurrencySchema.optional(),
1094
1214
  billingPeriod: BillingPeriodSchema.optional(),
1215
+ limits: GatewayLimitsSchema.optional(),
1216
+ /** @deprecated Use `limits`. Encoded string still accepted on load. */
1095
1217
  limitsJson: z4.string().optional(),
1096
1218
  includedActionKeys: z4.array(z4.string()).optional()
1097
1219
  });
@@ -1147,6 +1269,8 @@ var init_local_manifest = __esm({
1147
1269
  oidcMetadataUrl: z4.string().optional(),
1148
1270
  oidcAllowedIssuers: z4.array(z4.string()).optional(),
1149
1271
  oidcAudiences: z4.array(z4.string()).optional(),
1272
+ limits: GatewayLimitsSchema.optional(),
1273
+ /** @deprecated Use `limits`. Encoded string still accepted on load. */
1150
1274
  limitsJson: z4.string().optional(),
1151
1275
  publicHealthActionKey: z4.string().optional(),
1152
1276
  publicRoutes: z4.array(z4.string()).optional(),
@@ -5126,7 +5250,7 @@ __export(llms_exports, {
5126
5250
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
5127
5251
  });
5128
5252
  import { writeFile as writeFile9 } from "node:fs/promises";
5129
- import path45 from "node:path";
5253
+ import path46 from "node:path";
5130
5254
  import colors7 from "picocolors";
5131
5255
  async function generateLlmsTxtFiles({
5132
5256
  markdownFileInfos,
@@ -5161,7 +5285,7 @@ async function generateLlmsTxtFiles({
5161
5285
  }
5162
5286
  }
5163
5287
  const llmsTxt2 = llmsTxtParts.join("\n");
5164
- await writeFile9(path45.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5288
+ await writeFile9(path46.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
5165
5289
  if (process.env.APITOGO_JSON_ONLY !== "1") {
5166
5290
  console.log(colors7.blue("\u2713 generated llms.txt"));
5167
5291
  }
@@ -5189,7 +5313,7 @@ ${info.content}
5189
5313
  }
5190
5314
  const llmsFull = llmsFullParts.join("\n");
5191
5315
  await writeFile9(
5192
- path45.join(baseOutputDir, "llms-full.txt"),
5316
+ path46.join(baseOutputDir, "llms-full.txt"),
5193
5317
  llmsFull,
5194
5318
  "utf-8"
5195
5319
  );
@@ -5504,8 +5628,8 @@ var PlatformApiClient = class {
5504
5628
  constructor(config2) {
5505
5629
  this.config = config2;
5506
5630
  }
5507
- url(path69) {
5508
- return `${this.config.apiUrl}${path69.startsWith("/") ? path69 : `/${path69}`}`;
5631
+ url(path70) {
5632
+ return `${this.config.apiUrl}${path70.startsWith("/") ? path70 : `/${path70}`}`;
5509
5633
  }
5510
5634
  headers(extra) {
5511
5635
  return {
@@ -5515,9 +5639,9 @@ var PlatformApiClient = class {
5515
5639
  ...extra
5516
5640
  };
5517
5641
  }
5518
- async request(method, path69, init4) {
5642
+ async request(method, path70, init4) {
5519
5643
  const response = await fetchWithRetry(
5520
- this.url(path69),
5644
+ this.url(path70),
5521
5645
  {
5522
5646
  method,
5523
5647
  ...init4,
@@ -5717,15 +5841,15 @@ var PlatformApiClient = class {
5717
5841
  }
5718
5842
  );
5719
5843
  }
5720
- deleteDevPortalPage(projectId, path69) {
5721
- const query = new URLSearchParams({ path: path69 });
5844
+ deleteDevPortalPage(projectId, path70) {
5845
+ const query = new URLSearchParams({ path: path70 });
5722
5846
  return this.request(
5723
5847
  "DELETE",
5724
5848
  `/api/v1/projects/${projectId}/dev-portal/pages/files?${query.toString()}`
5725
5849
  );
5726
5850
  }
5727
- renameDevPortalPage(projectId, path69, newName) {
5728
- const query = new URLSearchParams({ path: path69 });
5851
+ renameDevPortalPage(projectId, path70, newName) {
5852
+ const query = new URLSearchParams({ path: path70 });
5729
5853
  return this.request(
5730
5854
  "POST",
5731
5855
  `/api/v1/projects/${projectId}/dev-portal/pages/files/rename?${query.toString()}`,
@@ -5961,6 +6085,9 @@ function resolveDevPortalDeployConfig(config2) {
5961
6085
  return { endpointUrl, apiKey, defaultEnv };
5962
6086
  }
5963
6087
 
6088
+ // src/cli/platform/tools/dev-portal-publish.ts
6089
+ init_gateway_limits();
6090
+
5964
6091
  // src/cli/platform/helpers/dev-portal-manifest.ts
5965
6092
  import { existsSync } from "node:fs";
5966
6093
  import { access, mkdir, readFile as readFile2, writeFile } from "node:fs/promises";
@@ -6017,6 +6144,7 @@ function readLandingFromConfig(config2) {
6017
6144
  }
6018
6145
 
6019
6146
  // src/cli/platform/helpers/dev-portal-manifest.ts
6147
+ init_gateway_limits();
6020
6148
  var APITOGO_CONFIG_FILENAME = "apitogo.config.json";
6021
6149
  var PLACEHOLDER_DEV_PORTAL_API_URL = "https://dp-example.azurecontainerapps.io";
6022
6150
  function isPlanFree(plan) {
@@ -6037,11 +6165,11 @@ function readPlanItemsFromConfig(config2) {
6037
6165
  const plansModule = userPanel?.plans;
6038
6166
  const items = plansModule?.items;
6039
6167
  if (Array.isArray(items) && items.length) {
6040
- return items;
6168
+ return items.map((item) => planForConfig(item));
6041
6169
  }
6042
6170
  const rootPlans = config2.plans;
6043
6171
  if (Array.isArray(rootPlans) && rootPlans.length) {
6044
- return rootPlans;
6172
+ return rootPlans.map((item) => planForConfig(item));
6045
6173
  }
6046
6174
  return void 0;
6047
6175
  }
@@ -6063,7 +6191,7 @@ function applyPlansToUserPanel(config2, plans, pricingEnabled) {
6063
6191
  const userPanel = modules.userPanel ?? {};
6064
6192
  const plansModule = userPanel.plans ?? {};
6065
6193
  if (plans.length > 0) {
6066
- plansModule.items = plans;
6194
+ plansModule.items = plans.map((plan) => planForConfig(plan));
6067
6195
  if (pricingEnabled !== false) {
6068
6196
  plansModule.enabled = plansModule.enabled ?? true;
6069
6197
  }
@@ -6177,6 +6305,9 @@ function extractManifestFromConfig(config2) {
6177
6305
  manifest[key] = config2[key];
6178
6306
  }
6179
6307
  }
6308
+ if (manifest.gateway) {
6309
+ manifest.gateway = gatewayForConfig(manifest.gateway);
6310
+ }
6180
6311
  const plans = readPlanItemsFromConfig(config2);
6181
6312
  if (plans) {
6182
6313
  manifest.plans = plans;
@@ -6210,7 +6341,7 @@ function applyManifestToConfig(config2, manifest) {
6210
6341
  for (const key of STORED_MANIFEST_KEYS) {
6211
6342
  const value = manifest[key];
6212
6343
  if (value !== void 0) {
6213
- next[key] = value;
6344
+ next[key] = key === "gateway" ? gatewayForConfig(value) : value;
6214
6345
  } else {
6215
6346
  delete next[key];
6216
6347
  }
@@ -6262,9 +6393,9 @@ var DEFAULT_PLANS = [
6262
6393
  sku: "free",
6263
6394
  displayName: "Free",
6264
6395
  priceAmount: 0,
6265
- limitsJson: JSON.stringify({
6396
+ limits: {
6266
6397
  rateLimit: { calls: 10, renewalPeriodSeconds: 60 }
6267
- }),
6398
+ },
6268
6399
  includedActionKeys: []
6269
6400
  },
6270
6401
  {
@@ -6272,10 +6403,10 @@ var DEFAULT_PLANS = [
6272
6403
  displayName: "Pro",
6273
6404
  priceAmount: 9.99,
6274
6405
  billingPeriod: "month",
6275
- limitsJson: JSON.stringify({
6406
+ limits: {
6276
6407
  rateLimit: { calls: 100, renewalPeriodSeconds: 60 },
6277
6408
  quota: { calls: 5e4, renewalPeriodDays: 1 }
6278
- }),
6409
+ },
6279
6410
  includedActionKeys: []
6280
6411
  }
6281
6412
  ];
@@ -6472,7 +6603,7 @@ function mergePlansBySku(existing, patch) {
6472
6603
  }
6473
6604
  for (const plan of patch) {
6474
6605
  const prior = bySku.get(plan.sku);
6475
- bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
6606
+ bySku.set(plan.sku, mergeLimitsSource(prior, plan));
6476
6607
  }
6477
6608
  return Array.from(bySku.values());
6478
6609
  }
@@ -6564,6 +6695,7 @@ async function writeManifest(siteDirectory, manifest) {
6564
6695
  }
6565
6696
 
6566
6697
  // src/cli/platform/helpers/publish-preflight.ts
6698
+ init_gateway_limits();
6567
6699
  var ALLOWED_RUNTIME_VERSIONS = [
6568
6700
  "DOTNET_10",
6569
6701
  "DOTNET_9",
@@ -6683,20 +6815,6 @@ function normalizeRuntime(runtime) {
6683
6815
  if (raw === "python") return "python";
6684
6816
  throw new Error(`runtime must be one of: dotnet, nodejs, python; got '${runtime}'.`);
6685
6817
  }
6686
- function validateLimitsJson(limitsJson, field) {
6687
- if (!limitsJson?.trim()) {
6688
- return [];
6689
- }
6690
- try {
6691
- const parsed = JSON.parse(limitsJson);
6692
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
6693
- return [{ field, message: `${field} must be a JSON object.` }];
6694
- }
6695
- return [];
6696
- } catch {
6697
- return [{ field, message: `${field} is not valid JSON.` }];
6698
- }
6699
- }
6700
6818
  function normalizePlanForGatewayApi(plan) {
6701
6819
  return {
6702
6820
  ...plan,
@@ -6811,7 +6929,12 @@ function validateManifestForPlatformPublish(manifest) {
6811
6929
  });
6812
6930
  }
6813
6931
  }
6814
- issues.push(...validateLimitsJson(plan.limitsJson, `plans[${index}].limitsJson`));
6932
+ issues.push(
6933
+ ...validateLimitsField(
6934
+ plan.limits ?? plan.limitsJson,
6935
+ `plans[${index}].limits`
6936
+ )
6937
+ );
6815
6938
  }
6816
6939
  }
6817
6940
  if (manifest.backend?.sourceDirectory?.trim() || manifest.backend?.runtimeVersion) {
@@ -6846,8 +6969,13 @@ function validateManifestForPlatformPublish(manifest) {
6846
6969
  });
6847
6970
  }
6848
6971
  }
6849
- if (manifest.gateway?.limitsJson) {
6850
- issues.push(...validateLimitsJson(manifest.gateway.limitsJson, "gateway.limitsJson"));
6972
+ if (manifest.gateway?.limits ?? manifest.gateway?.limitsJson) {
6973
+ issues.push(
6974
+ ...validateLimitsField(
6975
+ manifest.gateway.limits ?? manifest.gateway.limitsJson,
6976
+ "gateway.limits"
6977
+ )
6978
+ );
6851
6979
  }
6852
6980
  return {
6853
6981
  issues,
@@ -6874,6 +7002,7 @@ var COLLAPSED_UPPERCASE_ALIASES = {
6874
7002
  PRICECURRENCY: "priceCurrency",
6875
7003
  BILLINGPERIOD: "billingPeriod",
6876
7004
  LIMITSJSON: "limitsJson",
7005
+ LIMITS: "limits",
6877
7006
  INCLUDEDACTIONKEYS: "includedActionKeys",
6878
7007
  SOURCEDIRECTORY: "sourceDirectory",
6879
7008
  PUBLISHDIRECTORY: "publishDirectory",
@@ -7246,6 +7375,9 @@ function formatDevPortalBackendResponse(projectId, backend) {
7246
7375
  };
7247
7376
  }
7248
7377
 
7378
+ // src/cli/platform/helpers/gateway-plan-sync.ts
7379
+ init_gateway_limits();
7380
+
7249
7381
  // src/cli/platform/tools/gateway.ts
7250
7382
  var DEFAULT_BASELINE_LIMITS_JSON = JSON.stringify({
7251
7383
  rateLimit: { calls: 100, renewalPeriodSeconds: 60 },
@@ -7317,8 +7449,8 @@ function normalizeActionKey(actionKey) {
7317
7449
  const trimmed = actionKey.trim();
7318
7450
  if (trimmed.includes(":")) {
7319
7451
  const [method2, ...pathParts] = trimmed.split(":");
7320
- const path70 = pathParts.join(":").trim();
7321
- return `${method2.toLowerCase()}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
7452
+ const path71 = pathParts.join(":").trim();
7453
+ return `${method2.toLowerCase()}:${path71.startsWith("/") ? path71 : `/${path71}`}`;
7322
7454
  }
7323
7455
  const spaceIndex = trimmed.indexOf(" ");
7324
7456
  if (spaceIndex <= 0) {
@@ -7327,8 +7459,8 @@ function normalizeActionKey(actionKey) {
7327
7459
  );
7328
7460
  }
7329
7461
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
7330
- const path69 = trimmed.slice(spaceIndex + 1).trim();
7331
- return `${method}:${path69.startsWith("/") ? path69 : `/${path69}`}`;
7462
+ const path70 = trimmed.slice(spaceIndex + 1).trim();
7463
+ return `${method}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
7332
7464
  }
7333
7465
  async function applyGatewayPublicRoutes(client, projectId, routes, options) {
7334
7466
  const applied = [];
@@ -7655,7 +7787,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
7655
7787
  planId: found.id,
7656
7788
  displayName: input3.displayName,
7657
7789
  isActive: true,
7658
- limitsJson: input3.limitsJson,
7790
+ limitsJson: planLimitsForPlatform(input3),
7659
7791
  priceAmount: input3.priceAmount,
7660
7792
  priceCurrency: input3.priceCurrency,
7661
7793
  billingPeriod: input3.billingPeriod ? normalizeBillingPeriod(input3.billingPeriod) : void 0
@@ -7678,7 +7810,7 @@ async function upsertGatewayPlansFromManifest(client, config2, projectId, plans,
7678
7810
  priceAmount: input3.priceAmount,
7679
7811
  priceCurrency: input3.priceCurrency ?? "usd",
7680
7812
  billingPeriod: normalizeBillingPeriod(input3.billingPeriod),
7681
- limitsJson: input3.limitsJson,
7813
+ limitsJson: planLimitsForPlatform(input3),
7682
7814
  includedActionKeys: options?.deferActionKeys ? [] : resolveIncludedActionKeysForUpsert(input3),
7683
7815
  sortOrder: index
7684
7816
  });
@@ -11251,6 +11383,7 @@ async function handleBuildDevPortalSite(client, config2, args, progress) {
11251
11383
  import { readFile as readFile8 } from "node:fs/promises";
11252
11384
  import { createRequire } from "node:module";
11253
11385
  import path17 from "node:path";
11386
+ init_gateway_limits();
11254
11387
  var cachedFallbackTs;
11255
11388
  async function loadTypeScriptForSite(sourceDirectory) {
11256
11389
  const require2 = createRequire(path17.join(path17.resolve(sourceDirectory), "package.json"));
@@ -11371,6 +11504,11 @@ async function validateSiteConfigStructure(config2, sourceDirectory) {
11371
11504
  `"modules.userPanel.plans.items[${index}].sku" must be a non-empty string.`
11372
11505
  );
11373
11506
  }
11507
+ if (plan.limits !== void 0 && !isGatewayLimitsObject(plan.limits)) {
11508
+ errors.push(
11509
+ `"modules.userPanel.plans.items[${index}].limits" must be a JSON object.`
11510
+ );
11511
+ }
11374
11512
  if (typeof plan.limitsJson === "string" && plan.limitsJson.trim()) {
11375
11513
  try {
11376
11514
  JSON.parse(plan.limitsJson);
@@ -11482,8 +11620,8 @@ function normalizeActionKeyFormat(actionKey) {
11482
11620
  const trimmed = actionKey.trim();
11483
11621
  if (trimmed.includes(":")) {
11484
11622
  const [method2, ...pathParts] = trimmed.split(":");
11485
- const path70 = pathParts.join(":").trim();
11486
- return `${method2.toLowerCase()}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
11623
+ const path71 = pathParts.join(":").trim();
11624
+ return `${method2.toLowerCase()}:${path71.startsWith("/") ? path71 : `/${path71}`}`;
11487
11625
  }
11488
11626
  const spaceIndex = trimmed.indexOf(" ");
11489
11627
  if (spaceIndex <= 0) {
@@ -11492,8 +11630,8 @@ function normalizeActionKeyFormat(actionKey) {
11492
11630
  );
11493
11631
  }
11494
11632
  const method = trimmed.slice(0, spaceIndex).trim().toLowerCase();
11495
- const path69 = trimmed.slice(spaceIndex + 1).trim();
11496
- return `${method}:${path69.startsWith("/") ? path69 : `/${path69}`}`;
11633
+ const path70 = trimmed.slice(spaceIndex + 1).trim();
11634
+ return `${method}:${path70.startsWith("/") ? path70 : `/${path70}`}`;
11497
11635
  }
11498
11636
  function normalizePublicRoute(route) {
11499
11637
  const trimmed = route.trim();
@@ -11910,7 +12048,7 @@ async function runApplyFromSiteDirectory(client, config2, args, progress) {
11910
12048
  const enableGatewayJwt = Boolean(explicitAuthMode || explicitOidcUrl);
11911
12049
  const baselineArgs = {
11912
12050
  projectId,
11913
- limitsJson: gateway.limitsJson,
12051
+ limitsJson: planLimitsForPlatform(gateway),
11914
12052
  publicHealthActionKey: gateway.publicHealthActionKey,
11915
12053
  publicRoutes: gateway.publicRoutes,
11916
12054
  waitForEntra: wait,
@@ -12459,11 +12597,11 @@ var apply_default = {
12459
12597
  };
12460
12598
 
12461
12599
  // src/cli/build/handler.ts
12462
- import path49 from "node:path";
12600
+ import path50 from "node:path";
12463
12601
 
12464
12602
  // src/vite/build.ts
12465
12603
  import { mkdir as mkdir9, readFile as readFile11, rename, rm as rm3, writeFile as writeFile10 } from "node:fs/promises";
12466
- import path47 from "node:path";
12604
+ import path48 from "node:path";
12467
12605
  import { build as esbuild } from "esbuild";
12468
12606
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
12469
12607
 
@@ -12599,7 +12737,7 @@ init_invariant();
12599
12737
  init_joinUrl();
12600
12738
 
12601
12739
  // src/vite/config.ts
12602
- import path42 from "node:path";
12740
+ import path43 from "node:path";
12603
12741
  import dotenv from "dotenv";
12604
12742
  import colors5 from "picocolors";
12605
12743
  import {
@@ -12610,7 +12748,7 @@ import {
12610
12748
  // package.json
12611
12749
  var package_default = {
12612
12750
  name: "@lukoweb/apitogo",
12613
- version: "0.1.96",
12751
+ version: "0.1.98",
12614
12752
  type: "module",
12615
12753
  sideEffects: [
12616
12754
  "**/*.css",
@@ -13388,14 +13526,14 @@ var flattenAllOf = (schema2) => {
13388
13526
  };
13389
13527
 
13390
13528
  // src/lib/util/traverse.ts
13391
- var traverse = (specification, transform, path69 = []) => {
13392
- const transformed = transform(specification, path69);
13529
+ var traverse = (specification, transform, path70 = []) => {
13530
+ const transformed = transform(specification, path70);
13393
13531
  if (typeof transformed !== "object" || transformed === null) {
13394
13532
  return transformed;
13395
13533
  }
13396
13534
  const result = Array.isArray(transformed) ? [] : {};
13397
13535
  for (const [key, value] of Object.entries(transformed)) {
13398
- const currentPath = [...path69, key];
13536
+ const currentPath = [...path70, key];
13399
13537
  if (Array.isArray(value)) {
13400
13538
  result[key] = value.map(
13401
13539
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -13423,9 +13561,9 @@ var resolveLocalRef = (schema2, ref) => {
13423
13561
  if (schemaCache?.has(ref)) {
13424
13562
  return schemaCache.get(ref);
13425
13563
  }
13426
- const path69 = ref.split("/").slice(1);
13564
+ const path70 = ref.split("/").slice(1);
13427
13565
  let current = schema2;
13428
- for (const segment of path69) {
13566
+ for (const segment of path70) {
13429
13567
  if (!current || typeof current !== "object") {
13430
13568
  current = null;
13431
13569
  }
@@ -13444,7 +13582,7 @@ var dereference = async (schema2, resolvers = []) => {
13444
13582
  }
13445
13583
  const cloned = structuredClone(schema2);
13446
13584
  const visited = /* @__PURE__ */ new Set();
13447
- const resolve = async (current, path69) => {
13585
+ const resolve = async (current, path70) => {
13448
13586
  if (isIndexableObject(current)) {
13449
13587
  if (visited.has(current)) {
13450
13588
  return CIRCULAR_REF;
@@ -13452,7 +13590,7 @@ var dereference = async (schema2, resolvers = []) => {
13452
13590
  visited.add(current);
13453
13591
  if (Array.isArray(current)) {
13454
13592
  for (let index = 0; index < current.length; index++) {
13455
- current[index] = await resolve(current[index], `${path69}/${index}`);
13593
+ current[index] = await resolve(current[index], `${path70}/${index}`);
13456
13594
  }
13457
13595
  } else {
13458
13596
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -13463,13 +13601,13 @@ var dereference = async (schema2, resolvers = []) => {
13463
13601
  for (const resolver of resolvers) {
13464
13602
  const resolved = await resolver($ref);
13465
13603
  if (resolved) {
13466
- result2 = await resolve(resolved, path69);
13604
+ result2 = await resolve(resolved, path70);
13467
13605
  break;
13468
13606
  }
13469
13607
  }
13470
13608
  if (result2 === void 0) {
13471
13609
  const resolved = await resolveLocalRef(cloned, $ref);
13472
- result2 = await resolve(resolved, path69);
13610
+ result2 = await resolve(resolved, path70);
13473
13611
  }
13474
13612
  if (hasSiblings) {
13475
13613
  if (result2 === CIRCULAR_REF) {
@@ -13482,7 +13620,7 @@ var dereference = async (schema2, resolvers = []) => {
13482
13620
  return result2;
13483
13621
  }
13484
13622
  for (const key in current) {
13485
- current[key] = await resolve(current[key], `${path69}/${key}`);
13623
+ current[key] = await resolve(current[key], `${path70}/${key}`);
13486
13624
  }
13487
13625
  }
13488
13626
  visited.delete(current);
@@ -13521,9 +13659,9 @@ var upgradeSchema = (schema2) => {
13521
13659
  }
13522
13660
  return sub;
13523
13661
  });
13524
- schema2 = traverse(schema2, (sub, path69) => {
13662
+ schema2 = traverse(schema2, (sub, path70) => {
13525
13663
  if (sub.example !== void 0) {
13526
- if (isSchemaPath(path69 ?? [])) {
13664
+ if (isSchemaPath(path70 ?? [])) {
13527
13665
  sub.examples = [sub.example];
13528
13666
  } else {
13529
13667
  sub.examples = {
@@ -13536,11 +13674,11 @@ var upgradeSchema = (schema2) => {
13536
13674
  }
13537
13675
  return sub;
13538
13676
  });
13539
- schema2 = traverse(schema2, (schema3, path69) => {
13677
+ schema2 = traverse(schema2, (schema3, path70) => {
13540
13678
  if (schema3.type === "object" && schema3.properties !== void 0) {
13541
- const parentPath = path69?.slice(0, -1);
13679
+ const parentPath = path70?.slice(0, -1);
13542
13680
  const isMultipart = parentPath?.some((segment, index) => {
13543
- return segment === "content" && path69?.[index + 1] === "multipart/form-data";
13681
+ return segment === "content" && path70?.[index + 1] === "multipart/form-data";
13544
13682
  });
13545
13683
  if (isMultipart) {
13546
13684
  const entries = Object.entries(schema3.properties);
@@ -13554,8 +13692,8 @@ var upgradeSchema = (schema2) => {
13554
13692
  }
13555
13693
  return schema3;
13556
13694
  });
13557
- schema2 = traverse(schema2, (schema3, path69) => {
13558
- if (path69?.includes("content") && path69.includes("application/octet-stream")) {
13695
+ schema2 = traverse(schema2, (schema3, path70) => {
13696
+ if (path70?.includes("content") && path70.includes("application/octet-stream")) {
13559
13697
  return {};
13560
13698
  }
13561
13699
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -13581,11 +13719,11 @@ var upgradeSchema = (schema2) => {
13581
13719
  }
13582
13720
  return sub;
13583
13721
  });
13584
- schema2 = traverse(schema2, (schema3, path69) => {
13722
+ schema2 = traverse(schema2, (schema3, path70) => {
13585
13723
  if (schema3.type === "string" && schema3.format === "byte") {
13586
- const parentPath = path69?.slice(0, -1);
13724
+ const parentPath = path70?.slice(0, -1);
13587
13725
  const contentMediaType = parentPath?.find(
13588
- (_, index) => path69?.[index - 1] === "content"
13726
+ (_, index) => path70?.[index - 1] === "content"
13589
13727
  );
13590
13728
  return {
13591
13729
  type: "string",
@@ -13597,7 +13735,7 @@ var upgradeSchema = (schema2) => {
13597
13735
  });
13598
13736
  return schema2;
13599
13737
  };
13600
- function isSchemaPath(path69) {
13738
+ function isSchemaPath(path70) {
13601
13739
  const schemaLocations = [
13602
13740
  ["components", "schemas"],
13603
13741
  "properties",
@@ -13610,10 +13748,10 @@ function isSchemaPath(path69) {
13610
13748
  ];
13611
13749
  return schemaLocations.some((location) => {
13612
13750
  if (Array.isArray(location)) {
13613
- return location.every((segment, index) => path69[index] === segment);
13751
+ return location.every((segment, index) => path70[index] === segment);
13614
13752
  }
13615
- return path69.includes(location);
13616
- }) || path69.includes("schema") || path69.some((segment) => segment.endsWith("Schema"));
13753
+ return path70.includes(location);
13754
+ }) || path70.includes("schema") || path70.some((segment) => segment.endsWith("Schema"));
13617
13755
  }
13618
13756
 
13619
13757
  // src/lib/oas/parser/index.ts
@@ -13695,13 +13833,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
13695
13833
  "anyOf",
13696
13834
  "oneOf"
13697
13835
  ]);
13698
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path69 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
13836
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path70 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
13699
13837
  if (obj === null || typeof obj !== "object") return obj;
13700
13838
  const refPath = obj.__$ref;
13701
13839
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
13702
13840
  if (isCircular) {
13703
13841
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
13704
- const circularProp = path69.find((p) => !OPENAPI_PROPS.has(p)) || path69[0];
13842
+ const circularProp = path70.find((p) => !OPENAPI_PROPS.has(p)) || path70[0];
13705
13843
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
13706
13844
  }
13707
13845
  if (refs.has(obj)) return refs.get(obj);
@@ -13711,7 +13849,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
13711
13849
  value,
13712
13850
  currentPath,
13713
13851
  refs,
13714
- [...path69, key],
13852
+ [...path70, key],
13715
13853
  currentRefPaths
13716
13854
  );
13717
13855
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -13746,7 +13884,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
13746
13884
  var getAllTags = (schema2) => {
13747
13885
  const rootTags = schema2.tags ?? [];
13748
13886
  const operations = Object.values(schema2.paths ?? {}).flatMap(
13749
- (path69) => HttpMethods.map((k) => path69?.[k]).filter((op) => op != null)
13887
+ (path70) => HttpMethods.map((k) => path70?.[k]).filter((op) => op != null)
13750
13888
  );
13751
13889
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
13752
13890
  const hasUntaggedOperations = operations.some(
@@ -13801,7 +13939,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
13801
13939
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
13802
13940
  var getAllOperations = (paths) => {
13803
13941
  const operations = Object.entries(paths ?? {}).flatMap(
13804
- ([path69, value]) => HttpMethods.flatMap((method) => {
13942
+ ([path70, value]) => HttpMethods.flatMap((method) => {
13805
13943
  if (!value?.[method]) return [];
13806
13944
  const operation = value[method];
13807
13945
  const pathParameters = value.parameters ?? [];
@@ -13821,7 +13959,7 @@ var getAllOperations = (paths) => {
13821
13959
  return {
13822
13960
  ...operation,
13823
13961
  method,
13824
- path: path69,
13962
+ path: path70,
13825
13963
  parameters,
13826
13964
  servers,
13827
13965
  tags: operation.tags ?? []
@@ -14179,8 +14317,8 @@ var Schema = builder.objectRef("Schema").implement({
14179
14317
  }),
14180
14318
  paths: t.field({
14181
14319
  type: [PathItem],
14182
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path69, value]) => ({
14183
- path: path69,
14320
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path70, value]) => ({
14321
+ path: path70,
14184
14322
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
14185
14323
  methods: Object.keys(value)
14186
14324
  }))
@@ -14345,7 +14483,7 @@ init_joinUrl();
14345
14483
 
14346
14484
  // src/vite/api/schema-codegen.ts
14347
14485
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
14348
- var getSegmentsFromPath = (path69) => path69.split("/").slice(1).map(unescapeJsonPointer);
14486
+ var getSegmentsFromPath = (path70) => path70.split("/").slice(1).map(unescapeJsonPointer);
14349
14487
  var createLocalRefMap = (obj) => {
14350
14488
  const refMap = /* @__PURE__ */ new Map();
14351
14489
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -14376,16 +14514,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
14376
14514
  /"__refMap\+Siblings:(.*?)"/g,
14377
14515
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
14378
14516
  );
14379
- var lookup2 = (schema2, path69, filePath) => {
14380
- const parts = getSegmentsFromPath(path69);
14517
+ var lookup2 = (schema2, path70, filePath) => {
14518
+ const parts = getSegmentsFromPath(path70);
14381
14519
  let val = schema2;
14382
14520
  for (const part of parts) {
14383
14521
  while (val.$ref?.startsWith("#/")) {
14384
- val = val.$ref === path69 ? val : lookup2(schema2, val.$ref, filePath);
14522
+ val = val.$ref === path70 ? val : lookup2(schema2, val.$ref, filePath);
14385
14523
  }
14386
14524
  if (val[part] === void 0) {
14387
14525
  throw new Error(
14388
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path69}`
14526
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path70}`
14389
14527
  );
14390
14528
  }
14391
14529
  val = val[part];
@@ -14630,8 +14768,8 @@ var SchemaManager = class {
14630
14768
  }
14631
14769
  }
14632
14770
  };
14633
- getLatestSchema = (path69) => this.processedSchemas[path69]?.at(0);
14634
- getSchemasForPath = (path69) => this.processedSchemas[path69];
14771
+ getLatestSchema = (path70) => this.processedSchemas[path70]?.at(0);
14772
+ getSchemasForPath = (path70) => this.processedSchemas[path70];
14635
14773
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
14636
14774
  getUrlToFilePathMap = () => {
14637
14775
  const map = /* @__PURE__ */ new Map();
@@ -16467,9 +16605,53 @@ var viteModulesPlugin = () => {
16467
16605
  };
16468
16606
  var plugin_modules_default = viteModulesPlugin;
16469
16607
 
16470
- // src/vite/plugin-search.ts
16608
+ // src/vite/plugin-offroot-resolve.ts
16471
16609
  init_loader();
16472
16610
  import path41 from "node:path";
16611
+ function stripQuery(id) {
16612
+ const query = id.indexOf("?");
16613
+ return query === -1 ? id : id.slice(0, query);
16614
+ }
16615
+ function isInside(parent, child) {
16616
+ const relative = path41.relative(path41.resolve(parent), path41.resolve(child));
16617
+ return relative === "" || !relative.startsWith("..") && !path41.isAbsolute(relative);
16618
+ }
16619
+ function isBareSpecifier(source) {
16620
+ return !source.startsWith("\0") && !source.startsWith(".") && !source.startsWith("/") && !path41.isAbsolute(source);
16621
+ }
16622
+ function isInsideNodeModules(filePath) {
16623
+ return filePath.split(path41.sep).includes("node_modules");
16624
+ }
16625
+ function shouldResolveFromSiteRoot(source, importer, rootDir) {
16626
+ if (!importer || !isBareSpecifier(source)) {
16627
+ return false;
16628
+ }
16629
+ const importerPath = stripQuery(importer);
16630
+ if (isInside(rootDir, importerPath) || isInsideNodeModules(importerPath)) {
16631
+ return false;
16632
+ }
16633
+ return true;
16634
+ }
16635
+ function viteOffrootResolvePlugin() {
16636
+ return {
16637
+ name: "zudoku-offroot-resolve",
16638
+ enforce: "pre",
16639
+ async resolveId(source, importer, options) {
16640
+ const rootDir = getCurrentConfig().__meta.rootDir;
16641
+ if (!shouldResolveFromSiteRoot(source, importer, rootDir)) {
16642
+ return;
16643
+ }
16644
+ return this.resolve(source, path41.join(rootDir, "package.json"), {
16645
+ ...options,
16646
+ skipSelf: true
16647
+ });
16648
+ }
16649
+ };
16650
+ }
16651
+
16652
+ // src/vite/plugin-search.ts
16653
+ init_loader();
16654
+ import path42 from "node:path";
16473
16655
  var viteSearchPlugin = () => {
16474
16656
  const virtualModuleId4 = "virtual:zudoku-search-plugin";
16475
16657
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -16487,7 +16669,7 @@ var viteSearchPlugin = () => {
16487
16669
  return resolvedVirtualModuleId5;
16488
16670
  }
16489
16671
  if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
16490
- return path41.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
16672
+ return path42.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
16491
16673
  }
16492
16674
  },
16493
16675
  async load(id) {
@@ -16603,6 +16785,7 @@ init_plugin_theme();
16603
16785
  function vitePlugin() {
16604
16786
  return [
16605
16787
  viteShikiRegisterPlugin(),
16788
+ viteOffrootResolvePlugin(),
16606
16789
  viteConfigReloadPlugin(),
16607
16790
  plugin_local_manifest_default(),
16608
16791
  plugin_mdx_default(),
@@ -16626,17 +16809,17 @@ function vitePlugin() {
16626
16809
  }
16627
16810
 
16628
16811
  // src/vite/config.ts
16629
- var browserConfigLoaderPath2 = path42.join(
16812
+ var browserConfigLoaderPath2 = path43.join(
16630
16813
  getZudokuRootDir(),
16631
16814
  "src/config/apitogo-config-loader.browser.ts"
16632
16815
  );
16633
16816
  var resolveMergedPublicDir = (rootDir, merged) => {
16634
16817
  if (merged.publicDir === false) return void 0;
16635
16818
  const rel = typeof merged.publicDir === "string" ? merged.publicDir : "public";
16636
- return path42.resolve(rootDir, rel);
16819
+ return path43.resolve(rootDir, rel);
16637
16820
  };
16638
- var getAppClientEntryPath = () => path42.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
16639
- var getAppServerEntryPath = () => path42.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
16821
+ var getAppClientEntryPath = () => path43.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
16822
+ var getAppServerEntryPath = () => path43.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
16640
16823
  var hasLoggedCdnInfo = false;
16641
16824
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
16642
16825
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -16666,7 +16849,7 @@ async function getViteConfig(dir, configEnv) {
16666
16849
  );
16667
16850
  if (ZuploEnv.isZuplo) {
16668
16851
  dotenv.config({
16669
- path: path42.resolve(config2.__meta.rootDir, "../.env.zuplo"),
16852
+ path: path43.resolve(config2.__meta.rootDir, "../.env.zuplo"),
16670
16853
  quiet: true
16671
16854
  });
16672
16855
  }
@@ -16691,11 +16874,11 @@ async function getViteConfig(dir, configEnv) {
16691
16874
  client: {
16692
16875
  resolve: {
16693
16876
  alias: {
16694
- [path42.join(
16877
+ [path43.join(
16695
16878
  getZudokuRootDir(),
16696
16879
  "src/config/apitogo-config-loader.node.ts"
16697
16880
  )]: browserConfigLoaderPath2,
16698
- [path42.join(
16881
+ [path43.join(
16699
16882
  getZudokuRootDir(),
16700
16883
  "src/config/apitogo-config-loader.node.js"
16701
16884
  )]: browserConfigLoaderPath2
@@ -16727,6 +16910,9 @@ async function getViteConfig(dir, configEnv) {
16727
16910
  server: {
16728
16911
  middlewareMode: true,
16729
16912
  open: true,
16913
+ fs: {
16914
+ allow: [dir, path43.dirname(dir)]
16915
+ },
16730
16916
  watch: {
16731
16917
  ignored: [
16732
16918
  `${dir}/dist`,
@@ -16741,8 +16927,8 @@ async function getViteConfig(dir, configEnv) {
16741
16927
  ssr: configEnv.isSsrBuild,
16742
16928
  sourcemap: true,
16743
16929
  target: "es2022",
16744
- outDir: path42.resolve(
16745
- path42.join(
16930
+ outDir: path43.resolve(
16931
+ path43.join(
16746
16932
  dir,
16747
16933
  "dist",
16748
16934
  config2.basePath ?? "",
@@ -16761,7 +16947,7 @@ async function getViteConfig(dir, configEnv) {
16761
16947
  },
16762
16948
  experimental: {
16763
16949
  renderBuiltUrl(filename) {
16764
- if (cdnUrl?.base && [".js", ".css"].includes(path42.extname(filename))) {
16950
+ if (cdnUrl?.base && [".js", ".css"].includes(path43.extname(filename))) {
16765
16951
  return joinUrl(cdnUrl.base, filename);
16766
16952
  }
16767
16953
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -16774,7 +16960,7 @@ async function getViteConfig(dir, configEnv) {
16774
16960
  esbuildOptions: {
16775
16961
  target: "es2022"
16776
16962
  },
16777
- entries: [path42.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
16963
+ entries: [path43.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
16778
16964
  exclude: [
16779
16965
  "@lukoweb/apitogo",
16780
16966
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -16880,7 +17066,7 @@ init_package_json();
16880
17066
  init_joinUrl();
16881
17067
  import assert from "node:assert";
16882
17068
  import { cp, mkdir as mkdir7, writeFile as writeFile8 } from "node:fs/promises";
16883
- import path43 from "node:path";
17069
+ import path44 from "node:path";
16884
17070
  var pkgJson = getZudokuPackageJson();
16885
17071
  function generateOutput({
16886
17072
  config: config2,
@@ -16937,9 +17123,9 @@ async function writeOutput(dir, {
16937
17123
  rewrites
16938
17124
  }) {
16939
17125
  const output2 = generateOutput({ config: config2, redirects, rewrites });
16940
- const outputDir = process.env.VERCEL ? path43.join(dir, ".vercel/output") : path43.join(dir, "dist/.output");
17126
+ const outputDir = process.env.VERCEL ? path44.join(dir, ".vercel/output") : path44.join(dir, "dist/.output");
16941
17127
  await mkdir7(outputDir, { recursive: true });
16942
- const outputFile = path43.join(outputDir, "config.json");
17128
+ const outputFile = path44.join(outputDir, "config.json");
16943
17129
  await writeFile8(outputFile, JSON.stringify(output2, null, 2), "utf-8");
16944
17130
  if (process.env.VERCEL) {
16945
17131
  console.log("Wrote Vercel output to", outputDir);
@@ -16951,7 +17137,7 @@ init_logger();
16951
17137
  init_file_exists();
16952
17138
  import { readFile as readFile10, rm as rm2 } from "node:fs/promises";
16953
17139
  import os from "node:os";
16954
- import path46 from "node:path";
17140
+ import path47 from "node:path";
16955
17141
  import { pathToFileURL } from "node:url";
16956
17142
  import { createIndex } from "pagefind";
16957
17143
  import colors8 from "picocolors";
@@ -16993,7 +17179,7 @@ function throttle(fn) {
16993
17179
  init_joinUrl();
16994
17180
  import { createWriteStream as createWriteStream3, existsSync as existsSync3 } from "node:fs";
16995
17181
  import { mkdir as mkdir8 } from "node:fs/promises";
16996
- import path44 from "node:path";
17182
+ import path45 from "node:path";
16997
17183
  import colors6 from "picocolors";
16998
17184
  import { SitemapStream } from "sitemap";
16999
17185
  async function generateSitemap({
@@ -17007,11 +17193,11 @@ async function generateSitemap({
17007
17193
  return;
17008
17194
  }
17009
17195
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
17010
- const outputDir = path44.resolve(baseOutputDir, config2.outDir ?? "");
17196
+ const outputDir = path45.resolve(baseOutputDir, config2.outDir ?? "");
17011
17197
  if (!existsSync3(outputDir)) {
17012
17198
  await mkdir8(outputDir, { recursive: true });
17013
17199
  }
17014
- const sitemapOutputPath = path44.join(outputDir, "sitemap.xml");
17200
+ const sitemapOutputPath = path45.join(outputDir, "sitemap.xml");
17015
17201
  const writeStream = createWriteStream3(sitemapOutputPath);
17016
17202
  sitemap.pipe(writeStream);
17017
17203
  let lastmod;
@@ -17041,14 +17227,14 @@ async function generateSitemap({
17041
17227
 
17042
17228
  // src/vite/prerender/utils.ts
17043
17229
  init_joinUrl();
17044
- var resolveRoutePath = (path69) => {
17045
- const segments = path69.split("/");
17230
+ var resolveRoutePath = (path70) => {
17231
+ const segments = path70.split("/");
17046
17232
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
17047
17233
  return void 0;
17048
17234
  }
17049
17235
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
17050
17236
  };
17051
- var isSkipped = (path69) => path69.includes("*") || /^\d+$/.test(path69);
17237
+ var isSkipped = (path70) => path70.includes("*") || /^\d+$/.test(path70);
17052
17238
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
17053
17239
  if (route.path && isSkipped(route.path)) return [];
17054
17240
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -17097,12 +17283,12 @@ var prerender = async ({
17097
17283
  serverConfigFilename,
17098
17284
  writeRedirects = true
17099
17285
  }) => {
17100
- const distDir = path46.join(dir, "dist", basePath);
17286
+ const distDir = path47.join(dir, "dist", basePath);
17101
17287
  const serverConfigPath = pathToFileURL(
17102
- path46.join(distDir, "server", serverConfigFilename)
17288
+ path47.join(distDir, "server", serverConfigFilename)
17103
17289
  ).href;
17104
17290
  const entryServerPath = pathToFileURL(
17105
- path46.join(distDir, "server/entry.server.js")
17291
+ path47.join(distDir, "server/entry.server.js")
17106
17292
  ).href;
17107
17293
  const rawConfig = await import(serverConfigPath).then(
17108
17294
  (m) => m.default
@@ -17187,7 +17373,7 @@ var prerender = async ({
17187
17373
  })
17188
17374
  );
17189
17375
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
17190
- outputPath: path46.join(distDir, "pagefind")
17376
+ outputPath: path47.join(distDir, "pagefind")
17191
17377
  });
17192
17378
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
17193
17379
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
@@ -17219,7 +17405,7 @@ var prerender = async ({
17219
17405
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
17220
17406
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
17221
17407
  const llmsConfig = docsConfig.llms ?? {};
17222
- const markdownInfoPath = path46.join(
17408
+ const markdownInfoPath = path47.join(
17223
17409
  dir,
17224
17410
  "node_modules/.apitogo/markdown-info.json"
17225
17411
  );
@@ -17310,7 +17496,7 @@ async function runBuild(options) {
17310
17496
  html,
17311
17497
  basePath: config2.basePath
17312
17498
  });
17313
- await rm3(path47.join(clientOutDir, "index.html"), { force: true });
17499
+ await rm3(path48.join(clientOutDir, "index.html"), { force: true });
17314
17500
  } else {
17315
17501
  await runPrerender({
17316
17502
  dir,
@@ -17334,7 +17520,7 @@ var runPrerender = async (options) => {
17334
17520
  serverConfigFilename,
17335
17521
  writeRedirects: process.env.VERCEL === void 0
17336
17522
  });
17337
- const indexHtml = path47.join(clientOutDir, "index.html");
17523
+ const indexHtml = path48.join(clientOutDir, "index.html");
17338
17524
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
17339
17525
  await writeFile10(indexHtml, html, "utf-8");
17340
17526
  }
@@ -17344,15 +17530,15 @@ var runPrerender = async (options) => {
17344
17530
  for (const statusPage of statusPages) {
17345
17531
  await rename(
17346
17532
  statusPage,
17347
- path47.join(dir, DIST_DIR, path47.basename(statusPage))
17533
+ path48.join(dir, DIST_DIR, path48.basename(statusPage))
17348
17534
  );
17349
17535
  }
17350
17536
  await rm3(serverOutDir, { recursive: true, force: true });
17351
17537
  if (process.env.VERCEL) {
17352
- await mkdir9(path47.join(dir, ".vercel/output/static"), { recursive: true });
17538
+ await mkdir9(path48.join(dir, ".vercel/output/static"), { recursive: true });
17353
17539
  await rename(
17354
- path47.join(dir, DIST_DIR),
17355
- path47.join(dir, ".vercel/output/static")
17540
+ path48.join(dir, DIST_DIR),
17541
+ path48.join(dir, ".vercel/output/static")
17356
17542
  );
17357
17543
  }
17358
17544
  await writeOutput(dir, {
@@ -17362,7 +17548,7 @@ var runPrerender = async (options) => {
17362
17548
  });
17363
17549
  if (ZuploEnv.isZuplo && issuer) {
17364
17550
  await writeFile10(
17365
- path47.join(dir, DIST_DIR, ".output/zuplo.json"),
17551
+ path48.join(dir, DIST_DIR, ".output/zuplo.json"),
17366
17552
  JSON.stringify({ issuer }, null, 2),
17367
17553
  "utf-8"
17368
17554
  );
@@ -17374,10 +17560,10 @@ var runPrerender = async (options) => {
17374
17560
  };
17375
17561
  var bundleSSREntry = async (options) => {
17376
17562
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
17377
- const tempEntryPath = path47.join(dir, "__ssr-entry.ts");
17563
+ const tempEntryPath = path48.join(dir, "__ssr-entry.ts");
17378
17564
  const packageRoot = getZudokuRootDir();
17379
17565
  const templateContent = await readFile11(
17380
- path47.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
17566
+ path48.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
17381
17567
  "utf-8"
17382
17568
  );
17383
17569
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
@@ -17392,9 +17578,9 @@ var bundleSSREntry = async (options) => {
17392
17578
  platform: adapter === "node" ? "node" : "neutral",
17393
17579
  target: "es2022",
17394
17580
  format: "esm",
17395
- outfile: path47.join(serverOutDir, "entry.js"),
17581
+ outfile: path48.join(serverOutDir, "entry.js"),
17396
17582
  external: ["./entry.server.js", `./${serverConfigFilename}`],
17397
- nodePaths: [path47.join(packageRoot, "node_modules")],
17583
+ nodePaths: [path48.join(packageRoot, "node_modules")],
17398
17584
  banner: { js: "// Bundled SSR entry" }
17399
17585
  });
17400
17586
  } finally {
@@ -17407,11 +17593,11 @@ init_logger();
17407
17593
  init_package_json();
17408
17594
 
17409
17595
  // src/cli/preview/handler.ts
17410
- import path48 from "node:path";
17596
+ import path49 from "node:path";
17411
17597
  import { preview as vitePreview } from "vite";
17412
17598
  var DEFAULT_PREVIEW_PORT = 4e3;
17413
17599
  async function preview(argv) {
17414
- const dir = path48.resolve(process.cwd(), argv.dir);
17600
+ const dir = path49.resolve(process.cwd(), argv.dir);
17415
17601
  const viteConfig = await getViteConfig(dir, {
17416
17602
  command: "serve",
17417
17603
  mode: "production",
@@ -17452,7 +17638,7 @@ async function build(argv) {
17452
17638
  printDiagnosticsToConsole("");
17453
17639
  printDiagnosticsToConsole("");
17454
17640
  }
17455
- const dir = path49.resolve(process.cwd(), argv.dir);
17641
+ const dir = path50.resolve(process.cwd(), argv.dir);
17456
17642
  try {
17457
17643
  await runBuild({
17458
17644
  dir,
@@ -17512,12 +17698,12 @@ var build_default = {
17512
17698
  };
17513
17699
 
17514
17700
  // src/cli/check/handler.ts
17515
- import path51 from "node:path";
17701
+ import path52 from "node:path";
17516
17702
 
17517
17703
  // src/cli/platform/tools/check-publish-readiness.ts
17518
- import path50 from "node:path";
17704
+ import path51 from "node:path";
17519
17705
  async function checkPublishReadiness(client, _config, args) {
17520
- const sourceDirectory = path50.resolve(args.sourceDirectory);
17706
+ const sourceDirectory = path51.resolve(args.sourceDirectory);
17521
17707
  const manifest = await readManifest(sourceDirectory) ?? createScaffoldManifest();
17522
17708
  const emailOptions = await resolveEmailOptionsForPublish(
17523
17709
  client,
@@ -17595,7 +17781,7 @@ async function checkPublishReadiness(client, _config, args) {
17595
17781
 
17596
17782
  // src/cli/check/handler.ts
17597
17783
  async function check(argv) {
17598
- const sourceDirectory = path51.resolve(process.cwd(), argv.dir);
17784
+ const sourceDirectory = path52.resolve(process.cwd(), argv.dir);
17599
17785
  const config2 = loadConfig();
17600
17786
  const client = new PlatformApiClient(config2);
17601
17787
  let result;
@@ -17640,13 +17826,13 @@ var check_default = {
17640
17826
  // src/cli/make-config/handler.ts
17641
17827
  import { constants as constants2 } from "node:fs";
17642
17828
  import { access as access8, mkdir as mkdir12, readFile as readFile16, writeFile as writeFile15 } from "node:fs/promises";
17643
- import path59 from "node:path";
17829
+ import path60 from "node:path";
17644
17830
  import { stdin as input2 } from "node:process";
17645
17831
  import { glob as glob5 } from "glob";
17646
17832
 
17647
17833
  // src/cli/scaffold/dev-portal-config-pages.ts
17648
17834
  import { access as access4, readFile as readFile12, rename as rename2, rm as rm4, writeFile as writeFile11 } from "node:fs/promises";
17649
- import path52 from "node:path";
17835
+ import path53 from "node:path";
17650
17836
  async function writeConfigAtomically(filePath, content) {
17651
17837
  const temporaryPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
17652
17838
  try {
@@ -17659,7 +17845,7 @@ async function writeConfigAtomically(filePath, content) {
17659
17845
  }
17660
17846
  async function resolveApitogoConfigPath(sourceDirectory) {
17661
17847
  for (const filename of ["apitogo.config.tsx", "apitogo.config.jsx"]) {
17662
- const configPath = path52.join(sourceDirectory, filename);
17848
+ const configPath = path53.join(sourceDirectory, filename);
17663
17849
  try {
17664
17850
  await access4(configPath);
17665
17851
  return configPath;
@@ -18396,16 +18582,16 @@ async function wireNewDevPortalPageInConfig(sourceDirectory, slug, label) {
18396
18582
 
18397
18583
  // src/cli/scaffold/wire-openapi.ts
18398
18584
  import { access as access6, readFile as readFile14, writeFile as writeFile13 } from "node:fs/promises";
18399
- import path55 from "node:path";
18585
+ import path56 from "node:path";
18400
18586
 
18401
18587
  // src/cli/scaffold/scaffold-dev-portal-site.ts
18402
18588
  import { mkdir as mkdir10, readFile as readFile13, writeFile as writeFile12 } from "node:fs/promises";
18403
- import path54 from "node:path";
18589
+ import path55 from "node:path";
18404
18590
 
18405
18591
  // src/cli/scaffold/create-apitogo-cli.ts
18406
18592
  import { spawn as spawn3 } from "node:child_process";
18407
18593
  import { access as access5, rm as rm5 } from "node:fs/promises";
18408
- import path53 from "node:path";
18594
+ import path54 from "node:path";
18409
18595
 
18410
18596
  // src/cli/scaffold/apitogo-npm-packages.ts
18411
18597
  var DEFAULT_CREATE_APITOGO_PACKAGE2 = "@lukoweb/create-apitogo@latest";
@@ -18506,9 +18692,9 @@ function resolveDocToolPath(explicit) {
18506
18692
  return value || void 0;
18507
18693
  }
18508
18694
  function splitOutputDirectory(outputDirectory) {
18509
- const resolvedOutputDirectory = path53.resolve(outputDirectory);
18510
- const projectName = path53.basename(resolvedOutputDirectory);
18511
- const parentDirectory = path53.dirname(resolvedOutputDirectory);
18695
+ const resolvedOutputDirectory = path54.resolve(outputDirectory);
18696
+ const projectName = path54.basename(resolvedOutputDirectory);
18697
+ const parentDirectory = path54.dirname(resolvedOutputDirectory);
18512
18698
  if (!projectName || projectName === "." || projectName === "..") {
18513
18699
  throw new Error(
18514
18700
  "outputDirectory must be a named folder (e.g. ./dev-portal-site), not the current directory."
@@ -18534,7 +18720,7 @@ async function directoryHasEntries(dir) {
18534
18720
  }
18535
18721
  }
18536
18722
  function resolveLocalCreateApitogoEntry(docToolPath) {
18537
- return path53.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
18723
+ return path54.resolve(docToolPath, "packages/create-zudoku/dist/index.js");
18538
18724
  }
18539
18725
  async function resolveCreateApitogoInvocation(options) {
18540
18726
  const docToolPath = resolveDocToolPath(options.docToolPath);
@@ -18616,7 +18802,7 @@ async function runCreateApitogoDevPortal(options) {
18616
18802
  result.exitCode
18617
18803
  );
18618
18804
  }
18619
- if (!await pathExists3(path53.join(resolvedOutputDirectory, "package.json"))) {
18805
+ if (!await pathExists3(path54.join(resolvedOutputDirectory, "package.json"))) {
18620
18806
  throw new CreateApitogoCliError(
18621
18807
  `create-apitogo completed but package.json was not found at ${resolvedOutputDirectory}`,
18622
18808
  result.output,
@@ -18672,7 +18858,7 @@ function ensureRequiredApitogoModules(pkg, options) {
18672
18858
  ]
18673
18859
  ]) {
18674
18860
  if (options.docToolPath) {
18675
- deps[moduleName] = `file:${path54.join(options.docToolPath, localPath)}`;
18861
+ deps[moduleName] = `file:${path55.join(options.docToolPath, localPath)}`;
18676
18862
  continue;
18677
18863
  }
18678
18864
  deps[moduleName] = `npm:${moduleName}@${moduleAliasVersion}`;
@@ -18701,7 +18887,7 @@ function rewritePackageJson(raw, options) {
18701
18887
  if (!deps) continue;
18702
18888
  for (const [dep, relativePath] of Object.entries(DOC_TOOL_LOCAL_PACKAGE_PATHS)) {
18703
18889
  if (dep in deps) {
18704
- deps[dep] = `file:${path54.join(options.docToolPath, relativePath)}`;
18890
+ deps[dep] = `file:${path55.join(options.docToolPath, relativePath)}`;
18705
18891
  linkedWorkspacePackage = true;
18706
18892
  }
18707
18893
  }
@@ -18798,23 +18984,23 @@ function patchDashboardPageConfig(content) {
18798
18984
  );
18799
18985
  }
18800
18986
  async function ensureAccountPlansPage(outputDirectory) {
18801
- const pagePath = path54.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
18987
+ const pagePath = path55.join(outputDirectory, ACCOUNT_PLANS_PAGE_PATH);
18802
18988
  try {
18803
18989
  await readFile13(pagePath, "utf8");
18804
18990
  return void 0;
18805
18991
  } catch {
18806
- await mkdir10(path54.dirname(pagePath), { recursive: true });
18992
+ await mkdir10(path55.dirname(pagePath), { recursive: true });
18807
18993
  await writeFile12(pagePath, ACCOUNT_PLANS_PAGE);
18808
18994
  return ACCOUNT_PLANS_PAGE_PATH;
18809
18995
  }
18810
18996
  }
18811
18997
  async function ensureDashboardPage(outputDirectory) {
18812
- const pagePath = path54.join(outputDirectory, DASHBOARD_PAGE_PATH);
18998
+ const pagePath = path55.join(outputDirectory, DASHBOARD_PAGE_PATH);
18813
18999
  try {
18814
19000
  await readFile13(pagePath, "utf8");
18815
19001
  return void 0;
18816
19002
  } catch {
18817
- await mkdir10(path54.dirname(pagePath), { recursive: true });
19003
+ await mkdir10(path55.dirname(pagePath), { recursive: true });
18818
19004
  await writeFile12(pagePath, DASHBOARD_PAGE);
18819
19005
  return DASHBOARD_PAGE_PATH;
18820
19006
  }
@@ -18865,7 +19051,7 @@ function patchApitogoConfig(content, options) {
18865
19051
  async function patchScaffoldedSite(outputDirectory, options) {
18866
19052
  const title = options.branding?.title ?? options.siteName;
18867
19053
  const filesWritten = [];
18868
- const packageJsonPath = path54.join(outputDirectory, "package.json");
19054
+ const packageJsonPath = path55.join(outputDirectory, "package.json");
18869
19055
  if (options.patchPackageJson !== false) {
18870
19056
  const packageJson2 = await readFile13(packageJsonPath, "utf8");
18871
19057
  await writeFile12(
@@ -18878,7 +19064,7 @@ async function patchScaffoldedSite(outputDirectory, options) {
18878
19064
  );
18879
19065
  filesWritten.push("package.json");
18880
19066
  }
18881
- const configPath = path54.join(outputDirectory, "apitogo.config.tsx");
19067
+ const configPath = path55.join(outputDirectory, "apitogo.config.tsx");
18882
19068
  const configContent = await readFile13(configPath, "utf8");
18883
19069
  await writeFile12(
18884
19070
  configPath,
@@ -18973,8 +19159,8 @@ async function discoverOpenApiByMode(siteDirectory, mode) {
18973
19159
  return discoverNearbyOpenApi(siteDirectory);
18974
19160
  }
18975
19161
  async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
18976
- const resolvedSource = path55.resolve(sourceDirectory);
18977
- const resolvedOpenApi = path55.resolve(openApiPath);
19162
+ const resolvedSource = path56.resolve(sourceDirectory);
19163
+ const resolvedOpenApi = path56.resolve(openApiPath);
18978
19164
  const input3 = toSiteRelativeOpenApiInput(resolvedSource, resolvedOpenApi);
18979
19165
  const validation = await validateOpenApiFile(resolvedOpenApi);
18980
19166
  if (!validation.valid) {
@@ -18999,7 +19185,7 @@ async function wireDevPortalOpenApi(sourceDirectory, openApiPath) {
18999
19185
  "utf8"
19000
19186
  );
19001
19187
  } else {
19002
- const tsxConfigPath = path55.join(resolvedSource, "apitogo.config.tsx");
19188
+ const tsxConfigPath = path56.join(resolvedSource, "apitogo.config.tsx");
19003
19189
  const configContent = await readFile14(tsxConfigPath, "utf8");
19004
19190
  try {
19005
19191
  const patched = patchApitogoConfigOpenApiToFile(configContent, input3);
@@ -19087,10 +19273,10 @@ async function discoverAndWireOpenApi(siteDirectory, mode) {
19087
19273
  // src/cli/make-config/interactive.ts
19088
19274
  import { createInterface } from "node:readline/promises";
19089
19275
  import { stdin as input, stdout as output } from "node:process";
19090
- import path57 from "node:path";
19276
+ import path58 from "node:path";
19091
19277
 
19092
19278
  // src/cli/make-config/json-config.ts
19093
- import path56 from "node:path";
19279
+ import path57 from "node:path";
19094
19280
  var APITOGO_JSON_FILENAME = "apitogo.config.json";
19095
19281
  var DOCUMENTATION_NAV_LABEL2 = "Documentation";
19096
19282
  var API_REFERENCE_PATH = "/api";
@@ -19259,28 +19445,37 @@ function createDefaultApitogoJsonConfig(options) {
19259
19445
  displayName: "Free",
19260
19446
  priceAmount: 0,
19261
19447
  billingPeriod: "month",
19262
- limitsJson: '{"rateLimit":{"calls":10,"renewalPeriodSeconds":1},"quota":{"calls":1000,"renewalPeriodDays":30}}'
19448
+ limits: {
19449
+ rateLimit: { calls: 10, renewalPeriodSeconds: 1 },
19450
+ quota: { calls: 1e3, renewalPeriodDays: 30 }
19451
+ }
19263
19452
  },
19264
19453
  {
19265
19454
  sku: "developer",
19266
19455
  displayName: "Developer",
19267
19456
  priceAmount: 19,
19268
19457
  billingPeriod: "month",
19269
- limitsJson: '{"rateLimit":{"calls":50,"renewalPeriodSeconds":1},"quota":{"calls":50000,"renewalPeriodDays":30}}'
19458
+ limits: {
19459
+ rateLimit: { calls: 50, renewalPeriodSeconds: 1 },
19460
+ quota: { calls: 5e4, renewalPeriodDays: 30 }
19461
+ }
19270
19462
  },
19271
19463
  {
19272
19464
  sku: "team",
19273
19465
  displayName: "Team",
19274
19466
  priceAmount: 79,
19275
19467
  billingPeriod: "month",
19276
- limitsJson: '{"rateLimit":{"calls":200,"renewalPeriodSeconds":1},"quota":{"calls":500000,"renewalPeriodDays":30}}'
19468
+ limits: {
19469
+ rateLimit: { calls: 200, renewalPeriodSeconds: 1 },
19470
+ quota: { calls: 5e5, renewalPeriodDays: 30 }
19471
+ }
19277
19472
  },
19278
19473
  {
19279
19474
  sku: "enterprise",
19280
19475
  displayName: "Enterprise",
19281
19476
  priceAmount: -1,
19282
19477
  billingPeriod: "custom",
19283
- limitsJson: '{"quota":{"calls":-1}}'
19478
+ limits: { quota: { calls: -1 } }
19284
19479
  }
19285
19480
  ]
19286
19481
  }
@@ -19449,9 +19644,9 @@ function openapiInputForConfig(specRelativePosix) {
19449
19644
  return `./${specRelativePosix}`;
19450
19645
  }
19451
19646
  function toRelativeOpenApiInput(projectDir, inputPath) {
19452
- const resolved = path56.isAbsolute(inputPath) ? inputPath : path56.resolve(projectDir, inputPath);
19453
- const relative = path56.relative(projectDir, resolved);
19454
- const posix = relative.split(path56.sep).join(path56.posix.sep);
19647
+ const resolved = path57.isAbsolute(inputPath) ? inputPath : path57.resolve(projectDir, inputPath);
19648
+ const relative = path57.relative(projectDir, resolved);
19649
+ const posix = relative.split(path57.sep).join(path57.posix.sep);
19455
19650
  if (!posix) {
19456
19651
  throw new Error("OpenAPI path must point to a file.");
19457
19652
  }
@@ -19464,11 +19659,11 @@ function slugifyPlanSku(displayName) {
19464
19659
  const sku = displayName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
19465
19660
  return sku || "plan";
19466
19661
  }
19467
- function buildLimitsJson(rateLimitCalls, monthlyQuota) {
19468
- return JSON.stringify({
19662
+ function buildLimits(rateLimitCalls, monthlyQuota) {
19663
+ return {
19469
19664
  rateLimit: { calls: rateLimitCalls, renewalPeriodSeconds: 60 },
19470
19665
  quota: { calls: monthlyQuota, renewalPeriodDays: 30 }
19471
- });
19666
+ };
19472
19667
  }
19473
19668
  function buildPlanItemFromWizard(input3) {
19474
19669
  const sku = input3.sku ?? slugifyPlanSku(input3.displayName);
@@ -19476,7 +19671,7 @@ function buildPlanItemFromWizard(input3) {
19476
19671
  sku,
19477
19672
  displayName: input3.displayName,
19478
19673
  priceAmount: input3.priceAmount,
19479
- limitsJson: buildLimitsJson(input3.rateLimitCalls, input3.monthlyQuota)
19674
+ limits: buildLimits(input3.rateLimitCalls, input3.monthlyQuota)
19480
19675
  };
19481
19676
  if (input3.priceAmount > 0) {
19482
19677
  item.priceCurrency = "usd";
@@ -19824,7 +20019,7 @@ async function promptMakeConfigInteractive(options) {
19824
20019
  continue;
19825
20020
  }
19826
20021
  const routePath = `/${slug}`;
19827
- const relativePath = path57.posix.join(options.pagesDir, `${slug}.tsx`);
20022
+ const relativePath = path58.posix.join(options.pagesDir, `${slug}.tsx`);
19828
20023
  const page = {
19829
20024
  slug,
19830
20025
  title: pageTitle.trim(),
@@ -19917,7 +20112,7 @@ export default function ${componentName}() {
19917
20112
  init_package_json();
19918
20113
  import { constants } from "node:fs";
19919
20114
  import { access as access7, mkdir as mkdir11, readFile as readFile15, writeFile as writeFile14 } from "node:fs/promises";
19920
- import path58 from "node:path";
20115
+ import path59 from "node:path";
19921
20116
  import { glob as glob4 } from "glob";
19922
20117
 
19923
20118
  // src/cli/make-config/branding-assets.ts
@@ -19941,9 +20136,9 @@ var OPENAPI_GLOBS = [
19941
20136
  "openapi.yaml",
19942
20137
  "openapi.yml"
19943
20138
  ];
19944
- var toPosix = (p) => p.split(path58.sep).join("/");
20139
+ var toPosix = (p) => p.split(path59.sep).join("/");
19945
20140
  var sanitizePackageName = (dir) => {
19946
- const base = path58.basename(path58.resolve(dir));
20141
+ const base = path59.basename(path59.resolve(dir));
19947
20142
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
19948
20143
  return s || "apitogo-site";
19949
20144
  };
@@ -19953,7 +20148,7 @@ var apitogoVersionRange = () => {
19953
20148
  };
19954
20149
  async function findOpenApiSpecPath(dir) {
19955
20150
  for (const rel of OPENAPI_GLOBS) {
19956
- const full = path58.join(dir, rel);
20151
+ const full = path59.join(dir, rel);
19957
20152
  try {
19958
20153
  await access7(full, constants.R_OK);
19959
20154
  return toPosix(rel);
@@ -19968,7 +20163,7 @@ async function findOpenApiSpecPath(dir) {
19968
20163
  return extra[0] ? toPosix(extra[0]) : null;
19969
20164
  }
19970
20165
  async function ensurePackageJson(dir) {
19971
- const pkgPath = path58.join(dir, "package.json");
20166
+ const pkgPath = path59.join(dir, "package.json");
19972
20167
  const apitogoVer = apitogoVersionRange();
19973
20168
  const baseDeps = {
19974
20169
  react: ">=19.0.0",
@@ -20035,7 +20230,7 @@ async function ensurePackageJson(dir) {
20035
20230
  return false;
20036
20231
  }
20037
20232
  async function ensureTsconfigJson(dir) {
20038
- const tsPath = path58.join(dir, "tsconfig.json");
20233
+ const tsPath = path59.join(dir, "tsconfig.json");
20039
20234
  try {
20040
20235
  await access7(tsPath, constants.R_OK);
20041
20236
  return false;
@@ -20084,28 +20279,28 @@ var fileExists2 = async (filePath) => {
20084
20279
  }
20085
20280
  };
20086
20281
  async function ensurePortalStubFiles(dir) {
20087
- const landingPath = path58.join(dir, "landing", "LandingPage.tsx");
20282
+ const landingPath = path59.join(dir, "landing", "LandingPage.tsx");
20088
20283
  if (!await fileExists2(landingPath)) {
20089
- await mkdir11(path58.join(dir, "landing"), { recursive: true });
20284
+ await mkdir11(path59.join(dir, "landing"), { recursive: true });
20090
20285
  await writeFile14(landingPath, LANDING_PAGE_SOURCE, "utf8");
20091
20286
  }
20092
- const plansPath = path58.join(dir, "user-panel", "AccountPlansPage.tsx");
20287
+ const plansPath = path59.join(dir, "user-panel", "AccountPlansPage.tsx");
20093
20288
  if (!await fileExists2(plansPath)) {
20094
- await mkdir11(path58.join(dir, "user-panel"), { recursive: true });
20289
+ await mkdir11(path59.join(dir, "user-panel"), { recursive: true });
20095
20290
  await writeFile14(plansPath, ACCOUNT_PLANS_PAGE_SOURCE, "utf8");
20096
20291
  }
20097
- const dashboardPath = path58.join(dir, "user-panel", "DashboardPage.tsx");
20292
+ const dashboardPath = path59.join(dir, "user-panel", "DashboardPage.tsx");
20098
20293
  if (!await fileExists2(dashboardPath)) {
20099
- await mkdir11(path58.join(dir, "user-panel"), { recursive: true });
20294
+ await mkdir11(path59.join(dir, "user-panel"), { recursive: true });
20100
20295
  await writeFile14(dashboardPath, DASHBOARD_PAGE_SOURCE, "utf8");
20101
20296
  }
20102
20297
  await ensurePublicBrandingFiles(dir);
20103
20298
  }
20104
20299
  async function ensurePublicBrandingFiles(dir) {
20105
- const destDir = path58.join(dir, "public");
20300
+ const destDir = path59.join(dir, "public");
20106
20301
  await mkdir11(destDir, { recursive: true });
20107
20302
  for (const { name, content } of BRANDING_ASSETS) {
20108
- const dest = path58.join(destDir, name);
20303
+ const dest = path59.join(destDir, name);
20109
20304
  if (await fileExists2(dest)) {
20110
20305
  continue;
20111
20306
  }
@@ -20113,7 +20308,7 @@ async function ensurePublicBrandingFiles(dir) {
20113
20308
  }
20114
20309
  }
20115
20310
  async function ensureThinConfigTsx(dir) {
20116
- const tsxPath = path58.join(dir, "apitogo.config.tsx");
20311
+ const tsxPath = path59.join(dir, "apitogo.config.tsx");
20117
20312
  if (await fileExists2(tsxPath)) {
20118
20313
  return false;
20119
20314
  }
@@ -20122,7 +20317,7 @@ async function ensureThinConfigTsx(dir) {
20122
20317
  }
20123
20318
 
20124
20319
  // src/cli/make-config/handler.ts
20125
- var toPosixPath2 = (value) => value.split(path59.sep).join(path59.posix.sep);
20320
+ var toPosixPath2 = (value) => value.split(path60.sep).join(path60.posix.sep);
20126
20321
  var fileExists3 = async (filePath) => {
20127
20322
  try {
20128
20323
  await access8(filePath, constants2.F_OK);
@@ -20180,7 +20375,7 @@ async function persistConfig(config2, ctx) {
20180
20375
  };
20181
20376
  await writeFile15(ctx.jsonPath, `${JSON.stringify(next, null, 2)}
20182
20377
  `, "utf8");
20183
- const tsxPath = path59.join(ctx.dir, "apitogo.config.tsx");
20378
+ const tsxPath = path60.join(ctx.dir, "apitogo.config.tsx");
20184
20379
  if (await fileExists3(tsxPath) && tsxRoutes.length > 0) {
20185
20380
  const tsxSource = await readFile16(tsxPath, "utf8");
20186
20381
  if (isManagedConfigWrapper(tsxSource)) {
@@ -20207,7 +20402,7 @@ function mergeBackendFlag(config2, backend) {
20207
20402
  return next;
20208
20403
  }
20209
20404
  async function makeConfig(argv) {
20210
- const dir = path59.resolve(process.cwd(), argv.dir);
20405
+ const dir = path60.resolve(process.cwd(), argv.dir);
20211
20406
  const pagesDir = toPosixPath2(
20212
20407
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
20213
20408
  );
@@ -20227,14 +20422,14 @@ async function makeConfig(argv) {
20227
20422
  printDiagnosticsToConsole("Created tsconfig.json.");
20228
20423
  }
20229
20424
  await ensurePortalStubFiles(dir);
20230
- const jsonPath = path59.join(dir, APITOGO_JSON_FILENAME);
20425
+ const jsonPath = path60.join(dir, APITOGO_JSON_FILENAME);
20231
20426
  let createdJson = false;
20232
20427
  let config2;
20233
20428
  if (await fileExists3(jsonPath)) {
20234
20429
  config2 = await readJsonConfig(jsonPath);
20235
20430
  } else {
20236
20431
  config2 = createDefaultApitogoJsonConfig({
20237
- title: titleFromDirectoryName(path59.basename(dir)),
20432
+ title: titleFromDirectoryName(path60.basename(dir)),
20238
20433
  pagesDir
20239
20434
  });
20240
20435
  createdJson = true;
@@ -20283,8 +20478,8 @@ async function makeConfig(argv) {
20283
20478
  return;
20284
20479
  }
20285
20480
  if (action2.kind === "page") {
20286
- const pagePath = path59.join(dir, action2.page.relativePath);
20287
- await mkdir12(path59.dirname(pagePath), { recursive: true });
20481
+ const pagePath = path60.join(dir, action2.page.relativePath);
20482
+ await mkdir12(path60.dirname(pagePath), { recursive: true });
20288
20483
  await writeFile15(
20289
20484
  pagePath,
20290
20485
  buildStarterDocsPageTsx(action2.page.slug, action2.page.title),
@@ -20337,7 +20532,7 @@ async function makeConfig(argv) {
20337
20532
  if (argv.openapi) {
20338
20533
  const wire = await wireDevPortalOpenApi(
20339
20534
  dir,
20340
- path59.resolve(dir, argv.openapi)
20535
+ path60.resolve(dir, argv.openapi)
20341
20536
  );
20342
20537
  if (wire.status !== "succeeded") {
20343
20538
  throw new Error(
@@ -20366,7 +20561,7 @@ async function makeConfig(argv) {
20366
20561
  const slug = normalizePageSlug(argv.pageSlug);
20367
20562
  const pageTemplate = normalizePageTemplate(argv.pageTemplate);
20368
20563
  const relativePagePath = pageComponentRelativePath(slug);
20369
- const filePath = path59.join(dir, relativePagePath);
20564
+ const filePath = path60.join(dir, relativePagePath);
20370
20565
  const isUpdate = argv.pageUpdate === true;
20371
20566
  if (isUpdate) {
20372
20567
  if (!await fileExists3(filePath)) {
@@ -20399,7 +20594,7 @@ async function makeConfig(argv) {
20399
20594
  argv.pageContent,
20400
20595
  pageTemplate
20401
20596
  );
20402
- await mkdir12(path59.dirname(filePath), { recursive: true });
20597
+ await mkdir12(path60.dirname(filePath), { recursive: true });
20403
20598
  await writeFile15(filePath, tsx, "utf8");
20404
20599
  const configResult = await wireNewDevPortalPageInConfig(
20405
20600
  dir,
@@ -20412,7 +20607,7 @@ async function makeConfig(argv) {
20412
20607
  pagePath: relativePagePath,
20413
20608
  pageTemplate,
20414
20609
  configUpdated: configResult.updated,
20415
- configPath: configResult.configPath ? path59.relative(dir, configResult.configPath) : null
20610
+ configPath: configResult.configPath ? path60.relative(dir, configResult.configPath) : null
20416
20611
  };
20417
20612
  changes.push("page_add");
20418
20613
  }
@@ -20566,14 +20761,14 @@ var deploy_default = {
20566
20761
 
20567
20762
  // src/cli/dev/handler.ts
20568
20763
  init_joinUrl();
20569
- import path62 from "node:path";
20764
+ import path63 from "node:path";
20570
20765
 
20571
20766
  // src/vite/dev-server.ts
20572
20767
  init_logger();
20573
20768
  import fs11 from "node:fs/promises";
20574
20769
  import http from "node:http";
20575
20770
  import https from "node:https";
20576
- import path61 from "node:path";
20771
+ import path62 from "node:path";
20577
20772
  import { createHttpTerminator } from "http-terminator";
20578
20773
  import {
20579
20774
  createServer as createViteServer,
@@ -20606,7 +20801,7 @@ init_loader();
20606
20801
  // src/vite/pagefind-dev-index.ts
20607
20802
  init_invariant();
20608
20803
  init_joinUrl();
20609
- import path60 from "node:path";
20804
+ import path61 from "node:path";
20610
20805
  import { createIndex as createIndex2 } from "pagefind";
20611
20806
  import { isRunnableDevEnvironment } from "vite";
20612
20807
  async function* buildPagefindDevIndex(vite, config2) {
@@ -20659,7 +20854,7 @@ async function* buildPagefindDevIndex(vite, config2) {
20659
20854
  path: urlPath
20660
20855
  };
20661
20856
  }
20662
- const outputPath = path60.join(vite.config.publicDir, "pagefind");
20857
+ const outputPath = path61.join(vite.config.publicDir, "pagefind");
20663
20858
  await pagefindIndex.writeFiles({ outputPath });
20664
20859
  yield { type: "complete", success: true, indexed };
20665
20860
  }
@@ -20678,9 +20873,9 @@ var DevServer = class {
20678
20873
  this.protocol = "https";
20679
20874
  const { dir } = this.options;
20680
20875
  const [key, cert, ca] = await Promise.all([
20681
- fs11.readFile(path61.resolve(dir, config2.https.key)),
20682
- fs11.readFile(path61.resolve(dir, config2.https.cert)),
20683
- config2.https.ca ? fs11.readFile(path61.resolve(dir, config2.https.ca)) : void 0
20876
+ fs11.readFile(path62.resolve(dir, config2.https.key)),
20877
+ fs11.readFile(path62.resolve(dir, config2.https.cert)),
20878
+ config2.https.ca ? fs11.readFile(path62.resolve(dir, config2.https.ca)) : void 0
20684
20879
  ]);
20685
20880
  return https.createServer({ key, cert, ca });
20686
20881
  }
@@ -20697,7 +20892,7 @@ var DevServer = class {
20697
20892
  );
20698
20893
  const server = await this.createNodeServer(config2);
20699
20894
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
20700
- const publicRoot = path61.resolve(
20895
+ const publicRoot = path62.resolve(
20701
20896
  this.options.dir,
20702
20897
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
20703
20898
  );
@@ -20714,7 +20909,7 @@ var DevServer = class {
20714
20909
  // built-in transform middleware which would treat the path as a static asset.
20715
20910
  name: "apitogo:entry-client",
20716
20911
  configureServer(server2) {
20717
- const entryPath = path61.posix.join(
20912
+ const entryPath = path62.posix.join(
20718
20913
  server2.config.base,
20719
20914
  "/__z/entry.client.tsx"
20720
20915
  );
@@ -20879,7 +21074,7 @@ init_package_json();
20879
21074
  async function dev(argv) {
20880
21075
  const packageJson2 = getZudokuPackageJson();
20881
21076
  process.env.NODE_ENV = "development";
20882
- const dir = path62.resolve(process.cwd(), argv.dir);
21077
+ const dir = path63.resolve(process.cwd(), argv.dir);
20883
21078
  const server = new DevServer({
20884
21079
  dir,
20885
21080
  argPort: argv.port,
@@ -20962,11 +21157,11 @@ var dev_default = {
20962
21157
  };
20963
21158
 
20964
21159
  // src/cli/init/handler.ts
20965
- import path65 from "node:path";
21160
+ import path66 from "node:path";
20966
21161
 
20967
21162
  // src/cli/scaffold/run-scaffold-discovery.ts
20968
21163
  import { access as access10, readFile as readFile18, writeFile as writeFile17 } from "node:fs/promises";
20969
- import path64 from "node:path";
21164
+ import path65 from "node:path";
20970
21165
 
20971
21166
  // src/cli/scaffold/wire-docs.ts
20972
21167
  import {
@@ -20979,7 +21174,7 @@ import {
20979
21174
  symlink,
20980
21175
  writeFile as writeFile16
20981
21176
  } from "node:fs/promises";
20982
- import path63 from "node:path";
21177
+ import path64 from "node:path";
20983
21178
  var DOCS_DIR_WHITELIST = [
20984
21179
  "docs",
20985
21180
  "documents",
@@ -21016,14 +21211,14 @@ async function isDirectory(filePath) {
21016
21211
  }
21017
21212
  }
21018
21213
  function toPosix2(value) {
21019
- return value.split(path63.sep).join(path63.posix.sep);
21214
+ return value.split(path64.sep).join(path64.posix.sep);
21020
21215
  }
21021
21216
  function isWhitelistedDirName(name) {
21022
21217
  return DOCS_DIR_WHITELIST.includes(name.toLowerCase());
21023
21218
  }
21024
- function isInside(parent, child) {
21025
- const relative = path63.relative(parent, child);
21026
- return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
21219
+ function isInside2(parent, child) {
21220
+ const relative = path64.relative(parent, child);
21221
+ return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
21027
21222
  }
21028
21223
  async function collectMarkdownFiles(dir) {
21029
21224
  const files = [];
@@ -21037,7 +21232,7 @@ async function collectMarkdownFiles(dir) {
21037
21232
  if (entry.name.startsWith(".")) {
21038
21233
  continue;
21039
21234
  }
21040
- const full = path63.join(dir, entry.name);
21235
+ const full = path64.join(dir, entry.name);
21041
21236
  if (entry.isDirectory()) {
21042
21237
  if (SKIP_SEARCH_DIRS.has(entry.name) || entry.isSymbolicLink()) {
21043
21238
  continue;
@@ -21052,11 +21247,11 @@ async function collectMarkdownFiles(dir) {
21052
21247
  return files;
21053
21248
  }
21054
21249
  async function collectSearchRoots(siteDirectory) {
21055
- const site = path63.resolve(siteDirectory);
21056
- const parent = path63.dirname(site);
21250
+ const site = path64.resolve(siteDirectory);
21251
+ const parent = path64.dirname(site);
21057
21252
  const roots = [];
21058
21253
  const add = (dir) => {
21059
- const resolved = path63.resolve(dir);
21254
+ const resolved = path64.resolve(dir);
21060
21255
  if (!roots.includes(resolved)) {
21061
21256
  roots.push(resolved);
21062
21257
  }
@@ -21069,7 +21264,7 @@ async function collectSearchRoots(siteDirectory) {
21069
21264
  if (!entry.isDirectory() || SKIP_SEARCH_DIRS.has(entry.name)) {
21070
21265
  continue;
21071
21266
  }
21072
- add(path63.join(parent, entry.name));
21267
+ add(path64.join(parent, entry.name));
21073
21268
  }
21074
21269
  } catch {
21075
21270
  }
@@ -21078,14 +21273,14 @@ async function collectSearchRoots(siteDirectory) {
21078
21273
  return roots;
21079
21274
  }
21080
21275
  async function discoverNearbyDocsDirectories(siteDirectory) {
21081
- const site = path63.resolve(siteDirectory);
21082
- const sitePages = path63.join(site, PAGES_DIR);
21276
+ const site = path64.resolve(siteDirectory);
21277
+ const sitePages = path64.join(site, PAGES_DIR);
21083
21278
  const searchedDirectories = await collectSearchRoots(site);
21084
21279
  const directories = [];
21085
21280
  const seen = /* @__PURE__ */ new Set();
21086
21281
  const consider = async (dir) => {
21087
- const resolved = path63.resolve(dir);
21088
- if (resolved === site || seen.has(resolved) || isInside(sitePages, resolved)) {
21282
+ const resolved = path64.resolve(dir);
21283
+ if (resolved === site || seen.has(resolved) || isInside2(sitePages, resolved)) {
21089
21284
  return;
21090
21285
  }
21091
21286
  if (!await isDirectory(resolved)) {
@@ -21101,7 +21296,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21101
21296
  directories.push({ sourceDirectory: resolved, files });
21102
21297
  };
21103
21298
  for (const root of searchedDirectories) {
21104
- if (isWhitelistedDirName(path63.basename(root))) {
21299
+ if (isWhitelistedDirName(path64.basename(root))) {
21105
21300
  await consider(root);
21106
21301
  }
21107
21302
  try {
@@ -21113,7 +21308,7 @@ async function discoverNearbyDocsDirectories(siteDirectory) {
21113
21308
  if (!isWhitelistedDirName(entry.name)) {
21114
21309
  continue;
21115
21310
  }
21116
- await consider(path63.join(root, entry.name));
21311
+ await consider(path64.join(root, entry.name));
21117
21312
  }
21118
21313
  } catch {
21119
21314
  }
@@ -21124,8 +21319,8 @@ function slugifyDirName(name) {
21124
21319
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "docs";
21125
21320
  }
21126
21321
  async function allocateLinkName(pagesDir, sourceDirectory, used) {
21127
- const base = slugifyDirName(path63.basename(sourceDirectory));
21128
- const parent = slugifyDirName(path63.basename(path63.dirname(sourceDirectory)));
21322
+ const base = slugifyDirName(path64.basename(sourceDirectory));
21323
+ const parent = slugifyDirName(path64.basename(path64.dirname(sourceDirectory)));
21129
21324
  const candidates = [base, `${parent}-${base}`];
21130
21325
  let index = 2;
21131
21326
  while (true) {
@@ -21133,7 +21328,7 @@ async function allocateLinkName(pagesDir, sourceDirectory, used) {
21133
21328
  if (used.has(name)) {
21134
21329
  continue;
21135
21330
  }
21136
- const target = path63.join(pagesDir, name);
21331
+ const target = path64.join(pagesDir, name);
21137
21332
  if (await pathExists5(target)) {
21138
21333
  const stat4 = await lstat(target);
21139
21334
  if (!stat4.isDirectory() || !await isManagedLinkDir(target)) {
@@ -21164,8 +21359,8 @@ async function alreadyLinked(linkPath, sourcePath) {
21164
21359
  return false;
21165
21360
  }
21166
21361
  const current = await readlink(linkPath);
21167
- const resolved = path63.resolve(path63.dirname(linkPath), current);
21168
- return resolved === path63.resolve(sourcePath);
21362
+ const resolved = path64.resolve(path64.dirname(linkPath), current);
21363
+ return resolved === path64.resolve(sourcePath);
21169
21364
  } catch {
21170
21365
  return false;
21171
21366
  }
@@ -21177,8 +21372,8 @@ async function linkMarkdownFile(sourcePath, linkPath) {
21177
21372
  if (await pathExists5(linkPath)) {
21178
21373
  return "skipped";
21179
21374
  }
21180
- await mkdir13(path63.dirname(linkPath), { recursive: true });
21181
- const relativeTarget = path63.relative(path63.dirname(linkPath), sourcePath);
21375
+ await mkdir13(path64.dirname(linkPath), { recursive: true });
21376
+ const relativeTarget = path64.relative(path64.dirname(linkPath), sourcePath);
21182
21377
  await symlink(
21183
21378
  relativeTarget,
21184
21379
  linkPath,
@@ -21193,7 +21388,7 @@ async function applyDocsNavigation(siteDirectory, routes) {
21193
21388
  if (routes.length === 0) {
21194
21389
  return;
21195
21390
  }
21196
- const configPath = path63.join(siteDirectory, CONFIG_FILENAME);
21391
+ const configPath = path64.join(siteDirectory, CONFIG_FILENAME);
21197
21392
  if (!await pathExists5(configPath)) {
21198
21393
  return;
21199
21394
  }
@@ -21209,8 +21404,8 @@ async function applyDocsNavigation(siteDirectory, routes) {
21209
21404
  `, "utf8");
21210
21405
  }
21211
21406
  async function discoverAndWireDocs(siteDirectory) {
21212
- const site = path63.resolve(siteDirectory);
21213
- const pagesDir = path63.join(site, PAGES_DIR);
21407
+ const site = path64.resolve(siteDirectory);
21408
+ const pagesDir = path64.join(site, PAGES_DIR);
21214
21409
  const { directories, searchedDirectories } = await discoverNearbyDocsDirectories(site);
21215
21410
  if (directories.length === 0) {
21216
21411
  return {
@@ -21232,14 +21427,14 @@ async function discoverAndWireDocs(siteDirectory) {
21232
21427
  directory.sourceDirectory,
21233
21428
  usedNames
21234
21429
  );
21235
- const linkDirectory = path63.join(pagesDir, linkName);
21430
+ const linkDirectory = path64.join(pagesDir, linkName);
21236
21431
  const linked = [];
21237
21432
  const skipped = [];
21238
21433
  for (const sourcePath of directory.files) {
21239
21434
  const relativeSource = toPosix2(
21240
- path63.relative(directory.sourceDirectory, sourcePath)
21435
+ path64.relative(directory.sourceDirectory, sourcePath)
21241
21436
  );
21242
- const linkPath = path63.join(linkDirectory, relativeSource);
21437
+ const linkPath = path64.join(linkDirectory, relativeSource);
21243
21438
  const result = await linkMarkdownFile(sourcePath, linkPath);
21244
21439
  if (result === "skipped") {
21245
21440
  skipped.push({
@@ -21248,7 +21443,7 @@ async function discoverAndWireDocs(siteDirectory) {
21248
21443
  });
21249
21444
  continue;
21250
21445
  }
21251
- const relativeLink = toPosix2(path63.relative(site, linkPath));
21446
+ const relativeLink = toPosix2(path64.relative(site, linkPath));
21252
21447
  const route = toRoutePath(relativeLink, PAGES_DIR);
21253
21448
  linked.push({ sourcePath, linkPath, route, relativeSource });
21254
21449
  routes.push(route);
@@ -21281,11 +21476,11 @@ async function discoverAndWireDocs(siteDirectory) {
21281
21476
  };
21282
21477
  }
21283
21478
  function siteRelative(siteDirectory, filePath) {
21284
- const relative = toPosix2(path63.relative(siteDirectory, filePath));
21479
+ const relative = toPosix2(path64.relative(siteDirectory, filePath));
21285
21480
  if (!relative) {
21286
21481
  return ".";
21287
21482
  }
21288
- if (path63.isAbsolute(relative)) {
21483
+ if (path64.isAbsolute(relative)) {
21289
21484
  return toPosix2(filePath);
21290
21485
  }
21291
21486
  if (relative.startsWith("..")) {
@@ -21352,7 +21547,7 @@ async function pathExists6(filePath) {
21352
21547
  }
21353
21548
  async function wireOpenApiIntoJsonConfig(siteDirectory, openApiPath) {
21354
21549
  const input3 = toSiteRelativeOpenApiInput(siteDirectory, openApiPath);
21355
- const jsonConfigPath = path64.join(siteDirectory, "apitogo.config.json");
21550
+ const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
21356
21551
  const raw = await readFile18(jsonConfigPath, "utf8");
21357
21552
  const siteConfig = JSON.parse(raw);
21358
21553
  const updated = applyOpenApiToSiteConfig(siteConfig, {
@@ -21404,7 +21599,7 @@ async function discoverAndWireOpenApiLite(siteDirectory, mode) {
21404
21599
  wired: false
21405
21600
  };
21406
21601
  }
21407
- const jsonConfigPath = path64.join(siteDirectory, "apitogo.config.json");
21602
+ const jsonConfigPath = path65.join(siteDirectory, "apitogo.config.json");
21408
21603
  if (!await pathExists6(jsonConfigPath)) {
21409
21604
  return {
21410
21605
  openApiDiscovery: {
@@ -21465,8 +21660,8 @@ function slugifyName2(name) {
21465
21660
  return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "dev-portal-site";
21466
21661
  }
21467
21662
  function resolveInitOutputDirectory(dirArg, name) {
21468
- const resolved = path65.resolve(process.cwd(), dirArg);
21469
- const base = path65.basename(resolved);
21663
+ const resolved = path66.resolve(process.cwd(), dirArg);
21664
+ const base = path66.basename(resolved);
21470
21665
  const isDot = dirArg === "." || dirArg === "./" || base === "." || resolved === process.cwd();
21471
21666
  if (isDot) {
21472
21667
  const fromName = name?.trim();
@@ -21476,7 +21671,7 @@ function resolveInitOutputDirectory(dirArg, name) {
21476
21671
  );
21477
21672
  }
21478
21673
  return {
21479
- outputDirectory: path65.resolve(process.cwd(), slugifyName2(fromName)),
21674
+ outputDirectory: path66.resolve(process.cwd(), slugifyName2(fromName)),
21480
21675
  siteName: fromName
21481
21676
  };
21482
21677
  }
@@ -21720,9 +21915,9 @@ var remove_default = {
21720
21915
  };
21721
21916
 
21722
21917
  // src/cli/status/handler.ts
21723
- import path66 from "node:path";
21918
+ import path67 from "node:path";
21724
21919
  async function status(argv) {
21725
- const sourceDirectory = path66.resolve(process.cwd(), argv.dir);
21920
+ const sourceDirectory = path67.resolve(process.cwd(), argv.dir);
21726
21921
  const config2 = loadConfig();
21727
21922
  const client = new PlatformApiClient(config2);
21728
21923
  let whoamiJson;
@@ -21802,7 +21997,7 @@ var status_default = {
21802
21997
  };
21803
21998
 
21804
21999
  // src/cli/teardown/handler.ts
21805
- import path67 from "node:path";
22000
+ import path68 from "node:path";
21806
22001
  function resultLooksFailed3(payload) {
21807
22002
  try {
21808
22003
  const parsed = JSON.parse(payload);
@@ -21818,7 +22013,7 @@ async function teardown(argv) {
21818
22013
  );
21819
22014
  return;
21820
22015
  }
21821
- const sourceDirectory = path67.resolve(process.cwd(), argv.dir);
22016
+ const sourceDirectory = path68.resolve(process.cwd(), argv.dir);
21822
22017
  const config2 = loadConfig();
21823
22018
  const client = new PlatformApiClient(config2);
21824
22019
  let projectId = argv.projectId?.trim();
@@ -21951,12 +22146,12 @@ function box(message, {
21951
22146
 
21952
22147
  // src/cli/common/xdg/lib.ts
21953
22148
  import { homedir } from "node:os";
21954
- import path68 from "node:path";
22149
+ import path69 from "node:path";
21955
22150
  function defineDirectoryWithFallback(xdgName, fallback) {
21956
22151
  if (process.env[xdgName]) {
21957
22152
  return process.env[xdgName];
21958
22153
  } else {
21959
- return path68.join(homedir(), fallback);
22154
+ return path69.join(homedir(), fallback);
21960
22155
  }
21961
22156
  }
21962
22157
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -21971,15 +22166,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
21971
22166
  "XDG_DATA_HOME",
21972
22167
  ".local/state"
21973
22168
  );
21974
- var ZUDOKU_XDG_CONFIG_HOME = path68.join(
22169
+ var ZUDOKU_XDG_CONFIG_HOME = path69.join(
21975
22170
  XDG_CONFIG_HOME,
21976
22171
  CLI_XDG_FOLDER_NAME
21977
22172
  );
21978
- var ZUDOKU_XDG_DATA_HOME = path68.join(
22173
+ var ZUDOKU_XDG_DATA_HOME = path69.join(
21979
22174
  XDG_DATA_HOME,
21980
22175
  CLI_XDG_FOLDER_NAME
21981
22176
  );
21982
- var ZUDOKU_XDG_STATE_HOME = path68.join(
22177
+ var ZUDOKU_XDG_STATE_HOME = path69.join(
21983
22178
  XDG_STATE_HOME,
21984
22179
  CLI_XDG_FOLDER_NAME
21985
22180
  );