@lukoweb/apitogo 0.1.50 → 0.1.53

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.
Files changed (36) hide show
  1. package/dist/cli/cli.js +1339 -922
  2. package/dist/declarations/config/apitogo-config-core.d.ts +25 -0
  3. package/dist/declarations/config/apitogo-config-loader.d.ts +2 -0
  4. package/dist/declarations/config/apitogo-config-loader.node.d.ts +4 -0
  5. package/dist/declarations/config/build-apitogo-config.d.ts +8 -0
  6. package/dist/declarations/config/loader.d.ts +4 -0
  7. package/dist/declarations/config/local-manifest.d.ts +16 -9
  8. package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +24 -24
  9. package/dist/declarations/config/validators/ModulesSchema.d.ts +38 -0
  10. package/dist/declarations/config/validators/ZudokuConfig.d.ts +18 -9
  11. package/dist/declarations/index.d.ts +2 -1
  12. package/dist/declarations/lib/authentication/auth-header-nav.d.ts +10 -0
  13. package/dist/declarations/lib/core/plugins.d.ts +1 -0
  14. package/dist/declarations/lib/ui/Button.d.ts +1 -1
  15. package/dist/declarations/lib/ui/Item.d.ts +1 -1
  16. package/dist/flat-config.d.ts +36 -23
  17. package/docs/configuration/authentication.md +11 -8
  18. package/docs/configuration/manifest.md +83 -93
  19. package/package.json +17 -1
  20. package/src/config/apitogo-config-core.ts +485 -0
  21. package/src/config/apitogo-config-loader.node.ts +68 -0
  22. package/src/config/apitogo-config-loader.ts +6 -0
  23. package/src/config/build-apitogo-config.ts +52 -0
  24. package/src/config/loader.ts +61 -1
  25. package/src/config/local-manifest.ts +72 -52
  26. package/src/config/resolve-modules.ts +16 -13
  27. package/src/config/validators/ModulesSchema.ts +17 -0
  28. package/src/index.ts +9 -1
  29. package/src/lib/authentication/auth-header-nav.ts +56 -0
  30. package/src/lib/authentication/providers/dev-portal-utils.ts +7 -2
  31. package/src/lib/components/Header.tsx +48 -60
  32. package/src/lib/components/MobileTopNavigation.tsx +29 -40
  33. package/src/lib/core/plugins.ts +1 -0
  34. package/src/vite/dev-portal-env.ts +12 -4
  35. package/src/vite/plugin-config.ts +20 -3
  36. package/src/vite/plugin-local-manifest.ts +15 -0
package/dist/cli/cli.js CHANGED
@@ -52,6 +52,54 @@ var init_logger = __esm({
52
52
  }
53
53
  });
54
54
 
55
+ // src/lib/authentication/auth-header-nav.ts
56
+ function withoutLoginNavigation(navigation) {
57
+ return navigation.filter(
58
+ (item) => !("to" in item && item.to === LOGIN_NAV_PATH)
59
+ );
60
+ }
61
+ function applyAuthenticationHeaderNav(config2) {
62
+ if (!config2.authentication) {
63
+ return config2;
64
+ }
65
+ const authNavEnabled = config2.__meta?.authenticationEnabled === true;
66
+ const navigation = config2.header?.navigation ?? [];
67
+ if (!authNavEnabled) {
68
+ const filtered = withoutLoginNavigation(navigation);
69
+ if (filtered.length === navigation.length) {
70
+ return config2;
71
+ }
72
+ return {
73
+ ...config2,
74
+ header: {
75
+ ...config2.header,
76
+ navigation: filtered
77
+ }
78
+ };
79
+ }
80
+ if (navigation.some((item) => "to" in item && item.to === LOGIN_NAV_PATH)) {
81
+ return config2;
82
+ }
83
+ return {
84
+ ...config2,
85
+ header: {
86
+ ...config2.header,
87
+ navigation: [...navigation, LOGIN_HEADER_NAV_ITEM]
88
+ }
89
+ };
90
+ }
91
+ var LOGIN_NAV_PATH, LOGIN_HEADER_NAV_ITEM;
92
+ var init_auth_header_nav = __esm({
93
+ "src/lib/authentication/auth-header-nav.ts"() {
94
+ LOGIN_NAV_PATH = "/signin";
95
+ LOGIN_HEADER_NAV_ITEM = {
96
+ label: "Login",
97
+ to: LOGIN_NAV_PATH,
98
+ display: "anon"
99
+ };
100
+ }
101
+ });
102
+
55
103
  // src/lib/core/plugins.ts
56
104
  var isTransformConfigPlugin;
57
105
  var init_plugins = __esm({
@@ -126,95 +174,577 @@ var init_invariant = __esm({
126
174
  }
127
175
  });
128
176
 
177
+ // src/config/apitogo-config-core.ts
178
+ function parseEnvValue(raw) {
179
+ if (raw === void 0) {
180
+ return raw;
181
+ }
182
+ const trimmed = raw.trim();
183
+ if (trimmed === "true") {
184
+ return true;
185
+ }
186
+ if (trimmed === "false") {
187
+ return false;
188
+ }
189
+ if (trimmed === "null") {
190
+ return null;
191
+ }
192
+ if (/^-?\d+(\.\d+)?$/.test(trimmed)) {
193
+ return Number(trimmed);
194
+ }
195
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
196
+ try {
197
+ return JSON.parse(trimmed);
198
+ } catch {
199
+ return trimmed;
200
+ }
201
+ }
202
+ return trimmed;
203
+ }
204
+ function setNestedValue(target, pathParts, value) {
205
+ if (pathParts.length === 0) {
206
+ return;
207
+ }
208
+ let current = target;
209
+ for (let index = 0; index < pathParts.length - 1; index += 1) {
210
+ const key = pathParts[index];
211
+ if (!key) {
212
+ return;
213
+ }
214
+ const next = current[key];
215
+ if (next === void 0 || next === null || typeof next !== "object" || Array.isArray(next)) {
216
+ current[key] = {};
217
+ }
218
+ current = current[key];
219
+ }
220
+ const leafKey = pathParts[pathParts.length - 1];
221
+ if (!leafKey) {
222
+ return;
223
+ }
224
+ current[leafKey] = value;
225
+ }
226
+ function stripRuntimeConfigFields(config2) {
227
+ const { plugins: _plugins, ...jsonOnly } = config2;
228
+ return jsonOnly;
229
+ }
230
+ function applyEnvOverrides(config2, env = process.env) {
231
+ const result = structuredClone(stripRuntimeConfigFields(config2));
232
+ for (const [key, value] of Object.entries(env)) {
233
+ if (!key.startsWith(ENV_PREFIX) || value === void 0) {
234
+ continue;
235
+ }
236
+ const pathParts = key.slice(ENV_PREFIX.length).split("__").filter(Boolean);
237
+ if (pathParts.length === 0) {
238
+ continue;
239
+ }
240
+ setNestedValue(result, pathParts, parseEnvValue(value));
241
+ }
242
+ return result;
243
+ }
244
+ function asRecord(value) {
245
+ return value !== void 0 && value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
246
+ }
247
+ function readSiteTitle(config2) {
248
+ const site = asRecord(config2.site);
249
+ const branding = asRecord(config2.branding);
250
+ const siteTitle = site?.title;
251
+ const brandingTitle = branding?.title;
252
+ const legacySiteName = config2.siteName;
253
+ if (typeof siteTitle === "string" && siteTitle.trim()) {
254
+ return siteTitle.trim();
255
+ }
256
+ if (typeof brandingTitle === "string" && brandingTitle.trim()) {
257
+ return brandingTitle.trim();
258
+ }
259
+ if (typeof legacySiteName === "string" && legacySiteName.trim()) {
260
+ return legacySiteName.trim();
261
+ }
262
+ return void 0;
263
+ }
264
+ function readLogoUrl(config2) {
265
+ const site = asRecord(config2.site);
266
+ const logo = asRecord(site?.logo);
267
+ const src = asRecord(logo?.src);
268
+ const branding = asRecord(config2.branding);
269
+ const fromSite = typeof src?.light === "string" && src.light || typeof src?.dark === "string" && src.dark || typeof logo?.logoUrl === "string" && logo.logoUrl || typeof site?.logoUrl === "string" && site.logoUrl;
270
+ if (fromSite) {
271
+ return fromSite;
272
+ }
273
+ return typeof branding?.logoUrl === "string" ? branding.logoUrl : void 0;
274
+ }
275
+ function firstApiInput(config2) {
276
+ const apis = config2.apis;
277
+ const list = Array.isArray(apis) ? apis : apis ? [apis] : [];
278
+ for (const entry of list) {
279
+ const api = asRecord(entry);
280
+ if (typeof api?.input === "string" && api.input.trim()) {
281
+ return api.input.trim();
282
+ }
283
+ }
284
+ return void 0;
285
+ }
286
+ function mergeAuthenticationGateway(config2) {
287
+ const authentication = asRecord(config2.authentication);
288
+ if (!authentication) {
289
+ return void 0;
290
+ }
291
+ const authGateway = asRecord(authentication.gateway);
292
+ const rootGateway = asRecord(config2.gateway);
293
+ if (!authGateway && !rootGateway) {
294
+ return authentication;
295
+ }
296
+ return {
297
+ ...authentication,
298
+ gateway: {
299
+ ...rootGateway,
300
+ ...authGateway
301
+ }
302
+ };
303
+ }
304
+ function ensureModules(config2) {
305
+ const modules = asRecord(config2.modules) ?? {};
306
+ config2.modules = modules;
307
+ return modules;
308
+ }
309
+ function mergePlansBySku(existing, patch) {
310
+ const bySku = /* @__PURE__ */ new Map();
311
+ for (const plan of existing) {
312
+ if (typeof plan.sku === "string") {
313
+ bySku.set(plan.sku, plan);
314
+ }
315
+ }
316
+ for (const plan of patch) {
317
+ if (typeof plan.sku !== "string") {
318
+ continue;
319
+ }
320
+ const prior = bySku.get(plan.sku);
321
+ bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
322
+ }
323
+ return Array.from(bySku.values());
324
+ }
325
+ function readPlanCatalogItems(config2) {
326
+ const normalized = normalizeApitogoConfig(config2);
327
+ const items = asRecord(
328
+ asRecord(asRecord(normalized.modules)?.userPanel)?.plans
329
+ )?.items;
330
+ return Array.isArray(items) ? items : [];
331
+ }
332
+ function migratePlanCatalog(normalized) {
333
+ const modules = ensureModules(normalized);
334
+ const userPanel = asRecord(modules.userPanel) ?? {};
335
+ const plansModule = asRecord(userPanel.plans) ?? {};
336
+ const rootList = Array.isArray(normalized.plans) ? normalized.plans : [];
337
+ const existingItems = Array.isArray(plansModule.items) ? plansModule.items : [];
338
+ if (rootList.length) {
339
+ plansModule.items = mergePlansBySku(existingItems, rootList);
340
+ if (plansModule.enabled === void 0) {
341
+ plansModule.enabled = true;
342
+ }
343
+ userPanel.plans = plansModule;
344
+ modules.userPanel = userPanel;
345
+ }
346
+ delete normalized.plans;
347
+ }
348
+ function normalizeApitogoConfig(config2) {
349
+ const normalized = structuredClone(stripRuntimeConfigFields(config2));
350
+ const title = readSiteTitle(normalized);
351
+ const logoUrl = readLogoUrl(normalized);
352
+ const site = asRecord(normalized.site) ?? {};
353
+ if (title) {
354
+ site.title = title;
355
+ }
356
+ if (logoUrl && !asRecord(site.logo)?.src) {
357
+ site.logo = {
358
+ ...asRecord(site.logo) ?? {},
359
+ src: { light: logoUrl, dark: logoUrl }
360
+ };
361
+ }
362
+ normalized.site = site;
363
+ const authentication = mergeAuthenticationGateway(normalized);
364
+ if (authentication) {
365
+ normalized.authentication = authentication;
366
+ }
367
+ delete normalized.gateway;
368
+ const modules = ensureModules(normalized);
369
+ const legacyDocs = asRecord(normalized.docs);
370
+ const moduleDocs = asRecord(modules.docs) ?? {};
371
+ if (legacyDocs) {
372
+ modules.docs = { ...legacyDocs, ...moduleDocs };
373
+ }
374
+ delete normalized.docs;
375
+ const legacyApiKeys = asRecord(normalized.apiKeys);
376
+ const userPanel = asRecord(modules.userPanel) ?? {};
377
+ const apiKeys = asRecord(userPanel.apiKeys) ?? {};
378
+ if (legacyApiKeys?.enabled === true && apiKeys.enabled === void 0) {
379
+ userPanel.apiKeys = { ...apiKeys, enabled: true };
380
+ modules.userPanel = userPanel;
381
+ }
382
+ delete normalized.apiKeys;
383
+ const apiInput = firstApiInput(normalized);
384
+ if (apiInput) {
385
+ const backend = asRecord(normalized.backend) ?? {};
386
+ if (!backend.openApiPath) {
387
+ backend.openApiPath = apiInput;
388
+ }
389
+ normalized.backend = backend;
390
+ }
391
+ delete normalized.siteName;
392
+ delete normalized.branding;
393
+ delete normalized.projectName;
394
+ migratePlanCatalog(normalized);
395
+ syncBillingEnabled(normalized);
396
+ return normalized;
397
+ }
398
+ function isBillingEnabled(config2) {
399
+ const normalized = normalizeApitogoConfig(config2);
400
+ const plans = asRecord(
401
+ asRecord(asRecord(normalized.modules)?.userPanel)?.plans
402
+ );
403
+ return plans?.enabled === true;
404
+ }
405
+ function syncBillingEnabled(normalized) {
406
+ const legacyPricing = asRecord(normalized.pricing);
407
+ const modules = ensureModules(normalized);
408
+ const userPanel = asRecord(modules.userPanel) ?? {};
409
+ const plans = asRecord(userPanel.plans) ?? {};
410
+ const enabled = plans.enabled === true || legacyPricing?.enabled === true;
411
+ if (enabled) {
412
+ userPanel.plans = { ...plans, enabled: true };
413
+ modules.userPanel = userPanel;
414
+ }
415
+ delete normalized.pricing;
416
+ }
417
+ function deriveManifestFields(config2) {
418
+ const normalized = normalizeApitogoConfig(config2);
419
+ const manifest = {};
420
+ const title = readSiteTitle(normalized);
421
+ if (title) {
422
+ manifest.siteName = title;
423
+ const logoUrl = readLogoUrl(normalized);
424
+ manifest.branding = logoUrl ? { title, logoUrl } : { title };
425
+ }
426
+ for (const key of DERIVED_MANIFEST_KEYS) {
427
+ if (key === "siteName" || key === "branding") {
428
+ continue;
429
+ }
430
+ if (key === "authentication") {
431
+ const authentication2 = asRecord(normalized.authentication);
432
+ if (authentication2) {
433
+ const {
434
+ gateway: _gateway,
435
+ oidc: _oidc,
436
+ stripe: _stripe,
437
+ ...authPublic
438
+ } = authentication2;
439
+ manifest.authentication = authPublic;
440
+ }
441
+ continue;
442
+ }
443
+ if (key === "gateway") {
444
+ continue;
445
+ }
446
+ if (key === "pricing") {
447
+ if (isBillingEnabled(config2)) {
448
+ manifest.pricing = { enabled: true };
449
+ }
450
+ continue;
451
+ }
452
+ if (key === "plans") {
453
+ const items = readPlanCatalogItems(normalized);
454
+ if (items.length) {
455
+ manifest.plans = items;
456
+ }
457
+ continue;
458
+ }
459
+ if (normalized[key] !== void 0) {
460
+ manifest[key] = normalized[key];
461
+ }
462
+ }
463
+ const authentication = asRecord(normalized.authentication);
464
+ if (authentication?.gateway) {
465
+ manifest.gateway = authentication.gateway;
466
+ }
467
+ return manifest;
468
+ }
469
+ function extractManifest(config2) {
470
+ if (!config2 || typeof config2 !== "object") {
471
+ return null;
472
+ }
473
+ const manifest = deriveManifestFields(config2);
474
+ return Object.keys(manifest).length > 0 ? manifest : null;
475
+ }
476
+ var APITOGO_CONFIG_FILENAME, ENV_PREFIX, DERIVED_MANIFEST_KEYS;
477
+ var init_apitogo_config_core = __esm({
478
+ "src/config/apitogo-config-core.ts"() {
479
+ APITOGO_CONFIG_FILENAME = "apitogo.config.json";
480
+ ENV_PREFIX = "APITOGO_CONFIG_";
481
+ DERIVED_MANIFEST_KEYS = [
482
+ "siteName",
483
+ "branding",
484
+ "pricing",
485
+ "authentication",
486
+ "plans",
487
+ "backend",
488
+ "gateway",
489
+ "projectId"
490
+ ];
491
+ }
492
+ });
493
+
494
+ // src/config/apitogo-config-loader.node.ts
495
+ import { existsSync, readFileSync as readFileSync2 } from "node:fs";
496
+ import path2 from "node:path";
497
+ function loadApitogoConfig(rootDir = process.cwd()) {
498
+ const configPath = path2.join(path2.resolve(rootDir), APITOGO_CONFIG_FILENAME);
499
+ if (!existsSync(configPath)) {
500
+ throw new Error(
501
+ `Missing ${APITOGO_CONFIG_FILENAME} in ${path2.resolve(rootDir)}`
502
+ );
503
+ }
504
+ const raw = readFileSync2(configPath, "utf8");
505
+ const parsed = JSON.parse(raw);
506
+ return normalizeApitogoConfig(applyEnvOverrides(parsed, process.env));
507
+ }
508
+ var init_apitogo_config_loader_node = __esm({
509
+ "src/config/apitogo-config-loader.node.ts"() {
510
+ init_apitogo_config_core();
511
+ }
512
+ });
513
+
514
+ // src/config/apitogo-config-loader.ts
515
+ var init_apitogo_config_loader = __esm({
516
+ "src/config/apitogo-config-loader.ts"() {
517
+ init_apitogo_config_core();
518
+ init_apitogo_config_loader_node();
519
+ }
520
+ });
521
+
129
522
  // src/config/file-exists.ts
130
523
  import { stat } from "node:fs/promises";
131
524
  var fileExists;
132
525
  var init_file_exists = __esm({
133
526
  "src/config/file-exists.ts"() {
134
- fileExists = (path38) => stat(path38).then(() => true).catch(() => false);
527
+ fileExists = (path39) => stat(path39).then(() => true).catch(() => false);
135
528
  }
136
529
  });
137
530
 
138
- // src/config/validators/ModulesSchema.ts
531
+ // src/config/local-manifest.ts
532
+ import path3 from "node:path";
139
533
  import { z as z3 } from "zod";
140
- var ModuleToggleSchema, DocsModuleSchema, LandingLinkSchema, LandingFeatureSchema, LandingHeroSchema, LandingContentSchema, DashboardContentSchema, ProfileContentSchema, PlanTierSchema, PlansContentSchema, SubmodulePageFields, LandingModuleSchema, UserManagementModuleSchema, ApiKeysModuleSchema, PlansModuleSchema, DashboardModuleSchema, UserPanelModuleSchema, ModulesSchema;
534
+ function isPricingEnabled(manifest) {
535
+ return manifest?.pricing?.enabled === true;
536
+ }
537
+ function isAuthenticationEnabled(manifest) {
538
+ return manifest?.authentication?.enabled === true;
539
+ }
540
+ function manifestToPreviewCatalog(manifest) {
541
+ const plans = manifest?.plans;
542
+ const catalog = plansToPreviewCatalog(plans);
543
+ return {
544
+ pricingEnabled: isPricingEnabled(manifest),
545
+ authenticationEnabled: isAuthenticationEnabled(manifest),
546
+ plans: catalog.plans
547
+ };
548
+ }
549
+ function normalizeBillingPeriod(period) {
550
+ if (!period) {
551
+ return "monthly";
552
+ }
553
+ const normalized = period.toLowerCase();
554
+ if (normalized === "month") {
555
+ return "monthly";
556
+ }
557
+ if (normalized === "year") {
558
+ return "annual";
559
+ }
560
+ return normalized;
561
+ }
562
+ function plansToPreviewCatalog(plans) {
563
+ if (!plans?.length) {
564
+ return { plans: [] };
565
+ }
566
+ return {
567
+ plans: plans.map((plan) => ({
568
+ sku: plan.sku,
569
+ displayName: plan.displayName,
570
+ priceAmount: plan.priceAmount ?? 0,
571
+ priceCurrency: plan.priceCurrency ?? "usd",
572
+ billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
573
+ limitsJson: plan.limitsJson ?? null,
574
+ includedActionKeys: plan.includedActionKeys ?? []
575
+ }))
576
+ };
577
+ }
578
+ function resolveManifestEnv(viteMode) {
579
+ return viteMode === "production" ? "production" : "development";
580
+ }
581
+ function manifestPathsForEnv(rootDir, _env) {
582
+ const resolvedRoot = path3.resolve(rootDir);
583
+ const configPath = path3.join(resolvedRoot, APITOGO_CONFIG_FILENAME);
584
+ return {
585
+ basePath: configPath,
586
+ overridePath: configPath,
587
+ watchPaths: [configPath]
588
+ };
589
+ }
590
+ function parseManifestRecord(manifest) {
591
+ if (!manifest) {
592
+ return null;
593
+ }
594
+ const result = DevPortalLocalManifestSchema.safeParse(manifest);
595
+ return result.success ? result.data : null;
596
+ }
597
+ async function readEffectiveManifest(rootDir, _env) {
598
+ try {
599
+ const config2 = loadApitogoConfig(rootDir);
600
+ const manifest = parseManifestRecord(extractManifest(config2));
601
+ if (!manifest) {
602
+ return null;
603
+ }
604
+ if (!manifest.plans?.length) {
605
+ const items = readPlanCatalogItems(config2);
606
+ if (items.length) {
607
+ manifest.plans = items;
608
+ }
609
+ }
610
+ return {
611
+ ...manifest,
612
+ pricing: { ...manifest.pricing, enabled: isBillingEnabled(config2) }
613
+ };
614
+ } catch {
615
+ return null;
616
+ }
617
+ }
618
+ var BillingPeriodSchema, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
619
+ var init_local_manifest = __esm({
620
+ "src/config/local-manifest.ts"() {
621
+ init_apitogo_config_loader();
622
+ BillingPeriodSchema = z3.enum(["month", "year", "monthly", "annual"]);
623
+ ManifestPlanInputSchema = z3.object({
624
+ sku: z3.string().min(1),
625
+ displayName: z3.string().min(1),
626
+ priceAmount: z3.number().default(0),
627
+ priceCurrency: z3.string().optional(),
628
+ billingPeriod: BillingPeriodSchema.optional(),
629
+ limitsJson: z3.string().optional(),
630
+ includedActionKeys: z3.array(z3.string()).optional()
631
+ });
632
+ DevPortalLocalManifestSchema = z3.object({
633
+ siteName: z3.string().optional(),
634
+ branding: z3.object({
635
+ title: z3.string().optional(),
636
+ logoUrl: z3.string().optional()
637
+ }).optional(),
638
+ pricing: z3.object({
639
+ enabled: z3.boolean().optional()
640
+ }).optional(),
641
+ authentication: z3.object({
642
+ enabled: z3.boolean().optional(),
643
+ type: z3.string().optional(),
644
+ apiBaseUrl: z3.string().optional()
645
+ }).optional(),
646
+ plans: z3.array(ManifestPlanInputSchema).optional(),
647
+ backend: z3.object({
648
+ sourceDirectory: z3.string().optional(),
649
+ publishDirectory: z3.string().optional(),
650
+ openApiPath: z3.string().optional(),
651
+ runtime: z3.string().optional(),
652
+ runtimeVersion: z3.string().optional(),
653
+ deployed: z3.boolean().optional()
654
+ }).optional(),
655
+ gateway: z3.object({
656
+ authMode: z3.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
657
+ oidcMetadataUrl: z3.string().optional(),
658
+ oidcAllowedIssuers: z3.array(z3.string()).optional(),
659
+ oidcAudiences: z3.array(z3.string()).optional(),
660
+ limitsJson: z3.string().optional(),
661
+ publicHealthActionKey: z3.string().optional()
662
+ }).optional(),
663
+ projectId: z3.string().optional()
664
+ });
665
+ }
666
+ });
667
+
668
+ // src/config/validators/ModulesSchema.ts
669
+ import { z as z4 } from "zod";
670
+ var ModuleToggleSchema, DocsModuleSchema, LandingLinkSchema, LandingFeatureSchema, LandingHeroSchema, LandingContentSchema, DashboardContentSchema, ProfileContentSchema, PlanTierSchema, PlansContentSchema, SubmodulePageFields, LandingModuleSchema, UserManagementModuleSchema, ApiKeysModuleSchema, PlanCatalogItemSchema, PlansModuleSchema, DashboardModuleSchema, UserPanelModuleSchema, ModulesSchema;
141
671
  var init_ModulesSchema = __esm({
142
672
  "src/config/validators/ModulesSchema.ts"() {
143
- ModuleToggleSchema = z3.object({
144
- enabled: z3.boolean().describe("Whether this module is active in the application.")
673
+ ModuleToggleSchema = z4.object({
674
+ enabled: z4.boolean().describe("Whether this module is active in the application.")
145
675
  }).partial();
146
676
  DocsModuleSchema = ModuleToggleSchema.extend({
147
- files: z3.union([z3.string(), z3.array(z3.string())]).optional(),
148
- publishMarkdown: z3.boolean().optional(),
149
- defaultOptions: z3.object({
150
- toc: z3.boolean(),
151
- copyPage: z3.boolean().optional(),
152
- disablePager: z3.boolean(),
153
- showLastModified: z3.boolean(),
154
- suggestEdit: z3.object({
155
- url: z3.string(),
156
- text: z3.string().optional()
677
+ files: z4.union([z4.string(), z4.array(z4.string())]).optional(),
678
+ publishMarkdown: z4.boolean().optional(),
679
+ defaultOptions: z4.object({
680
+ toc: z4.boolean(),
681
+ copyPage: z4.boolean().optional(),
682
+ disablePager: z4.boolean(),
683
+ showLastModified: z4.boolean(),
684
+ suggestEdit: z4.object({
685
+ url: z4.string(),
686
+ text: z4.string().optional()
157
687
  }).optional()
158
688
  }).partial().optional(),
159
- llms: z3.object({
160
- llmsTxt: z3.boolean().optional(),
161
- llmsTxtFull: z3.boolean().optional(),
162
- includeProtected: z3.boolean().optional()
689
+ llms: z4.object({
690
+ llmsTxt: z4.boolean().optional(),
691
+ llmsTxtFull: z4.boolean().optional(),
692
+ includeProtected: z4.boolean().optional()
163
693
  }).optional()
164
694
  });
165
- LandingLinkSchema = z3.object({
166
- label: z3.string(),
167
- href: z3.string()
695
+ LandingLinkSchema = z4.object({
696
+ label: z4.string(),
697
+ href: z4.string()
168
698
  });
169
- LandingFeatureSchema = z3.object({
170
- title: z3.string(),
171
- description: z3.string()
699
+ LandingFeatureSchema = z4.object({
700
+ title: z4.string(),
701
+ description: z4.string()
172
702
  });
173
- LandingHeroSchema = z3.object({
174
- title: z3.string().optional(),
175
- subtitle: z3.string().optional(),
176
- description: z3.string().optional()
703
+ LandingHeroSchema = z4.object({
704
+ title: z4.string().optional(),
705
+ subtitle: z4.string().optional(),
706
+ description: z4.string().optional()
177
707
  }).optional();
178
- LandingContentSchema = z3.object({
708
+ LandingContentSchema = z4.object({
179
709
  hero: LandingHeroSchema,
180
- features: z3.array(LandingFeatureSchema).optional(),
710
+ features: z4.array(LandingFeatureSchema).optional(),
181
711
  primaryAction: LandingLinkSchema.optional(),
182
712
  secondaryAction: LandingLinkSchema.optional(),
183
- showPoweredBy: z3.boolean().optional()
713
+ showPoweredBy: z4.boolean().optional()
184
714
  }).optional();
185
- DashboardContentSchema = z3.object({
186
- title: z3.string().optional(),
187
- subtitle: z3.string().optional(),
188
- description: z3.string().optional(),
189
- quickLinks: z3.array(LandingLinkSchema).optional()
715
+ DashboardContentSchema = z4.object({
716
+ title: z4.string().optional(),
717
+ subtitle: z4.string().optional(),
718
+ description: z4.string().optional(),
719
+ quickLinks: z4.array(LandingLinkSchema).optional()
190
720
  }).optional();
191
- ProfileContentSchema = z3.object({
192
- title: z3.string().optional(),
193
- description: z3.string().optional()
721
+ ProfileContentSchema = z4.object({
722
+ title: z4.string().optional(),
723
+ description: z4.string().optional()
194
724
  }).optional();
195
- PlanTierSchema = z3.object({
196
- name: z3.string(),
197
- price: z3.string().optional(),
198
- description: z3.string().optional()
725
+ PlanTierSchema = z4.object({
726
+ name: z4.string(),
727
+ price: z4.string().optional(),
728
+ description: z4.string().optional()
199
729
  });
200
- PlansContentSchema = z3.object({
201
- title: z3.string().optional(),
202
- description: z3.string().optional(),
203
- tiers: z3.array(PlanTierSchema).optional()
730
+ PlansContentSchema = z4.object({
731
+ title: z4.string().optional(),
732
+ description: z4.string().optional(),
733
+ tiers: z4.array(PlanTierSchema).optional()
204
734
  }).optional();
205
735
  SubmodulePageFields = {
206
- page: z3.string().optional().describe(
736
+ page: z4.string().optional().describe(
207
737
  "Path to a custom page component file, relative to the project root."
208
738
  ),
209
- component: z3.custom().optional().describe("Custom React component for this sub-module page.")
739
+ component: z4.custom().optional().describe("Custom React component for this sub-module page.")
210
740
  };
211
741
  LandingModuleSchema = ModuleToggleSchema.extend({
212
- path: z3.string().default("/").describe("Route path for the landing page."),
213
- component: z3.custom().optional().describe("Custom React component for the landing page."),
214
- page: z3.string().optional().describe(
742
+ path: z4.string().default("/").describe("Route path for the landing page."),
743
+ component: z4.custom().optional().describe("Custom React component for the landing page."),
744
+ page: z4.string().optional().describe(
215
745
  "Path to a custom landing page component file, relative to the project root."
216
746
  ),
217
- layout: z3.enum(["default", "landing", "none"]).default("landing").describe(
747
+ layout: z4.enum(["default", "landing", "none"]).default("landing").describe(
218
748
  "Layout wrapper: landing (header + footer), default (docs layout), or none."
219
749
  ),
220
750
  content: LandingContentSchema.describe(
@@ -222,11 +752,11 @@ var init_ModulesSchema = __esm({
222
752
  )
223
753
  });
224
754
  UserManagementModuleSchema = ModuleToggleSchema.extend({
225
- routes: z3.object({
226
- login: z3.string().default("/signin"),
227
- register: z3.string().default("/signup"),
228
- profile: z3.string().default("profile"),
229
- logout: z3.string().default("/signout")
755
+ routes: z4.object({
756
+ login: z4.string().default("/signin"),
757
+ register: z4.string().default("/signup"),
758
+ profile: z4.string().default("profile"),
759
+ logout: z4.string().default("/signout")
230
760
  }).partial().optional(),
231
761
  page: SubmodulePageFields.page,
232
762
  component: SubmodulePageFields.component,
@@ -235,18 +765,30 @@ var init_ModulesSchema = __esm({
235
765
  )
236
766
  });
237
767
  ApiKeysModuleSchema = ModuleToggleSchema.extend({
238
- path: z3.string().default("settings/api-keys").describe("Route path for API key management.")
768
+ path: z4.string().default("settings/api-keys").describe("Route path for API key management.")
769
+ });
770
+ PlanCatalogItemSchema = z4.object({
771
+ sku: z4.string(),
772
+ displayName: z4.string(),
773
+ priceAmount: z4.number().default(0),
774
+ priceCurrency: z4.string().optional(),
775
+ billingPeriod: z4.string().optional(),
776
+ limitsJson: z4.string().optional(),
777
+ includedActionKeys: z4.array(z4.string()).optional()
239
778
  });
240
779
  PlansModuleSchema = ModuleToggleSchema.extend({
241
- path: z3.string().default("plans").describe("Route path for plans and subscription management."),
780
+ path: z4.string().default("plans").describe("Route path for plans and subscription management."),
242
781
  page: SubmodulePageFields.page,
243
782
  component: SubmodulePageFields.component,
244
783
  content: PlansContentSchema.describe(
245
784
  "Default plans page content when no custom component is provided."
785
+ ),
786
+ items: z4.array(PlanCatalogItemSchema).optional().describe(
787
+ "Gateway plan catalog for /pricing preview and publish (canonical storage)."
246
788
  )
247
789
  });
248
790
  DashboardModuleSchema = ModuleToggleSchema.extend({
249
- path: z3.string().default("dashboard").describe("Route path for the user dashboard."),
791
+ path: z4.string().default("dashboard").describe("Route path for the user dashboard."),
250
792
  page: SubmodulePageFields.page,
251
793
  component: SubmodulePageFields.component,
252
794
  content: DashboardContentSchema.describe(
@@ -254,13 +796,13 @@ var init_ModulesSchema = __esm({
254
796
  )
255
797
  });
256
798
  UserPanelModuleSchema = ModuleToggleSchema.extend({
257
- basePath: z3.string().default("/account").describe("Base path prefix for user panel routes."),
799
+ basePath: z4.string().default("/account").describe("Base path prefix for user panel routes."),
258
800
  dashboard: DashboardModuleSchema.optional(),
259
801
  userManagement: UserManagementModuleSchema.optional(),
260
802
  apiKeys: ApiKeysModuleSchema.optional(),
261
803
  plans: PlansModuleSchema.optional()
262
804
  });
263
- ModulesSchema = z3.object({
805
+ ModulesSchema = z4.object({
264
806
  docs: DocsModuleSchema.optional().describe(
265
807
  "Documentation module \u2014 MD/MDX pages and OpenAPI reference."
266
808
  ),
@@ -359,17 +901,18 @@ var init_resolve_modules = __esm({
359
901
  const plansConfig = userPanelModule?.plans;
360
902
  const dashboardEnabled = dashboardConfig?.enabled ?? (explicit ? false : false);
361
903
  const userManagementEnabled = explicit ? userManagementConfig?.enabled ?? !!config2.authentication : !!config2.authentication;
362
- const apiKeysEnabled = explicit ? apiKeysModuleConfig?.enabled ?? config2.apiKeys?.enabled ?? false : config2.apiKeys?.enabled ?? false;
363
- const plansEnabled = plansConfig?.enabled ?? false;
904
+ const apiKeysEnabled = explicit ? apiKeysModuleConfig?.enabled ?? false : false;
905
+ const billingEnabled = config2.__meta?.pricingEnabled === true || plansConfig?.enabled === true;
906
+ const plansEnabled = billingEnabled;
364
907
  const userPanelEnabled = userPanelModule?.enabled ?? (dashboardEnabled || userManagementEnabled || apiKeysEnabled || plansEnabled);
365
908
  const basePath = userPanelModule?.basePath ?? "/account";
366
909
  return {
367
910
  docs: {
368
911
  enabled: docsEnabled,
369
- files: docsModule?.files ?? config2.docs?.files,
370
- publishMarkdown: docsModule?.publishMarkdown ?? config2.docs?.publishMarkdown,
371
- defaultOptions: docsModule?.defaultOptions ?? config2.docs?.defaultOptions,
372
- llms: docsModule?.llms ?? config2.docs?.llms
912
+ files: docsModule?.files,
913
+ publishMarkdown: docsModule?.publishMarkdown,
914
+ defaultOptions: docsModule?.defaultOptions,
915
+ llms: docsModule?.llms
373
916
  },
374
917
  landing: {
375
918
  enabled: landingEnabled,
@@ -409,7 +952,8 @@ var init_resolve_modules = __esm({
409
952
  plans: {
410
953
  enabled: plansEnabled,
411
954
  path: joinPanelPath(basePath, plansConfig?.path ?? "plans"),
412
- content: resolvePlansContent(plansConfig?.content)
955
+ content: resolvePlansContent(plansConfig?.content),
956
+ items: plansConfig?.items
413
957
  }
414
958
  }
415
959
  };
@@ -563,30 +1107,30 @@ var init_objectEntries = __esm({
563
1107
  });
564
1108
 
565
1109
  // src/vite/shadcn-registry.ts
566
- import { z as z4 } from "zod";
1110
+ import { z as z5 } from "zod";
567
1111
  var registryItemCssSchema, registryItemSchema, fetchShadcnRegistryItem;
568
1112
  var init_shadcn_registry = __esm({
569
1113
  "src/vite/shadcn-registry.ts"() {
570
- registryItemCssSchema = z4.record(
571
- z4.string(),
572
- z4.lazy(
573
- () => z4.union([
574
- z4.string(),
575
- z4.record(
576
- z4.string(),
577
- z4.union([z4.string(), z4.record(z4.string(), z4.string())])
1114
+ registryItemCssSchema = z5.record(
1115
+ z5.string(),
1116
+ z5.lazy(
1117
+ () => z5.union([
1118
+ z5.string(),
1119
+ z5.record(
1120
+ z5.string(),
1121
+ z5.union([z5.string(), z5.record(z5.string(), z5.string())])
578
1122
  )
579
1123
  ])
580
1124
  )
581
1125
  );
582
- registryItemSchema = z4.object({
583
- $schema: z4.literal("https://ui.shadcn.com/schema/registry-item.json"),
584
- name: z4.string(),
585
- type: z4.enum(["registry:theme", "registry:style"]),
586
- cssVars: z4.object({
587
- theme: z4.record(z4.string(), z4.string()).optional(),
588
- light: z4.record(z4.string(), z4.string()).optional(),
589
- dark: z4.record(z4.string(), z4.string()).optional()
1126
+ registryItemSchema = z5.object({
1127
+ $schema: z5.literal("https://ui.shadcn.com/schema/registry-item.json"),
1128
+ name: z5.string(),
1129
+ type: z5.enum(["registry:theme", "registry:style"]),
1130
+ cssVars: z5.object({
1131
+ theme: z5.record(z5.string(), z5.string()).optional(),
1132
+ light: z5.record(z5.string(), z5.string()).optional(),
1133
+ dark: z5.record(z5.string(), z5.string()).optional()
590
1134
  }).optional(),
591
1135
  css: registryItemCssSchema.optional()
592
1136
  });
@@ -603,7 +1147,7 @@ var init_shadcn_registry = __esm({
603
1147
  });
604
1148
 
605
1149
  // src/vite/plugin-theme.ts
606
- import path2 from "node:path";
1150
+ import path4 from "node:path";
607
1151
  import { normalizeTheme } from "shiki";
608
1152
  var THEME_VARIABLES, uncamelize, processColorValue, generateCss, generateRegistryCss, processCustomCss, MAIN_REPLACE, DEFAULT_THEME_REPLACE, GOOGLE_FONTS, getGoogleFontUrl, processFont, processFontConfig, processFonts, virtualModuleId, resolvedVirtualModuleId, viteThemePlugin;
609
1153
  var init_plugin_theme = __esm({
@@ -891,7 +1435,7 @@ ${rootVars.join("\n")}
891
1435
  config2.__meta.rootDir,
892
1436
  ...config2.__meta.dependencies,
893
1437
  ...config2.__pluginDirs ?? []
894
- ].map((file) => path2.relative(path2.dirname(id), file))
1438
+ ].map((file) => path4.relative(path4.dirname(id), file))
895
1439
  );
896
1440
  const code = [...files].map((file) => `@source "${file}";`);
897
1441
  code.push("@theme inline {");
@@ -2915,65 +3459,65 @@ var init_icon_types = __esm({
2915
3459
  });
2916
3460
 
2917
3461
  // src/config/validators/InputNavigationSchema.ts
2918
- import { z as z5 } from "zod";
3462
+ import { z as z6 } from "zod";
2919
3463
  var IconSchema, BadgeSchema, InputNavigationCategoryLinkDocSchema, DisplaySchema, NavigationModifyRuleSchema, NavigationInsertRuleSchema, NavigationRemoveRuleSchema, NavigationSortRuleSchema, NavigationMoveRuleSchema, NavigationRuleSchema, NavigationRulesSchema, InputNavigationDocSchema, InputNavigationLinkSchema, InputNavigationCustomPageSchema, InputNavigationSeparatorSchema, InputNavigationSectionSchema, InputNavigationFilterSchema, BaseInputNavigationCategorySchema, InputNavigationCategorySchema, InputNavigationItemSchema, InputNavigationSchema;
2920
3464
  var init_InputNavigationSchema = __esm({
2921
3465
  "src/config/validators/InputNavigationSchema.ts"() {
2922
- IconSchema = z5.custom((f) => typeof f === "string");
2923
- BadgeSchema = z5.object({
2924
- label: z5.string(),
3466
+ IconSchema = z6.custom((f) => typeof f === "string");
3467
+ BadgeSchema = z6.object({
3468
+ label: z6.string(),
2925
3469
  // prettier-ignore
2926
- color: z5.enum(["green", "blue", "yellow", "red", "purple", "indigo", "gray", "outline"]),
2927
- invert: z5.boolean().optional(),
2928
- className: z5.string().optional()
3470
+ color: z6.enum(["green", "blue", "yellow", "red", "purple", "indigo", "gray", "outline"]),
3471
+ invert: z6.boolean().optional(),
3472
+ className: z6.string().optional()
2929
3473
  });
2930
- InputNavigationCategoryLinkDocSchema = z5.union([
2931
- z5.string(),
2932
- z5.object({
2933
- type: z5.literal("doc"),
2934
- file: z5.string(),
2935
- label: z5.string().optional(),
2936
- path: z5.string().optional()
3474
+ InputNavigationCategoryLinkDocSchema = z6.union([
3475
+ z6.string(),
3476
+ z6.object({
3477
+ type: z6.literal("doc"),
3478
+ file: z6.string(),
3479
+ label: z6.string().optional(),
3480
+ path: z6.string().optional()
2937
3481
  })
2938
3482
  ]);
2939
- DisplaySchema = z5.union([
2940
- z5.enum(["auth", "anon", "always", "hide"]),
2941
- z5.custom((val) => typeof val === "function")
3483
+ DisplaySchema = z6.union([
3484
+ z6.enum(["auth", "anon", "always", "hide"]),
3485
+ z6.custom((val) => typeof val === "function")
2942
3486
  ]).optional();
2943
- NavigationModifyRuleSchema = z5.object({
2944
- type: z5.literal("modify"),
2945
- match: z5.string(),
2946
- set: z5.object({
2947
- label: z5.string().optional(),
3487
+ NavigationModifyRuleSchema = z6.object({
3488
+ type: z6.literal("modify"),
3489
+ match: z6.string(),
3490
+ set: z6.object({
3491
+ label: z6.string().optional(),
2948
3492
  icon: IconSchema.optional(),
2949
3493
  badge: BadgeSchema.optional(),
2950
- collapsed: z5.boolean().optional(),
2951
- collapsible: z5.boolean().optional(),
3494
+ collapsed: z6.boolean().optional(),
3495
+ collapsible: z6.boolean().optional(),
2952
3496
  display: DisplaySchema
2953
3497
  })
2954
3498
  });
2955
- NavigationInsertRuleSchema = z5.object({
2956
- type: z5.literal("insert"),
2957
- match: z5.string(),
2958
- position: z5.enum(["before", "after"]),
2959
- items: z5.lazy(() => InputNavigationItemSchema.array())
3499
+ NavigationInsertRuleSchema = z6.object({
3500
+ type: z6.literal("insert"),
3501
+ match: z6.string(),
3502
+ position: z6.enum(["before", "after"]),
3503
+ items: z6.lazy(() => InputNavigationItemSchema.array())
2960
3504
  });
2961
- NavigationRemoveRuleSchema = z5.object({
2962
- type: z5.literal("remove"),
2963
- match: z5.string()
3505
+ NavigationRemoveRuleSchema = z6.object({
3506
+ type: z6.literal("remove"),
3507
+ match: z6.string()
2964
3508
  });
2965
- NavigationSortRuleSchema = z5.object({
2966
- type: z5.literal("sort"),
2967
- match: z5.string(),
2968
- by: z5.custom((val) => typeof val === "function")
3509
+ NavigationSortRuleSchema = z6.object({
3510
+ type: z6.literal("sort"),
3511
+ match: z6.string(),
3512
+ by: z6.custom((val) => typeof val === "function")
2969
3513
  });
2970
- NavigationMoveRuleSchema = z5.object({
2971
- type: z5.literal("move"),
2972
- match: z5.string(),
2973
- to: z5.string(),
2974
- position: z5.enum(["before", "after"])
3514
+ NavigationMoveRuleSchema = z6.object({
3515
+ type: z6.literal("move"),
3516
+ match: z6.string(),
3517
+ to: z6.string(),
3518
+ position: z6.enum(["before", "after"])
2975
3519
  });
2976
- NavigationRuleSchema = z5.discriminatedUnion("type", [
3520
+ NavigationRuleSchema = z6.discriminatedUnion("type", [
2977
3521
  NavigationModifyRuleSchema,
2978
3522
  NavigationInsertRuleSchema,
2979
3523
  NavigationRemoveRuleSchema,
@@ -2981,65 +3525,65 @@ var init_InputNavigationSchema = __esm({
2981
3525
  NavigationMoveRuleSchema
2982
3526
  ]);
2983
3527
  NavigationRulesSchema = NavigationRuleSchema.array();
2984
- InputNavigationDocSchema = z5.union([
2985
- z5.string(),
2986
- z5.object({
2987
- type: z5.literal("doc"),
2988
- file: z5.string(),
3528
+ InputNavigationDocSchema = z6.union([
3529
+ z6.string(),
3530
+ z6.object({
3531
+ type: z6.literal("doc"),
3532
+ file: z6.string(),
2989
3533
  // Custom URL path for this document (overrides file-based path)
2990
- path: z5.string().optional(),
3534
+ path: z6.string().optional(),
2991
3535
  icon: IconSchema.optional(),
2992
- label: z5.string().optional(),
3536
+ label: z6.string().optional(),
2993
3537
  badge: BadgeSchema.optional(),
2994
3538
  display: DisplaySchema
2995
3539
  })
2996
3540
  ]);
2997
- InputNavigationLinkSchema = z5.object({
2998
- type: z5.literal("link"),
2999
- to: z5.string(),
3000
- label: z5.string(),
3001
- target: z5.enum(["_self", "_blank"]).optional(),
3541
+ InputNavigationLinkSchema = z6.object({
3542
+ type: z6.literal("link"),
3543
+ to: z6.string(),
3544
+ label: z6.string(),
3545
+ target: z6.enum(["_self", "_blank"]).optional(),
3002
3546
  icon: IconSchema.optional(),
3003
3547
  badge: BadgeSchema.optional(),
3004
3548
  display: DisplaySchema
3005
3549
  });
3006
- InputNavigationCustomPageSchema = z5.object({
3007
- type: z5.literal("custom-page"),
3008
- path: z5.string(),
3009
- label: z5.string().optional(),
3010
- element: z5.any(),
3550
+ InputNavigationCustomPageSchema = z6.object({
3551
+ type: z6.literal("custom-page"),
3552
+ path: z6.string(),
3553
+ label: z6.string().optional(),
3554
+ element: z6.any(),
3011
3555
  icon: IconSchema.optional(),
3012
3556
  badge: BadgeSchema.optional(),
3013
3557
  display: DisplaySchema,
3014
- layout: z5.enum(["default", "none"]).optional()
3558
+ layout: z6.enum(["default", "none"]).optional()
3015
3559
  });
3016
- InputNavigationSeparatorSchema = z5.object({
3017
- type: z5.literal("separator"),
3560
+ InputNavigationSeparatorSchema = z6.object({
3561
+ type: z6.literal("separator"),
3018
3562
  display: DisplaySchema
3019
3563
  });
3020
- InputNavigationSectionSchema = z5.object({
3021
- type: z5.literal("section"),
3022
- label: z5.string(),
3564
+ InputNavigationSectionSchema = z6.object({
3565
+ type: z6.literal("section"),
3566
+ label: z6.string(),
3023
3567
  display: DisplaySchema
3024
3568
  });
3025
- InputNavigationFilterSchema = z5.object({
3026
- type: z5.literal("filter"),
3027
- placeholder: z5.string().optional(),
3569
+ InputNavigationFilterSchema = z6.object({
3570
+ type: z6.literal("filter"),
3571
+ placeholder: z6.string().optional(),
3028
3572
  display: DisplaySchema
3029
3573
  });
3030
- BaseInputNavigationCategorySchema = z5.object({
3031
- type: z5.literal("category"),
3574
+ BaseInputNavigationCategorySchema = z6.object({
3575
+ type: z6.literal("category"),
3032
3576
  icon: IconSchema.optional(),
3033
- label: z5.string(),
3034
- collapsible: z5.boolean().optional(),
3035
- collapsed: z5.boolean().optional(),
3577
+ label: z6.string(),
3578
+ collapsible: z6.boolean().optional(),
3579
+ collapsed: z6.boolean().optional(),
3036
3580
  link: InputNavigationCategoryLinkDocSchema.optional(),
3037
3581
  display: DisplaySchema
3038
3582
  });
3039
3583
  InputNavigationCategorySchema = BaseInputNavigationCategorySchema.extend({
3040
- items: z5.lazy(() => InputNavigationItemSchema.array())
3584
+ items: z6.lazy(() => InputNavigationItemSchema.array())
3041
3585
  });
3042
- InputNavigationItemSchema = z5.union([
3586
+ InputNavigationItemSchema = z6.union([
3043
3587
  InputNavigationDocSchema,
3044
3588
  InputNavigationLinkSchema,
3045
3589
  InputNavigationCustomPageSchema,
@@ -3053,39 +3597,39 @@ var init_InputNavigationSchema = __esm({
3053
3597
  });
3054
3598
 
3055
3599
  // src/config/validators/HeaderNavigationSchema.ts
3056
- import { z as z6 } from "zod";
3600
+ import { z as z7 } from "zod";
3057
3601
  var IconSchema2, HeaderNavLinkItemSchema, HeaderNavGroupSchema, HeaderNavItemSchema, HeaderNavigationSchema;
3058
3602
  var init_HeaderNavigationSchema = __esm({
3059
3603
  "src/config/validators/HeaderNavigationSchema.ts"() {
3060
3604
  init_icon_types();
3061
3605
  init_InputNavigationSchema();
3062
- IconSchema2 = z6.enum(IconNames);
3063
- HeaderNavLinkItemSchema = z6.object({
3064
- label: z6.string(),
3606
+ IconSchema2 = z7.enum(IconNames);
3607
+ HeaderNavLinkItemSchema = z7.object({
3608
+ label: z7.string(),
3065
3609
  icon: IconSchema2.optional(),
3066
- description: z6.string().optional(),
3067
- to: z6.string(),
3068
- target: z6.enum(["_self", "_blank"]).optional(),
3610
+ description: z7.string().optional(),
3611
+ to: z7.string(),
3612
+ target: z7.enum(["_self", "_blank"]).optional(),
3069
3613
  display: DisplaySchema
3070
3614
  });
3071
- HeaderNavGroupSchema = z6.object({
3072
- label: z6.string(),
3073
- items: z6.array(HeaderNavLinkItemSchema)
3615
+ HeaderNavGroupSchema = z7.object({
3616
+ label: z7.string(),
3617
+ items: z7.array(HeaderNavLinkItemSchema)
3074
3618
  });
3075
- HeaderNavItemSchema = z6.union([
3076
- z6.object({
3077
- label: z6.string(),
3619
+ HeaderNavItemSchema = z7.union([
3620
+ z7.object({
3621
+ label: z7.string(),
3078
3622
  icon: IconSchema2.optional(),
3079
- to: z6.string(),
3080
- target: z6.enum(["_self", "_blank"]).optional(),
3623
+ to: z7.string(),
3624
+ target: z7.enum(["_self", "_blank"]).optional(),
3081
3625
  display: DisplaySchema
3082
3626
  }),
3083
- z6.object({
3084
- label: z6.string(),
3085
- items: z6.array(z6.union([HeaderNavLinkItemSchema, HeaderNavGroupSchema]))
3627
+ z7.object({
3628
+ label: z7.string(),
3629
+ items: z7.array(z7.union([HeaderNavLinkItemSchema, HeaderNavGroupSchema]))
3086
3630
  })
3087
3631
  ]);
3088
- HeaderNavigationSchema = z6.array(HeaderNavItemSchema);
3632
+ HeaderNavigationSchema = z7.array(HeaderNavItemSchema);
3089
3633
  }
3090
3634
  });
3091
3635
 
@@ -3150,23 +3694,23 @@ var init_ZudokuContext = __esm({
3150
3694
  });
3151
3695
 
3152
3696
  // src/config/validators/ProtectedRoutesSchema.ts
3153
- import { z as z7 } from "zod/mini";
3697
+ import { z as z8 } from "zod/mini";
3154
3698
  var ProtectedRoutesInputSchema, ProtectedRoutesSchema;
3155
3699
  var init_ProtectedRoutesSchema = __esm({
3156
3700
  "src/config/validators/ProtectedRoutesSchema.ts"() {
3157
3701
  init_ZudokuContext();
3158
- ProtectedRoutesInputSchema = z7.optional(
3159
- z7.union([
3160
- z7.array(z7.string()),
3161
- z7.record(
3162
- z7.string(),
3163
- z7.custom((val) => typeof val === "function")
3702
+ ProtectedRoutesInputSchema = z8.optional(
3703
+ z8.union([
3704
+ z8.array(z8.string()),
3705
+ z8.record(
3706
+ z8.string(),
3707
+ z8.custom((val) => typeof val === "function")
3164
3708
  )
3165
3709
  ])
3166
3710
  );
3167
- ProtectedRoutesSchema = z7.pipe(
3711
+ ProtectedRoutesSchema = z8.pipe(
3168
3712
  ProtectedRoutesInputSchema,
3169
- z7.transform(normalizeProtectedRoutes)
3713
+ z8.transform(normalizeProtectedRoutes)
3170
3714
  );
3171
3715
  }
3172
3716
  });
@@ -3184,18 +3728,18 @@ __export(ZudokuConfig_exports, {
3184
3728
  });
3185
3729
  import colors from "picocolors";
3186
3730
  import { isValidElement as isValidElement2 } from "react";
3187
- import { z as z8 } from "zod";
3731
+ import { z as z9 } from "zod";
3188
3732
  function validateConfig(config2, configPath) {
3189
3733
  const validationResult = ZudokuConfig.safeParse(config2);
3190
3734
  if (!validationResult.success) {
3191
3735
  if (process.env.NODE_ENV === "production") {
3192
3736
  throw new Error(
3193
3737
  `Whoops, looks like there's an issue with your ${configPath ?? "config"}:
3194
- ${z8.prettifyError(validationResult.error)}`
3738
+ ${z9.prettifyError(validationResult.error)}`
3195
3739
  );
3196
3740
  }
3197
3741
  console.log(colors.yellow("Validation errors:"));
3198
- console.log(colors.yellow(z8.prettifyError(validationResult.error)));
3742
+ console.log(colors.yellow(z9.prettifyError(validationResult.error)));
3199
3743
  }
3200
3744
  }
3201
3745
  var ThemeSchema, ApiCatalogCategorySchema, LanguageOption, AiAssistantCustomSchema, AiAssistantPresets, AiAssistantsSchema, ApiOptionsSchema, ApiConfigSchema, VersionConfigSchema, ApiSchema, ApiKeysSchema, LogoSchema, FooterSocialIcons, FooterSocialSchema, FooterSchema, SiteMapSchema, DEFAULT_DOCS_FILES, LlmsConfigSchema, DocsConfigSchema, Redirect, SearchSchema, AuthenticationSchema, MetadataSchema, FontConfigSchema, FontsConfigSchema, CssObject, ThemeConfigSchema, SiteSchema, PlacementPosition, HeaderConfigSchema, ApiCatalogSchema, CdnUrlSchema, BaseConfigSchema, ZudokuConfig;
@@ -3206,114 +3750,114 @@ var init_ZudokuConfig = __esm({
3206
3750
  init_InputNavigationSchema();
3207
3751
  init_ModulesSchema();
3208
3752
  init_ProtectedRoutesSchema();
3209
- ThemeSchema = z8.object({
3210
- background: z8.string(),
3211
- foreground: z8.string(),
3212
- card: z8.string(),
3213
- cardForeground: z8.string(),
3214
- popover: z8.string(),
3215
- popoverForeground: z8.string(),
3216
- primary: z8.string(),
3217
- primaryForeground: z8.string(),
3218
- secondary: z8.string(),
3219
- secondaryForeground: z8.string(),
3220
- muted: z8.string(),
3221
- mutedForeground: z8.string(),
3222
- accent: z8.string(),
3223
- accentForeground: z8.string(),
3224
- destructive: z8.string(),
3225
- destructiveForeground: z8.string(),
3226
- border: z8.string(),
3227
- input: z8.string(),
3228
- ring: z8.string(),
3229
- radius: z8.string()
3753
+ ThemeSchema = z9.object({
3754
+ background: z9.string(),
3755
+ foreground: z9.string(),
3756
+ card: z9.string(),
3757
+ cardForeground: z9.string(),
3758
+ popover: z9.string(),
3759
+ popoverForeground: z9.string(),
3760
+ primary: z9.string(),
3761
+ primaryForeground: z9.string(),
3762
+ secondary: z9.string(),
3763
+ secondaryForeground: z9.string(),
3764
+ muted: z9.string(),
3765
+ mutedForeground: z9.string(),
3766
+ accent: z9.string(),
3767
+ accentForeground: z9.string(),
3768
+ destructive: z9.string(),
3769
+ destructiveForeground: z9.string(),
3770
+ border: z9.string(),
3771
+ input: z9.string(),
3772
+ ring: z9.string(),
3773
+ radius: z9.string()
3230
3774
  }).partial();
3231
- ApiCatalogCategorySchema = z8.object({
3232
- label: z8.string(),
3233
- tags: z8.array(z8.string())
3775
+ ApiCatalogCategorySchema = z9.object({
3776
+ label: z9.string(),
3777
+ tags: z9.array(z9.string())
3234
3778
  });
3235
- LanguageOption = z8.object({
3236
- value: z8.string().min(1),
3237
- label: z8.string().min(1)
3779
+ LanguageOption = z9.object({
3780
+ value: z9.string().min(1),
3781
+ label: z9.string().min(1)
3238
3782
  });
3239
- AiAssistantCustomSchema = z8.object({
3240
- label: z8.string(),
3241
- icon: z8.custom().optional(),
3242
- url: z8.union([
3243
- z8.string(),
3244
- z8.custom((val) => typeof val === "function")
3783
+ AiAssistantCustomSchema = z9.object({
3784
+ label: z9.string(),
3785
+ icon: z9.custom().optional(),
3786
+ url: z9.union([
3787
+ z9.string(),
3788
+ z9.custom((val) => typeof val === "function")
3245
3789
  ])
3246
3790
  });
3247
3791
  AiAssistantPresets = ["claude", "chatgpt"];
3248
- AiAssistantsSchema = z8.union([
3249
- z8.literal(false),
3250
- z8.array(z8.union([z8.enum(AiAssistantPresets), AiAssistantCustomSchema]))
3792
+ AiAssistantsSchema = z9.union([
3793
+ z9.literal(false),
3794
+ z9.array(z9.union([z9.enum(AiAssistantPresets), AiAssistantCustomSchema]))
3251
3795
  ]).optional();
3252
- ApiOptionsSchema = z8.object({
3253
- examplesLanguage: z8.string(),
3254
- supportedLanguages: z8.array(LanguageOption),
3255
- disablePlayground: z8.boolean(),
3256
- disableSidecar: z8.boolean(),
3257
- showVersionSelect: z8.enum(["always", "if-available", "hide"]),
3258
- expandAllTags: z8.boolean(),
3259
- showInfoPage: z8.boolean(),
3260
- schemaDownload: z8.object({ enabled: z8.boolean() }).partial(),
3261
- transformExamples: z8.custom(
3796
+ ApiOptionsSchema = z9.object({
3797
+ examplesLanguage: z9.string(),
3798
+ supportedLanguages: z9.array(LanguageOption),
3799
+ disablePlayground: z9.boolean(),
3800
+ disableSidecar: z9.boolean(),
3801
+ showVersionSelect: z9.enum(["always", "if-available", "hide"]),
3802
+ expandAllTags: z9.boolean(),
3803
+ showInfoPage: z9.boolean(),
3804
+ schemaDownload: z9.object({ enabled: z9.boolean() }).partial(),
3805
+ transformExamples: z9.custom(
3262
3806
  (val) => typeof val === "function"
3263
3807
  ),
3264
- generateCodeSnippet: z8.custom(
3808
+ generateCodeSnippet: z9.custom(
3265
3809
  (val) => typeof val === "function"
3266
3810
  )
3267
3811
  }).partial();
3268
- ApiConfigSchema = z8.object({
3269
- server: z8.string(),
3270
- path: z8.string(),
3271
- categories: z8.array(ApiCatalogCategorySchema),
3812
+ ApiConfigSchema = z9.object({
3813
+ server: z9.string(),
3814
+ path: z9.string(),
3815
+ categories: z9.array(ApiCatalogCategorySchema),
3272
3816
  options: ApiOptionsSchema
3273
3817
  }).partial();
3274
- VersionConfigSchema = z8.object({
3275
- path: z8.string(),
3276
- input: z8.string(),
3277
- label: z8.string().optional()
3818
+ VersionConfigSchema = z9.object({
3819
+ path: z9.string(),
3820
+ input: z9.string(),
3821
+ label: z9.string().optional()
3278
3822
  });
3279
- ApiSchema = z8.discriminatedUnion("type", [
3280
- z8.object({
3281
- type: z8.literal("url"),
3282
- input: z8.union([z8.string(), z8.array(VersionConfigSchema)]),
3823
+ ApiSchema = z9.discriminatedUnion("type", [
3824
+ z9.object({
3825
+ type: z9.literal("url"),
3826
+ input: z9.union([z9.string(), z9.array(VersionConfigSchema)]),
3283
3827
  ...ApiConfigSchema.shape
3284
3828
  }),
3285
- z8.object({
3286
- type: z8.literal("file"),
3287
- input: z8.union([
3288
- z8.string(),
3289
- z8.array(z8.union([z8.string(), VersionConfigSchema]))
3829
+ z9.object({
3830
+ type: z9.literal("file"),
3831
+ input: z9.union([
3832
+ z9.string(),
3833
+ z9.array(z9.union([z9.string(), VersionConfigSchema]))
3290
3834
  ]),
3291
3835
  ...ApiConfigSchema.shape
3292
3836
  }),
3293
- z8.object({
3294
- type: z8.literal("raw"),
3295
- input: z8.string(),
3837
+ z9.object({
3838
+ type: z9.literal("raw"),
3839
+ input: z9.string(),
3296
3840
  ...ApiConfigSchema.shape
3297
3841
  })
3298
3842
  ]);
3299
- ApiKeysSchema = z8.object({
3300
- enabled: z8.boolean(),
3301
- getConsumers: z8.custom(
3843
+ ApiKeysSchema = z9.object({
3844
+ enabled: z9.boolean(),
3845
+ getConsumers: z9.custom(
3302
3846
  (val) => typeof val === "function"
3303
3847
  ).optional(),
3304
- rollKey: z8.custom(
3848
+ rollKey: z9.custom(
3305
3849
  (val) => typeof val === "function"
3306
3850
  ).optional(),
3307
- deleteKey: z8.custom((val) => typeof val === "function").optional(),
3308
- updateKeyDescription: z8.custom((val) => typeof val === "function").optional(),
3309
- createKey: z8.custom((val) => typeof val === "function").optional()
3851
+ deleteKey: z9.custom((val) => typeof val === "function").optional(),
3852
+ updateKeyDescription: z9.custom((val) => typeof val === "function").optional(),
3853
+ createKey: z9.custom((val) => typeof val === "function").optional()
3310
3854
  });
3311
- LogoSchema = z8.object({
3312
- src: z8.object({ light: z8.string(), dark: z8.string() }),
3313
- alt: z8.string().optional(),
3314
- width: z8.string().or(z8.number()).optional(),
3315
- href: z8.string().optional(),
3316
- reloadDocument: z8.boolean().optional()
3855
+ LogoSchema = z9.object({
3856
+ src: z9.object({ light: z9.string(), dark: z9.string() }),
3857
+ alt: z9.string().optional(),
3858
+ width: z9.string().or(z9.number()).optional(),
3859
+ href: z9.string().optional(),
3860
+ reloadDocument: z9.boolean().optional()
3317
3861
  });
3318
3862
  FooterSocialIcons = [
3319
3863
  "reddit",
@@ -3331,38 +3875,38 @@ var init_ZudokuConfig = __esm({
3331
3875
  "whatsapp",
3332
3876
  "telegram"
3333
3877
  ];
3334
- FooterSocialSchema = z8.object({
3335
- label: z8.string().optional(),
3336
- href: z8.string(),
3337
- icon: z8.union([
3338
- z8.enum(FooterSocialIcons),
3339
- z8.custom((val) => isValidElement2(val))
3878
+ FooterSocialSchema = z9.object({
3879
+ label: z9.string().optional(),
3880
+ href: z9.string(),
3881
+ icon: z9.union([
3882
+ z9.enum(FooterSocialIcons),
3883
+ z9.custom((val) => isValidElement2(val))
3340
3884
  ]).optional()
3341
3885
  });
3342
- FooterSchema = z8.object({
3343
- columns: z8.array(
3344
- z8.object({
3345
- position: z8.enum(["start", "center", "end"]).optional(),
3346
- title: z8.string(),
3347
- links: z8.array(z8.object({ label: z8.string(), href: z8.string() }))
3886
+ FooterSchema = z9.object({
3887
+ columns: z9.array(
3888
+ z9.object({
3889
+ position: z9.enum(["start", "center", "end"]).optional(),
3890
+ title: z9.string(),
3891
+ links: z9.array(z9.object({ label: z9.string(), href: z9.string() }))
3348
3892
  })
3349
3893
  ).optional(),
3350
- social: z8.array(FooterSocialSchema).optional(),
3351
- copyright: z8.string().optional(),
3894
+ social: z9.array(FooterSocialSchema).optional(),
3895
+ copyright: z9.string().optional(),
3352
3896
  logo: LogoSchema.optional(),
3353
- position: z8.enum(["start", "center", "end"]).optional()
3897
+ position: z9.enum(["start", "center", "end"]).optional()
3354
3898
  }).optional();
3355
- SiteMapSchema = z8.object({
3899
+ SiteMapSchema = z9.object({
3356
3900
  /**
3357
3901
  * Base url of your website
3358
3902
  */
3359
- siteUrl: z8.string(),
3903
+ siteUrl: z9.string(),
3360
3904
  /**
3361
3905
  * Change frequency.
3362
3906
  * @default 'daily'
3363
3907
  */
3364
- changefreq: z8.optional(
3365
- z8.enum([
3908
+ changefreq: z9.optional(
3909
+ z9.enum([
3366
3910
  "always",
3367
3911
  "hourly",
3368
3912
  "daily",
@@ -3376,101 +3920,101 @@ var init_ZudokuConfig = __esm({
3376
3920
  * Priority
3377
3921
  * @default 0.7
3378
3922
  */
3379
- priority: z8.optional(z8.number()),
3380
- outDir: z8.string().optional(),
3923
+ priority: z9.optional(z9.number()),
3924
+ outDir: z9.string().optional(),
3381
3925
  /**
3382
3926
  * Add <lastmod/> property.
3383
3927
  * @default true
3384
3928
  */
3385
- autoLastmod: z8.boolean().optional(),
3929
+ autoLastmod: z9.boolean().optional(),
3386
3930
  /**
3387
3931
  * Array of relative paths to exclude from listing on sitemap.xml or sitemap-*.xml.
3388
3932
  * @example ['/page-0', '/page/example']
3389
3933
  */
3390
- exclude: z8.union([
3391
- z8.custom((val) => typeof val === "function"),
3392
- z8.array(z8.string())
3934
+ exclude: z9.union([
3935
+ z9.custom((val) => typeof val === "function"),
3936
+ z9.array(z9.string())
3393
3937
  ]).optional()
3394
3938
  }).optional();
3395
3939
  DEFAULT_DOCS_FILES = "/pages/**/*.{md,mdx}";
3396
- LlmsConfigSchema = z8.object({
3397
- llmsTxt: z8.boolean().default(false).describe(
3940
+ LlmsConfigSchema = z9.object({
3941
+ llmsTxt: z9.boolean().default(false).describe(
3398
3942
  "When enabled, generates an llms.txt file following the spec at https://llmstxt.org/. This file provides a summary with links to all documentation."
3399
3943
  ),
3400
- llmsTxtFull: z8.boolean().default(false).describe(
3944
+ llmsTxtFull: z9.boolean().default(false).describe(
3401
3945
  "When enabled, generates an llms-full.txt file with the complete content of all markdown documents for LLM consumption."
3402
3946
  ),
3403
- includeProtected: z8.boolean().default(false).describe(
3947
+ includeProtected: z9.boolean().default(false).describe(
3404
3948
  "When enabled, includes content from protected routes in the generated .md files and llms.txt files. By default, protected routes are excluded."
3405
3949
  )
3406
3950
  }).partial();
3407
- DocsConfigSchema = z8.object({
3408
- files: z8.union([z8.string(), z8.array(z8.string())]).transform((val) => typeof val === "string" ? [val] : val).default([DEFAULT_DOCS_FILES]),
3409
- publishMarkdown: z8.boolean().default(false).describe(
3951
+ DocsConfigSchema = z9.object({
3952
+ files: z9.union([z9.string(), z9.array(z9.string())]).transform((val) => typeof val === "string" ? [val] : val).default([DEFAULT_DOCS_FILES]),
3953
+ publishMarkdown: z9.boolean().default(false).describe(
3410
3954
  "When enabled, generates .md files for each document during build. Access documents at their URL path with .md extension (e.g., /foo/hello.md). Markdown files are generated without frontmatter."
3411
3955
  ),
3412
- defaultOptions: z8.object({
3413
- toc: z8.boolean(),
3414
- copyPage: z8.boolean().optional(),
3415
- disablePager: z8.boolean(),
3416
- showLastModified: z8.boolean(),
3417
- suggestEdit: z8.object({
3418
- url: z8.string(),
3419
- text: z8.string().optional()
3956
+ defaultOptions: z9.object({
3957
+ toc: z9.boolean(),
3958
+ copyPage: z9.boolean().optional(),
3959
+ disablePager: z9.boolean(),
3960
+ showLastModified: z9.boolean(),
3961
+ suggestEdit: z9.object({
3962
+ url: z9.string(),
3963
+ text: z9.string().optional()
3420
3964
  }).optional()
3421
3965
  }).partial().optional(),
3422
3966
  llms: LlmsConfigSchema.optional()
3423
3967
  });
3424
- Redirect = z8.object({
3425
- from: z8.string(),
3426
- to: z8.string()
3968
+ Redirect = z9.object({
3969
+ from: z9.string(),
3970
+ to: z9.string()
3427
3971
  });
3428
- SearchSchema = z8.discriminatedUnion("type", [
3972
+ SearchSchema = z9.discriminatedUnion("type", [
3429
3973
  // looseObject to allow additional properties so the
3430
3974
  // user can set other inkeep settings
3431
- z8.looseObject({
3432
- type: z8.literal("inkeep"),
3433
- apiKey: z8.string(),
3434
- integrationId: z8.string(),
3435
- organizationId: z8.string(),
3436
- primaryBrandColor: z8.string(),
3437
- organizationDisplayName: z8.string()
3975
+ z9.looseObject({
3976
+ type: z9.literal("inkeep"),
3977
+ apiKey: z9.string(),
3978
+ integrationId: z9.string(),
3979
+ organizationId: z9.string(),
3980
+ primaryBrandColor: z9.string(),
3981
+ organizationDisplayName: z9.string()
3438
3982
  }),
3439
- z8.object({
3440
- type: z8.literal("pagefind"),
3441
- ranking: z8.object({
3442
- termFrequency: z8.number(),
3443
- pageLength: z8.number(),
3444
- termSimilarity: z8.number(),
3445
- termSaturation: z8.number()
3983
+ z9.object({
3984
+ type: z9.literal("pagefind"),
3985
+ ranking: z9.object({
3986
+ termFrequency: z9.number(),
3987
+ pageLength: z9.number(),
3988
+ termSimilarity: z9.number(),
3989
+ termSaturation: z9.number()
3446
3990
  }).optional(),
3447
- maxResults: z8.number().optional(),
3448
- maxSubResults: z8.number().optional(),
3449
- transformResults: z8.custom((val) => typeof val === "function").optional()
3991
+ maxResults: z9.number().optional(),
3992
+ maxSubResults: z9.number().optional(),
3993
+ transformResults: z9.custom((val) => typeof val === "function").optional()
3450
3994
  })
3451
3995
  ]).optional();
3452
- AuthenticationSchema = z8.discriminatedUnion("type", [
3453
- z8.object({
3454
- type: z8.literal("clerk"),
3455
- clerkPubKey: z8.custom().refine((val) => /^pk_(test|live)_\w+$/.test(val), {
3996
+ AuthenticationSchema = z9.discriminatedUnion("type", [
3997
+ z9.object({
3998
+ type: z9.literal("clerk"),
3999
+ clerkPubKey: z9.custom().refine((val) => /^pk_(test|live)_\w+$/.test(val), {
3456
4000
  message: "Clerk public key invalid, must start with pk_test or pk_live"
3457
4001
  }),
3458
- jwtTemplateName: z8.string().optional().default("dev-portal"),
3459
- redirectToAfterSignUp: z8.string().optional(),
3460
- redirectToAfterSignIn: z8.string().optional(),
3461
- redirectToAfterSignOut: z8.string().optional()
4002
+ jwtTemplateName: z9.string().optional().default("dev-portal"),
4003
+ redirectToAfterSignUp: z9.string().optional(),
4004
+ redirectToAfterSignIn: z9.string().optional(),
4005
+ redirectToAfterSignOut: z9.string().optional()
3462
4006
  }),
3463
- z8.object({
3464
- type: z8.literal("firebase"),
3465
- apiKey: z8.string(),
3466
- authDomain: z8.string(),
3467
- projectId: z8.string(),
3468
- storageBucket: z8.string().optional(),
3469
- messagingSenderId: z8.string().optional(),
3470
- appId: z8.string(),
3471
- measurementId: z8.string().optional(),
3472
- providers: z8.array(
3473
- z8.enum([
4007
+ z9.object({
4008
+ type: z9.literal("firebase"),
4009
+ apiKey: z9.string(),
4010
+ authDomain: z9.string(),
4011
+ projectId: z9.string(),
4012
+ storageBucket: z9.string().optional(),
4013
+ messagingSenderId: z9.string().optional(),
4014
+ appId: z9.string(),
4015
+ measurementId: z9.string().optional(),
4016
+ providers: z9.array(
4017
+ z9.enum([
3474
4018
  "google",
3475
4019
  "facebook",
3476
4020
  "twitter",
@@ -3483,37 +4027,37 @@ var init_ZudokuConfig = __esm({
3483
4027
  "emailLink"
3484
4028
  ])
3485
4029
  ).optional(),
3486
- redirectToAfterSignUp: z8.string().optional(),
3487
- redirectToAfterSignIn: z8.string().optional(),
3488
- redirectToAfterSignOut: z8.string().optional()
4030
+ redirectToAfterSignUp: z9.string().optional(),
4031
+ redirectToAfterSignIn: z9.string().optional(),
4032
+ redirectToAfterSignOut: z9.string().optional()
3489
4033
  }),
3490
- z8.object({
3491
- type: z8.literal("openid"),
3492
- basePath: z8.string().optional(),
3493
- clientId: z8.string(),
3494
- issuer: z8.string(),
3495
- audience: z8.string().optional(),
3496
- scopes: z8.array(z8.string()).optional(),
3497
- redirectToAfterSignUp: z8.string().optional(),
3498
- redirectToAfterSignIn: z8.string().optional(),
3499
- redirectToAfterSignOut: z8.string().optional()
4034
+ z9.object({
4035
+ type: z9.literal("openid"),
4036
+ basePath: z9.string().optional(),
4037
+ clientId: z9.string(),
4038
+ issuer: z9.string(),
4039
+ audience: z9.string().optional(),
4040
+ scopes: z9.array(z9.string()).optional(),
4041
+ redirectToAfterSignUp: z9.string().optional(),
4042
+ redirectToAfterSignIn: z9.string().optional(),
4043
+ redirectToAfterSignOut: z9.string().optional()
3500
4044
  }),
3501
- z8.object({
3502
- type: z8.literal("azureb2c"),
3503
- basePath: z8.string().optional(),
3504
- clientId: z8.string(),
3505
- tenantName: z8.string(),
3506
- policyName: z8.string(),
3507
- scopes: z8.array(z8.string()).optional(),
3508
- issuer: z8.string(),
3509
- redirectToAfterSignUp: z8.string().optional(),
3510
- redirectToAfterSignIn: z8.string().optional(),
3511
- redirectToAfterSignOut: z8.string().optional()
4045
+ z9.object({
4046
+ type: z9.literal("azureb2c"),
4047
+ basePath: z9.string().optional(),
4048
+ clientId: z9.string(),
4049
+ tenantName: z9.string(),
4050
+ policyName: z9.string(),
4051
+ scopes: z9.array(z9.string()).optional(),
4052
+ issuer: z9.string(),
4053
+ redirectToAfterSignUp: z9.string().optional(),
4054
+ redirectToAfterSignIn: z9.string().optional(),
4055
+ redirectToAfterSignOut: z9.string().optional()
3512
4056
  }),
3513
- z8.object({
3514
- type: z8.literal("auth0"),
3515
- clientId: z8.string(),
3516
- domain: z8.string().refine(
4057
+ z9.object({
4058
+ type: z9.literal("auth0"),
4059
+ clientId: z9.string(),
4060
+ domain: z9.string().refine(
3517
4061
  (val) => {
3518
4062
  if (val.startsWith("http://") || val.startsWith("https://")) {
3519
4063
  return false;
@@ -3527,116 +4071,116 @@ var init_ZudokuConfig = __esm({
3527
4071
  message: "Domain must be a host only (e.g., 'example.com') without protocol or slashes"
3528
4072
  }
3529
4073
  ),
3530
- audience: z8.string().optional(),
3531
- scopes: z8.array(z8.string()).optional(),
3532
- redirectToAfterSignUp: z8.string().optional(),
3533
- redirectToAfterSignIn: z8.string().optional(),
3534
- redirectToAfterSignOut: z8.string().optional(),
3535
- options: z8.object({
3536
- alwaysPromptLogin: z8.boolean().optional(),
3537
- prompt: z8.string().optional()
4074
+ audience: z9.string().optional(),
4075
+ scopes: z9.array(z9.string()).optional(),
4076
+ redirectToAfterSignUp: z9.string().optional(),
4077
+ redirectToAfterSignIn: z9.string().optional(),
4078
+ redirectToAfterSignOut: z9.string().optional(),
4079
+ options: z9.object({
4080
+ alwaysPromptLogin: z9.boolean().optional(),
4081
+ prompt: z9.string().optional()
3538
4082
  }).optional()
3539
4083
  }),
3540
- z8.object({
3541
- type: z8.literal("supabase"),
3542
- basePath: z8.string().optional(),
3543
- supabaseUrl: z8.string(),
3544
- supabaseKey: z8.string(),
3545
- provider: z8.string().optional(),
3546
- providers: z8.array(z8.string()).optional(),
3547
- onlyThirdPartyProviders: z8.boolean().optional(),
3548
- redirectToAfterSignUp: z8.string().optional(),
3549
- redirectToAfterSignIn: z8.string().optional(),
3550
- redirectToAfterSignOut: z8.string().optional()
4084
+ z9.object({
4085
+ type: z9.literal("supabase"),
4086
+ basePath: z9.string().optional(),
4087
+ supabaseUrl: z9.string(),
4088
+ supabaseKey: z9.string(),
4089
+ provider: z9.string().optional(),
4090
+ providers: z9.array(z9.string()).optional(),
4091
+ onlyThirdPartyProviders: z9.boolean().optional(),
4092
+ redirectToAfterSignUp: z9.string().optional(),
4093
+ redirectToAfterSignIn: z9.string().optional(),
4094
+ redirectToAfterSignOut: z9.string().optional()
3551
4095
  }),
3552
- z8.object({
3553
- type: z8.literal("dev-portal"),
3554
- apiBaseUrl: z8.string().optional(),
3555
- redirectToAfterSignUp: z8.string().optional(),
3556
- redirectToAfterSignIn: z8.string().optional(),
3557
- redirectToAfterSignOut: z8.string().optional()
4096
+ z9.object({
4097
+ type: z9.literal("dev-portal"),
4098
+ apiBaseUrl: z9.string().optional(),
4099
+ redirectToAfterSignUp: z9.string().optional(),
4100
+ redirectToAfterSignIn: z9.string().optional(),
4101
+ redirectToAfterSignOut: z9.string().optional()
3558
4102
  })
3559
4103
  ]);
3560
- MetadataSchema = z8.object({
3561
- title: z8.string(),
3562
- defaultTitle: z8.string().optional(),
3563
- description: z8.string(),
3564
- logo: z8.string(),
3565
- favicon: z8.string(),
3566
- generator: z8.string(),
3567
- applicationName: z8.string(),
3568
- referrer: z8.string(),
3569
- keywords: z8.array(z8.string()),
3570
- authors: z8.array(z8.string()),
3571
- creator: z8.string(),
3572
- publisher: z8.string()
4104
+ MetadataSchema = z9.object({
4105
+ title: z9.string(),
4106
+ defaultTitle: z9.string().optional(),
4107
+ description: z9.string(),
4108
+ logo: z9.string(),
4109
+ favicon: z9.string(),
4110
+ generator: z9.string(),
4111
+ applicationName: z9.string(),
4112
+ referrer: z9.string(),
4113
+ keywords: z9.array(z9.string()),
4114
+ authors: z9.array(z9.string()),
4115
+ creator: z9.string(),
4116
+ publisher: z9.string()
3573
4117
  }).partial();
3574
- FontConfigSchema = z8.union([
3575
- z8.enum(GOOGLE_FONTS),
3576
- z8.object({
3577
- url: z8.string(),
3578
- fontFamily: z8.string().optional()
4118
+ FontConfigSchema = z9.union([
4119
+ z9.enum(GOOGLE_FONTS),
4120
+ z9.object({
4121
+ url: z9.string(),
4122
+ fontFamily: z9.string().optional()
3579
4123
  })
3580
4124
  ]);
3581
- FontsConfigSchema = z8.object({
4125
+ FontsConfigSchema = z9.object({
3582
4126
  sans: FontConfigSchema.optional(),
3583
4127
  serif: FontConfigSchema.optional(),
3584
4128
  mono: FontConfigSchema.optional()
3585
4129
  });
3586
- CssObject = z8.record(
3587
- z8.string(),
3588
- z8.lazy(
3589
- () => z8.union([
3590
- z8.string(),
3591
- z8.record(
3592
- z8.string(),
3593
- z8.union([z8.string(), z8.record(z8.string(), z8.string())])
4130
+ CssObject = z9.record(
4131
+ z9.string(),
4132
+ z9.lazy(
4133
+ () => z9.union([
4134
+ z9.string(),
4135
+ z9.record(
4136
+ z9.string(),
4137
+ z9.union([z9.string(), z9.record(z9.string(), z9.string())])
3594
4138
  )
3595
4139
  ])
3596
4140
  )
3597
4141
  );
3598
- ThemeConfigSchema = z8.object({
3599
- registryUrl: z8.string().url().optional(),
3600
- customCss: z8.union([z8.string(), CssObject]).optional(),
4142
+ ThemeConfigSchema = z9.object({
4143
+ registryUrl: z9.string().url().optional(),
4144
+ customCss: z9.union([z9.string(), CssObject]).optional(),
3601
4145
  light: ThemeSchema.optional(),
3602
4146
  dark: ThemeSchema.optional(),
3603
4147
  fonts: FontsConfigSchema.optional(),
3604
- noDefaultTheme: z8.boolean().optional()
4148
+ noDefaultTheme: z9.boolean().optional()
3605
4149
  });
3606
- SiteSchema = z8.object({
3607
- title: z8.string(),
3608
- logoUrl: z8.string(),
3609
- dir: z8.enum(["ltr", "rtl"]).optional(),
4150
+ SiteSchema = z9.object({
4151
+ title: z9.string(),
4152
+ logoUrl: z9.string(),
4153
+ dir: z9.enum(["ltr", "rtl"]).optional(),
3610
4154
  logo: LogoSchema,
3611
- banner: z8.object({
3612
- message: z8.custom(),
3613
- color: z8.custom(
4155
+ banner: z9.object({
4156
+ message: z9.custom(),
4157
+ color: z9.custom(
3614
4158
  (val) => typeof val === "string"
3615
4159
  ).optional(),
3616
- dismissible: z8.boolean().optional()
4160
+ dismissible: z9.boolean().optional()
3617
4161
  }),
3618
4162
  footer: FooterSchema
3619
4163
  }).partial();
3620
- PlacementPosition = z8.enum(["start", "center", "end"]);
3621
- HeaderConfigSchema = z8.object({
4164
+ PlacementPosition = z9.enum(["start", "center", "end"]);
4165
+ HeaderConfigSchema = z9.object({
3622
4166
  navigation: HeaderNavigationSchema,
3623
- placements: z8.object({
4167
+ placements: z9.object({
3624
4168
  navigation: PlacementPosition,
3625
4169
  search: PlacementPosition,
3626
- auth: z8.enum(["start", "center", "end", "navigation"])
4170
+ auth: z9.enum(["start", "center", "end", "navigation"])
3627
4171
  }).partial().optional()
3628
4172
  }).partial();
3629
- ApiCatalogSchema = z8.object({
3630
- path: z8.string(),
3631
- label: z8.string(),
3632
- items: z8.array(z8.string()).optional(),
3633
- filterItems: z8.custom((val) => typeof val === "function").optional()
4173
+ ApiCatalogSchema = z9.object({
4174
+ path: z9.string(),
4175
+ label: z9.string(),
4176
+ items: z9.array(z9.string()).optional(),
4177
+ filterItems: z9.custom((val) => typeof val === "function").optional()
3634
4178
  });
3635
- CdnUrlSchema = z8.union([
3636
- z8.string(),
3637
- z8.object({
3638
- base: z8.string().optional(),
3639
- media: z8.string().optional()
4179
+ CdnUrlSchema = z9.union([
4180
+ z9.string(),
4181
+ z9.object({
4182
+ base: z9.string().optional(),
4183
+ media: z9.string().optional()
3640
4184
  })
3641
4185
  ]).transform((val) => {
3642
4186
  if (typeof val === "string") {
@@ -3644,45 +4188,45 @@ var init_ZudokuConfig = __esm({
3644
4188
  }
3645
4189
  return { base: val.base, media: val.media };
3646
4190
  }).optional();
3647
- BaseConfigSchema = z8.object({
3648
- slots: z8.record(z8.string(), z8.custom()),
4191
+ BaseConfigSchema = z9.object({
4192
+ slots: z9.record(z9.string(), z9.custom()),
3649
4193
  /**
3650
4194
  * @deprecated Use `slots` instead
3651
4195
  */
3652
- UNSAFE_slotlets: z8.record(z8.string(), z8.custom()),
3653
- mdx: z8.object({
3654
- components: z8.custom()
4196
+ UNSAFE_slotlets: z9.record(z9.string(), z9.custom()),
4197
+ mdx: z9.object({
4198
+ components: z9.custom()
3655
4199
  }).partial(),
3656
- customPages: z8.array(
3657
- z8.object({
3658
- path: z8.string(),
3659
- element: z8.custom().optional(),
3660
- render: z8.custom().optional(),
3661
- prose: z8.boolean().optional()
4200
+ customPages: z9.array(
4201
+ z9.object({
4202
+ path: z9.string(),
4203
+ element: z9.custom().optional(),
4204
+ render: z9.custom().optional(),
4205
+ prose: z9.boolean().optional()
3662
4206
  })
3663
4207
  ),
3664
- plugins: z8.array(z8.custom()),
3665
- build: z8.custom(),
4208
+ plugins: z9.array(z9.custom()),
4209
+ build: z9.custom(),
3666
4210
  protectedRoutes: ProtectedRoutesSchema,
3667
- basePath: z8.string().optional(),
3668
- canonicalUrlOrigin: z8.string().optional(),
4211
+ basePath: z9.string().optional(),
4212
+ canonicalUrlOrigin: z9.string().optional(),
3669
4213
  cdnUrl: CdnUrlSchema.optional(),
3670
- port: z8.number().optional(),
3671
- https: z8.object({
3672
- key: z8.string(),
3673
- cert: z8.string(),
3674
- ca: z8.string().optional()
4214
+ port: z9.number().optional(),
4215
+ https: z9.object({
4216
+ key: z9.string(),
4217
+ cert: z9.string(),
4218
+ ca: z9.string().optional()
3675
4219
  }).optional(),
3676
4220
  site: SiteSchema,
3677
4221
  header: HeaderConfigSchema.optional(),
3678
4222
  navigation: InputNavigationSchema,
3679
4223
  navigationRules: NavigationRulesSchema.optional(),
3680
4224
  theme: ThemeConfigSchema,
3681
- syntaxHighlighting: z8.object({
3682
- languages: z8.array(z8.custom()),
3683
- themes: z8.object({
3684
- light: z8.custom(),
3685
- dark: z8.custom()
4225
+ syntaxHighlighting: z9.object({
4226
+ languages: z9.array(z9.custom()),
4227
+ themes: z9.object({
4228
+ light: z9.custom(),
4229
+ dark: z9.custom()
3686
4230
  })
3687
4231
  }).partial().optional(),
3688
4232
  metadata: MetadataSchema,
@@ -3690,22 +4234,22 @@ var init_ZudokuConfig = __esm({
3690
4234
  search: SearchSchema,
3691
4235
  docs: DocsConfigSchema.optional(),
3692
4236
  modules: ModulesSchema,
3693
- apis: z8.union([ApiSchema, z8.array(ApiSchema)]),
3694
- catalogs: z8.union([ApiCatalogSchema, z8.array(ApiCatalogSchema)]),
4237
+ apis: z9.union([ApiSchema, z9.array(ApiSchema)]),
4238
+ catalogs: z9.union([ApiCatalogSchema, z9.array(ApiCatalogSchema)]),
3695
4239
  apiKeys: ApiKeysSchema,
3696
4240
  aiAssistants: AiAssistantsSchema,
3697
- redirects: z8.array(Redirect),
4241
+ redirects: z9.array(Redirect),
3698
4242
  sitemap: SiteMapSchema,
3699
- enableStatusPages: z8.boolean().optional(),
3700
- defaults: z8.object({
4243
+ enableStatusPages: z9.boolean().optional(),
4244
+ defaults: z9.object({
3701
4245
  apis: ApiOptionsSchema,
3702
4246
  /**
3703
4247
  * @deprecated Use `apis.examplesLanguage` or `defaults.apis.examplesLanguage` instead
3704
4248
  */
3705
- examplesLanguage: z8.string().optional()
4249
+ examplesLanguage: z9.string().optional()
3706
4250
  }),
3707
4251
  // Internal: populated by plugins via `transformConfig` to track plugin directories
3708
- __pluginDirs: z8.array(z8.string())
4252
+ __pluginDirs: z9.array(z9.string())
3709
4253
  });
3710
4254
  ZudokuConfig = BaseConfigSchema.partial();
3711
4255
  }
@@ -3713,7 +4257,7 @@ var init_ZudokuConfig = __esm({
3713
4257
 
3714
4258
  // src/config/loader.ts
3715
4259
  import { stat as stat2 } from "node:fs/promises";
3716
- import path3 from "node:path";
4260
+ import path5 from "node:path";
3717
4261
  import colors2 from "picocolors";
3718
4262
  import {
3719
4263
  runnerImport,
@@ -3721,7 +4265,7 @@ import {
3721
4265
  } from "vite";
3722
4266
  async function getConfigFilePath(rootDir) {
3723
4267
  for (const fileName of zudokuConfigFiles) {
3724
- const filepath = path3.join(rootDir, fileName);
4268
+ const filepath = path5.join(rootDir, fileName);
3725
4269
  if (await fileExists(filepath)) {
3726
4270
  return filepath;
3727
4271
  }
@@ -3791,8 +4335,16 @@ function isWatchableConfigDependency(depPath) {
3791
4335
  return !depPath.startsWith("\0virtual:") && !depPath.startsWith("virtual:");
3792
4336
  }
3793
4337
  function getWatchableConfigDependencies(config2) {
4338
+ const manifestEnv = resolveManifestEnv(
4339
+ config2.__meta.mode === "production" ? "production" : "development"
4340
+ );
4341
+ const { watchPaths } = manifestPathsForEnv(
4342
+ config2.__meta.rootDir,
4343
+ manifestEnv
4344
+ );
3794
4345
  return [
3795
4346
  config2.__meta.configPath,
4347
+ ...watchPaths,
3796
4348
  ...config2.__meta.dependencies.filter(isWatchableConfigDependency)
3797
4349
  ];
3798
4350
  }
@@ -3802,6 +4354,9 @@ async function hasConfigChanged() {
3802
4354
  try {
3803
4355
  const hasChanged = await Promise.all(
3804
4356
  files.map(async (depPath) => {
4357
+ if (!await fileExists(depPath)) {
4358
+ return false;
4359
+ }
3805
4360
  const depStat = await stat2(depPath);
3806
4361
  const cachedMtime = modifiedTimes?.get(depPath);
3807
4362
  return !cachedMtime || depStat.mtimeMs !== cachedMtime;
@@ -3818,6 +4373,9 @@ async function updateModifiedTimes() {
3818
4373
  modifiedTimes = /* @__PURE__ */ new Map();
3819
4374
  await Promise.all(
3820
4375
  files.map(async (depPath) => {
4376
+ if (!await fileExists(depPath)) {
4377
+ return;
4378
+ }
3821
4379
  const depStat = await stat2(depPath);
3822
4380
  modifiedTimes?.set(depPath, depStat.mtimeMs);
3823
4381
  })
@@ -3831,9 +4389,31 @@ async function loadZudokuConfig(configEnv, rootDir) {
3831
4389
  ({ publicEnv, envPrefix } = loadEnv(configEnv, rootDir));
3832
4390
  try {
3833
4391
  const loadedConfig = await loadZudokuConfigWithMeta(rootDir);
3834
- const transformedConfig = await runPluginTransformConfig(loadedConfig);
4392
+ const manifestEnv = resolveManifestEnv(configEnv.mode);
4393
+ const manifest = await readEffectiveManifest(rootDir, manifestEnv);
4394
+ const previewCatalog = manifestToPreviewCatalog(manifest);
4395
+ const jsonConfig = loadApitogoConfig(rootDir);
4396
+ const previewPlans = previewCatalog.plans.length ? previewCatalog.plans : plansToPreviewCatalog(
4397
+ readPlanCatalogItems(jsonConfig)
4398
+ ).plans;
4399
+ const configWithManifestMeta = {
4400
+ ...loadedConfig,
4401
+ __meta: {
4402
+ ...loadedConfig.__meta,
4403
+ pricingEnabled: isBillingEnabled(jsonConfig),
4404
+ authenticationEnabled: isAuthenticationEnabled(manifest),
4405
+ previewPlans
4406
+ }
4407
+ };
4408
+ const transformedConfig = applyAuthenticationHeaderNav(
4409
+ await runPluginTransformConfig(configWithManifestMeta)
4410
+ );
3835
4411
  config = {
3836
4412
  ...transformedConfig,
4413
+ __meta: {
4414
+ ...transformedConfig.__meta,
4415
+ ...configWithManifestMeta.__meta
4416
+ },
3837
4417
  __resolvedModules: resolveModulesConfig(transformedConfig)
3838
4418
  };
3839
4419
  if (!process.env.APITOGO_JSON_ONLY) {
@@ -3858,9 +4438,12 @@ var init_loader = __esm({
3858
4438
  "src/config/loader.ts"() {
3859
4439
  init_logger();
3860
4440
  init_package_json();
4441
+ init_auth_header_nav();
3861
4442
  init_transform_config();
3862
4443
  init_invariant();
4444
+ init_apitogo_config_loader();
3863
4445
  init_file_exists();
4446
+ init_local_manifest();
3864
4447
  init_resolve_modules();
3865
4448
  init_ZudokuConfig();
3866
4449
  zudokuConfigFiles = [
@@ -3898,7 +4481,7 @@ __export(llms_exports, {
3898
4481
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
3899
4482
  });
3900
4483
  import { writeFile as writeFile4 } from "node:fs/promises";
3901
- import path25 from "node:path";
4484
+ import path26 from "node:path";
3902
4485
  import colors6 from "picocolors";
3903
4486
  async function generateLlmsTxtFiles({
3904
4487
  markdownFileInfos,
@@ -3933,7 +4516,7 @@ async function generateLlmsTxtFiles({
3933
4516
  }
3934
4517
  }
3935
4518
  const llmsTxt2 = llmsTxtParts.join("\n");
3936
- await writeFile4(path25.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
4519
+ await writeFile4(path26.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
3937
4520
  if (process.env.APITOGO_JSON_ONLY !== "1") {
3938
4521
  console.log(colors6.blue("\u2713 generated llms.txt"));
3939
4522
  }
@@ -3961,7 +4544,7 @@ ${info.content}
3961
4544
  }
3962
4545
  const llmsFull = llmsFullParts.join("\n");
3963
4546
  await writeFile4(
3964
- path25.join(baseOutputDir, "llms-full.txt"),
4547
+ path26.join(baseOutputDir, "llms-full.txt"),
3965
4548
  llmsFull,
3966
4549
  "utf-8"
3967
4550
  );
@@ -3982,11 +4565,11 @@ import { hideBin } from "yargs/helpers";
3982
4565
  import yargs from "yargs/yargs";
3983
4566
 
3984
4567
  // src/cli/build/handler.ts
3985
- import path29 from "node:path";
4568
+ import path30 from "node:path";
3986
4569
 
3987
4570
  // src/vite/build.ts
3988
- import { mkdir as mkdir5, readFile as readFile4, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
3989
- import path27 from "node:path";
4571
+ import { mkdir as mkdir5, readFile as readFile3, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
4572
+ import path28 from "node:path";
3990
4573
  import { build as esbuild } from "esbuild";
3991
4574
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
3992
4575
 
@@ -4122,7 +4705,7 @@ init_invariant();
4122
4705
  init_joinUrl();
4123
4706
 
4124
4707
  // src/vite/config.ts
4125
- import path22 from "node:path";
4708
+ import path23 from "node:path";
4126
4709
  import dotenv from "dotenv";
4127
4710
  import colors4 from "picocolors";
4128
4711
  import {
@@ -4133,7 +4716,7 @@ import {
4133
4716
  // package.json
4134
4717
  var package_default = {
4135
4718
  name: "@lukoweb/apitogo",
4136
- version: "0.1.50",
4719
+ version: "0.1.53",
4137
4720
  type: "module",
4138
4721
  sideEffects: [
4139
4722
  "**/*.css",
@@ -4202,7 +4785,9 @@ var package_default = {
4202
4785
  "./processors/*": "./src/lib/plugins/openapi/processors/*.ts",
4203
4786
  "./with-zuplo": "./src/zuplo/with-zuplo.ts",
4204
4787
  "./testing": "./src/lib/testing/index.tsx",
4205
- "./local-manifest": "./src/config/local-manifest.ts"
4788
+ "./local-manifest": "./src/config/local-manifest.ts",
4789
+ "./build-config": "./src/config/build-apitogo-config.ts",
4790
+ "./config-loader": "./src/config/apitogo-config-loader.ts"
4206
4791
  },
4207
4792
  scripts: {
4208
4793
  build: "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
@@ -4516,6 +5101,14 @@ var package_default = {
4516
5101
  "./local-manifest": {
4517
5102
  types: "./dist/declarations/config/local-manifest.d.ts",
4518
5103
  default: "./src/config/local-manifest.ts"
5104
+ },
5105
+ "./build-config": {
5106
+ types: "./dist/declarations/config/build-apitogo-config.d.ts",
5107
+ default: "./src/config/build-apitogo-config.ts"
5108
+ },
5109
+ "./config-loader": {
5110
+ types: "./dist/declarations/config/apitogo-config-loader.d.ts",
5111
+ default: "./src/config/apitogo-config-loader.ts"
4519
5112
  }
4520
5113
  }
4521
5114
  }
@@ -4530,36 +5123,38 @@ init_joinUrl();
4530
5123
 
4531
5124
  // src/vite/dev-portal-env.ts
4532
5125
  import { loadEnv as loadEnv2 } from "vite";
5126
+ var AUTHENTICATION_API_BASE_URL_ENV = "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
5127
+ var LEGACY_DEV_PORTAL_API_URL_ENV = "VITE_APITOGO_DEV_PORTAL_API_URL";
4533
5128
  async function loadDevPortalViteDefines(rootDir, mode) {
4534
5129
  const env = loadEnv2(mode, rootDir, "VITE_");
4535
5130
  const defines = {};
4536
- const apiUrl = env.VITE_APITOGO_DEV_PORTAL_API_URL?.trim();
5131
+ const apiUrl = env[AUTHENTICATION_API_BASE_URL_ENV]?.trim() || env[LEGACY_DEV_PORTAL_API_URL_ENV]?.trim();
4537
5132
  if (apiUrl) {
4538
- defines.VITE_APITOGO_DEV_PORTAL_API_URL = JSON.stringify(apiUrl);
5133
+ defines[AUTHENTICATION_API_BASE_URL_ENV] = JSON.stringify(apiUrl);
4539
5134
  }
4540
5135
  return defines;
4541
5136
  }
4542
5137
 
4543
5138
  // src/vite/package-root.ts
4544
5139
  init_file_exists();
4545
- import path4 from "node:path";
5140
+ import path6 from "node:path";
4546
5141
  var findPackageRoot = async (startDir) => {
4547
5142
  let dir = startDir;
4548
- while (dir !== path4.dirname(dir)) {
4549
- if (await fileExists(path4.join(dir, "package.json"))) return dir;
4550
- dir = path4.dirname(dir);
5143
+ while (dir !== path6.dirname(dir)) {
5144
+ if (await fileExists(path6.join(dir, "package.json"))) return dir;
5145
+ dir = path6.dirname(dir);
4551
5146
  }
4552
5147
  };
4553
5148
 
4554
5149
  // src/vite/pagefind-dev-stub.ts
4555
5150
  import fs from "node:fs/promises";
4556
- import path5 from "node:path";
5151
+ import path7 from "node:path";
4557
5152
  var NOT_BUILT_YET = 'throw new Error("NOT_BUILT_YET");';
4558
5153
  async function ensurePagefindDevStub(publicDir) {
4559
- const pagefindPath = path5.join(publicDir, "pagefind/pagefind.js");
5154
+ const pagefindPath = path7.join(publicDir, "pagefind/pagefind.js");
4560
5155
  const exists = await fs.stat(pagefindPath).catch(() => false);
4561
5156
  if (!exists) {
4562
- await fs.mkdir(path5.dirname(pagefindPath), { recursive: true });
5157
+ await fs.mkdir(path7.dirname(pagefindPath), { recursive: true });
4563
5158
  await fs.writeFile(pagefindPath, NOT_BUILT_YET);
4564
5159
  }
4565
5160
  }
@@ -4571,7 +5166,7 @@ import react from "@vitejs/plugin-react";
4571
5166
  // src/vite/css/plugin.ts
4572
5167
  init_loader();
4573
5168
  init_plugin_theme();
4574
- import path6 from "node:path";
5169
+ import path8 from "node:path";
4575
5170
  import { isCSSRequest as isCSSRequest2 } from "vite";
4576
5171
 
4577
5172
  // src/vite/css/collect.ts
@@ -4606,7 +5201,7 @@ var VIRTUAL_ENTRY = "virtual:ssr-css.css";
4606
5201
  function vitePluginSsrCss(pluginOpts) {
4607
5202
  let server;
4608
5203
  const config2 = getCurrentConfig();
4609
- const virtualHref = path6.join(
5204
+ const virtualHref = path8.join(
4610
5205
  config2.basePath ?? "",
4611
5206
  `/@id/__x00__${VIRTUAL_ENTRY}?direct`
4612
5207
  );
@@ -4743,7 +5338,7 @@ var plugin_api_keys_default = viteApiKeysPlugin;
4743
5338
 
4744
5339
  // src/vite/plugin-api.ts
4745
5340
  import fs3 from "node:fs/promises";
4746
- import path12 from "node:path";
5341
+ import path14 from "node:path";
4747
5342
  import { deepEqual as deepEqual2 } from "fast-equals";
4748
5343
  import { runnerImport as runnerImport3 } from "vite";
4749
5344
  init_package_json();
@@ -4752,20 +5347,20 @@ init_loader();
4752
5347
  // src/config/validators/BuildSchema.ts
4753
5348
  init_file_exists();
4754
5349
  init_loader();
4755
- import path7 from "node:path";
5350
+ import path9 from "node:path";
4756
5351
  import { runnerImport as runnerImport2 } from "vite";
4757
- import { z as z9 } from "zod";
4758
- var BuildProcessorSchema = z9.custom((val) => typeof val === "function");
4759
- var PluginConfigSchema = z9.custom().or(
4760
- z9.custom(
5352
+ import { z as z10 } from "zod";
5353
+ var BuildProcessorSchema = z10.custom((val) => typeof val === "function");
5354
+ var PluginConfigSchema = z10.custom().or(
5355
+ z10.custom(
4761
5356
  (val) => typeof val === "function"
4762
5357
  )
4763
5358
  );
4764
- var BuildConfigSchema2 = z9.object({
4765
- processors: z9.array(BuildProcessorSchema).optional(),
5359
+ var BuildConfigSchema2 = z10.object({
5360
+ processors: z10.array(BuildProcessorSchema).optional(),
4766
5361
  remarkPlugins: PluginConfigSchema.optional(),
4767
5362
  rehypePlugins: PluginConfigSchema.optional(),
4768
- prerender: z9.object({ workers: z9.number().optional() }).optional()
5363
+ prerender: z10.object({ workers: z10.number().optional() }).optional()
4769
5364
  });
4770
5365
  var buildConfigFiles = [
4771
5366
  "apitogo.build.js",
@@ -4781,7 +5376,7 @@ var buildConfigFiles = [
4781
5376
  ];
4782
5377
  async function getBuildConfigFilePath(rootDir) {
4783
5378
  for (const fileName of buildConfigFiles) {
4784
- const filepath = path7.join(rootDir, fileName);
5379
+ const filepath = path9.join(rootDir, fileName);
4785
5380
  if (await fileExists(filepath)) {
4786
5381
  return filepath;
4787
5382
  }
@@ -4803,10 +5398,10 @@ function validateBuildConfig(config2) {
4803
5398
  const validationResult = BuildConfigSchema2.safeParse(config2);
4804
5399
  if (!validationResult.success) {
4805
5400
  if (process.env.NODE_ENV === "production") {
4806
- throw new Error(z9.prettifyError(validationResult.error));
5401
+ throw new Error(z10.prettifyError(validationResult.error));
4807
5402
  }
4808
5403
  console.warn("Build config validation errors:");
4809
- console.warn(z9.prettifyError(validationResult.error));
5404
+ console.warn(z10.prettifyError(validationResult.error));
4810
5405
  return;
4811
5406
  }
4812
5407
  return validationResult.data;
@@ -4890,14 +5485,14 @@ var flattenAllOf = (schema2) => {
4890
5485
  };
4891
5486
 
4892
5487
  // src/lib/util/traverse.ts
4893
- var traverse = (specification, transform, path38 = []) => {
4894
- const transformed = transform(specification, path38);
5488
+ var traverse = (specification, transform, path39 = []) => {
5489
+ const transformed = transform(specification, path39);
4895
5490
  if (typeof transformed !== "object" || transformed === null) {
4896
5491
  return transformed;
4897
5492
  }
4898
5493
  const result = Array.isArray(transformed) ? [] : {};
4899
5494
  for (const [key, value] of Object.entries(transformed)) {
4900
- const currentPath = [...path38, key];
5495
+ const currentPath = [...path39, key];
4901
5496
  if (Array.isArray(value)) {
4902
5497
  result[key] = value.map(
4903
5498
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -4925,9 +5520,9 @@ var resolveLocalRef = (schema2, ref) => {
4925
5520
  if (schemaCache?.has(ref)) {
4926
5521
  return schemaCache.get(ref);
4927
5522
  }
4928
- const path38 = ref.split("/").slice(1);
5523
+ const path39 = ref.split("/").slice(1);
4929
5524
  let current = schema2;
4930
- for (const segment of path38) {
5525
+ for (const segment of path39) {
4931
5526
  if (!current || typeof current !== "object") {
4932
5527
  current = null;
4933
5528
  }
@@ -4946,7 +5541,7 @@ var dereference = async (schema2, resolvers = []) => {
4946
5541
  }
4947
5542
  const cloned = structuredClone(schema2);
4948
5543
  const visited = /* @__PURE__ */ new Set();
4949
- const resolve = async (current, path38) => {
5544
+ const resolve = async (current, path39) => {
4950
5545
  if (isIndexableObject(current)) {
4951
5546
  if (visited.has(current)) {
4952
5547
  return CIRCULAR_REF;
@@ -4954,7 +5549,7 @@ var dereference = async (schema2, resolvers = []) => {
4954
5549
  visited.add(current);
4955
5550
  if (Array.isArray(current)) {
4956
5551
  for (let index = 0; index < current.length; index++) {
4957
- current[index] = await resolve(current[index], `${path38}/${index}`);
5552
+ current[index] = await resolve(current[index], `${path39}/${index}`);
4958
5553
  }
4959
5554
  } else {
4960
5555
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -4965,13 +5560,13 @@ var dereference = async (schema2, resolvers = []) => {
4965
5560
  for (const resolver of resolvers) {
4966
5561
  const resolved = await resolver($ref);
4967
5562
  if (resolved) {
4968
- result2 = await resolve(resolved, path38);
5563
+ result2 = await resolve(resolved, path39);
4969
5564
  break;
4970
5565
  }
4971
5566
  }
4972
5567
  if (result2 === void 0) {
4973
5568
  const resolved = await resolveLocalRef(cloned, $ref);
4974
- result2 = await resolve(resolved, path38);
5569
+ result2 = await resolve(resolved, path39);
4975
5570
  }
4976
5571
  if (hasSiblings) {
4977
5572
  if (result2 === CIRCULAR_REF) {
@@ -4984,7 +5579,7 @@ var dereference = async (schema2, resolvers = []) => {
4984
5579
  return result2;
4985
5580
  }
4986
5581
  for (const key in current) {
4987
- current[key] = await resolve(current[key], `${path38}/${key}`);
5582
+ current[key] = await resolve(current[key], `${path39}/${key}`);
4988
5583
  }
4989
5584
  }
4990
5585
  visited.delete(current);
@@ -5023,9 +5618,9 @@ var upgradeSchema = (schema2) => {
5023
5618
  }
5024
5619
  return sub;
5025
5620
  });
5026
- schema2 = traverse(schema2, (sub, path38) => {
5621
+ schema2 = traverse(schema2, (sub, path39) => {
5027
5622
  if (sub.example !== void 0) {
5028
- if (isSchemaPath(path38 ?? [])) {
5623
+ if (isSchemaPath(path39 ?? [])) {
5029
5624
  sub.examples = [sub.example];
5030
5625
  } else {
5031
5626
  sub.examples = {
@@ -5038,11 +5633,11 @@ var upgradeSchema = (schema2) => {
5038
5633
  }
5039
5634
  return sub;
5040
5635
  });
5041
- schema2 = traverse(schema2, (schema3, path38) => {
5636
+ schema2 = traverse(schema2, (schema3, path39) => {
5042
5637
  if (schema3.type === "object" && schema3.properties !== void 0) {
5043
- const parentPath = path38?.slice(0, -1);
5638
+ const parentPath = path39?.slice(0, -1);
5044
5639
  const isMultipart = parentPath?.some((segment, index) => {
5045
- return segment === "content" && path38?.[index + 1] === "multipart/form-data";
5640
+ return segment === "content" && path39?.[index + 1] === "multipart/form-data";
5046
5641
  });
5047
5642
  if (isMultipart) {
5048
5643
  const entries = Object.entries(schema3.properties);
@@ -5056,8 +5651,8 @@ var upgradeSchema = (schema2) => {
5056
5651
  }
5057
5652
  return schema3;
5058
5653
  });
5059
- schema2 = traverse(schema2, (schema3, path38) => {
5060
- if (path38?.includes("content") && path38.includes("application/octet-stream")) {
5654
+ schema2 = traverse(schema2, (schema3, path39) => {
5655
+ if (path39?.includes("content") && path39.includes("application/octet-stream")) {
5061
5656
  return {};
5062
5657
  }
5063
5658
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -5083,11 +5678,11 @@ var upgradeSchema = (schema2) => {
5083
5678
  }
5084
5679
  return sub;
5085
5680
  });
5086
- schema2 = traverse(schema2, (schema3, path38) => {
5681
+ schema2 = traverse(schema2, (schema3, path39) => {
5087
5682
  if (schema3.type === "string" && schema3.format === "byte") {
5088
- const parentPath = path38?.slice(0, -1);
5683
+ const parentPath = path39?.slice(0, -1);
5089
5684
  const contentMediaType = parentPath?.find(
5090
- (_, index) => path38?.[index - 1] === "content"
5685
+ (_, index) => path39?.[index - 1] === "content"
5091
5686
  );
5092
5687
  return {
5093
5688
  type: "string",
@@ -5099,7 +5694,7 @@ var upgradeSchema = (schema2) => {
5099
5694
  });
5100
5695
  return schema2;
5101
5696
  };
5102
- function isSchemaPath(path38) {
5697
+ function isSchemaPath(path39) {
5103
5698
  const schemaLocations = [
5104
5699
  ["components", "schemas"],
5105
5700
  "properties",
@@ -5112,10 +5707,10 @@ function isSchemaPath(path38) {
5112
5707
  ];
5113
5708
  return schemaLocations.some((location) => {
5114
5709
  if (Array.isArray(location)) {
5115
- return location.every((segment, index) => path38[index] === segment);
5710
+ return location.every((segment, index) => path39[index] === segment);
5116
5711
  }
5117
- return path38.includes(location);
5118
- }) || path38.includes("schema") || path38.some((segment) => segment.endsWith("Schema"));
5712
+ return path39.includes(location);
5713
+ }) || path39.includes("schema") || path39.some((segment) => segment.endsWith("Schema"));
5119
5714
  }
5120
5715
 
5121
5716
  // src/lib/oas/parser/index.ts
@@ -5197,13 +5792,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
5197
5792
  "anyOf",
5198
5793
  "oneOf"
5199
5794
  ]);
5200
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path38 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
5795
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path39 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
5201
5796
  if (obj === null || typeof obj !== "object") return obj;
5202
5797
  const refPath = obj.__$ref;
5203
5798
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
5204
5799
  if (isCircular) {
5205
5800
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
5206
- const circularProp = path38.find((p) => !OPENAPI_PROPS.has(p)) || path38[0];
5801
+ const circularProp = path39.find((p) => !OPENAPI_PROPS.has(p)) || path39[0];
5207
5802
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
5208
5803
  }
5209
5804
  if (refs.has(obj)) return refs.get(obj);
@@ -5213,7 +5808,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
5213
5808
  value,
5214
5809
  currentPath,
5215
5810
  refs,
5216
- [...path38, key],
5811
+ [...path39, key],
5217
5812
  currentRefPaths
5218
5813
  );
5219
5814
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -5248,7 +5843,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
5248
5843
  var getAllTags = (schema2) => {
5249
5844
  const rootTags = schema2.tags ?? [];
5250
5845
  const operations = Object.values(schema2.paths ?? {}).flatMap(
5251
- (path38) => HttpMethods.map((k) => path38?.[k]).filter((op) => op != null)
5846
+ (path39) => HttpMethods.map((k) => path39?.[k]).filter((op) => op != null)
5252
5847
  );
5253
5848
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
5254
5849
  const hasUntaggedOperations = operations.some(
@@ -5303,7 +5898,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
5303
5898
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
5304
5899
  var getAllOperations = (paths) => {
5305
5900
  const operations = Object.entries(paths ?? {}).flatMap(
5306
- ([path38, value]) => HttpMethods.flatMap((method) => {
5901
+ ([path39, value]) => HttpMethods.flatMap((method) => {
5307
5902
  if (!value?.[method]) return [];
5308
5903
  const operation = value[method];
5309
5904
  const pathParameters = value.parameters ?? [];
@@ -5323,7 +5918,7 @@ var getAllOperations = (paths) => {
5323
5918
  return {
5324
5919
  ...operation,
5325
5920
  method,
5326
- path: path38,
5921
+ path: path39,
5327
5922
  parameters,
5328
5923
  servers,
5329
5924
  tags: operation.tags ?? []
@@ -5681,8 +6276,8 @@ var Schema = builder.objectRef("Schema").implement({
5681
6276
  }),
5682
6277
  paths: t.field({
5683
6278
  type: [PathItem],
5684
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path38, value]) => ({
5685
- path: path38,
6279
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path39, value]) => ({
6280
+ path: path39,
5686
6281
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
5687
6282
  methods: Object.keys(value)
5688
6283
  }))
@@ -5777,7 +6372,7 @@ var ensureArray = (value) => Array.isArray(value) ? value : [value];
5777
6372
 
5778
6373
  // src/vite/api/SchemaManager.ts
5779
6374
  import fs2 from "node:fs/promises";
5780
- import path8 from "node:path";
6375
+ import path10 from "node:path";
5781
6376
  import {
5782
6377
  $RefParser as $RefParser2
5783
6378
  } from "@apidevtools/json-schema-ref-parser";
@@ -5829,7 +6424,7 @@ init_joinUrl();
5829
6424
 
5830
6425
  // src/vite/api/schema-codegen.ts
5831
6426
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
5832
- var getSegmentsFromPath = (path38) => path38.split("/").slice(1).map(unescapeJsonPointer);
6427
+ var getSegmentsFromPath = (path39) => path39.split("/").slice(1).map(unescapeJsonPointer);
5833
6428
  var createLocalRefMap = (obj) => {
5834
6429
  const refMap = /* @__PURE__ */ new Map();
5835
6430
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -5860,16 +6455,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
5860
6455
  /"__refMap\+Siblings:(.*?)"/g,
5861
6456
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
5862
6457
  );
5863
- var lookup = (schema2, path38, filePath) => {
5864
- const parts = getSegmentsFromPath(path38);
6458
+ var lookup = (schema2, path39, filePath) => {
6459
+ const parts = getSegmentsFromPath(path39);
5865
6460
  let val = schema2;
5866
6461
  for (const part of parts) {
5867
6462
  while (val.$ref?.startsWith("#/")) {
5868
- val = val.$ref === path38 ? val : lookup(schema2, val.$ref, filePath);
6463
+ val = val.$ref === path39 ? val : lookup(schema2, val.$ref, filePath);
5869
6464
  }
5870
6465
  if (val[part] === void 0) {
5871
6466
  throw new Error(
5872
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path38}`
6467
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path39}`
5873
6468
  );
5874
6469
  }
5875
6470
  val = val[part];
@@ -5967,18 +6562,18 @@ var SchemaManager = class {
5967
6562
  ];
5968
6563
  }
5969
6564
  getPathForFile = (input, params) => {
5970
- const filePath = path8.resolve(this.config.__meta.rootDir, input);
6565
+ const filePath = path10.resolve(this.config.__meta.rootDir, input);
5971
6566
  const apis = ensureArray(this.config.apis ?? []);
5972
6567
  for (const apiConfig of apis) {
5973
6568
  if (!apiConfig || apiConfig.type !== "file" || !apiConfig.path) continue;
5974
6569
  const match = normalizeInputs(apiConfig.input).some(
5975
- (i) => path8.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
6570
+ (i) => path10.resolve(this.config.__meta.rootDir, i.input) === filePath && deepEqual(i.params, params)
5976
6571
  );
5977
6572
  if (match) return apiConfig.path;
5978
6573
  }
5979
6574
  };
5980
6575
  processSchema = async (input) => {
5981
- const filePath = path8.resolve(this.config.__meta.rootDir, input.input);
6576
+ const filePath = path10.resolve(this.config.__meta.rootDir, input.input);
5982
6577
  const params = input.params;
5983
6578
  const configuredPath = this.getPathForFile(input.input, params);
5984
6579
  if (!configuredPath) {
@@ -6014,9 +6609,9 @@ var SchemaManager = class {
6014
6609
  const processedTime = Date.now();
6015
6610
  const code = generateCode(processedSchema, filePath);
6016
6611
  const prefixPath = slugify(configuredPath);
6017
- const processedFilePath = path8.posix.join(
6612
+ const processedFilePath = path10.posix.join(
6018
6613
  this.storeDir,
6019
- `${prefixPath}-${path8.basename(filePath)}${paramsSuffix(params)}.js`
6614
+ `${prefixPath}-${path10.basename(filePath)}${paramsSuffix(params)}.js`
6020
6615
  );
6021
6616
  const importKey = processedFilePath;
6022
6617
  await fs2.writeFile(processedFilePath, code);
@@ -6065,7 +6660,7 @@ var SchemaManager = class {
6065
6660
  };
6066
6661
  getAllTrackedFiles = () => Array.from(this.referencedBy.keys());
6067
6662
  getFilesToReprocess = (changedFile) => {
6068
- const resolvedPath = path8.resolve(this.config.__meta.rootDir, changedFile);
6663
+ const resolvedPath = path10.resolve(this.config.__meta.rootDir, changedFile);
6069
6664
  const referencedBy = this.referencedBy.get(resolvedPath);
6070
6665
  if (!referencedBy) return [];
6071
6666
  const filesToProcess = referencedBy.size === 0 ? [resolvedPath] : Array.from(referencedBy);
@@ -6094,7 +6689,7 @@ var SchemaManager = class {
6094
6689
  version: "",
6095
6690
  path: input.path ?? "",
6096
6691
  label: input.label,
6097
- inputPath: path8.resolve(this.config.__meta.rootDir, input.input),
6692
+ inputPath: path10.resolve(this.config.__meta.rootDir, input.input),
6098
6693
  params: input.params,
6099
6694
  importKey: "",
6100
6695
  downloadUrl: "",
@@ -6114,8 +6709,8 @@ var SchemaManager = class {
6114
6709
  }
6115
6710
  }
6116
6711
  };
6117
- getLatestSchema = (path38) => this.processedSchemas[path38]?.at(0);
6118
- getSchemasForPath = (path38) => this.processedSchemas[path38];
6712
+ getLatestSchema = (path39) => this.processedSchemas[path39]?.at(0);
6713
+ getSchemasForPath = (path39) => this.processedSchemas[path39];
6119
6714
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
6120
6715
  getUrlToFilePathMap = () => {
6121
6716
  const map = /* @__PURE__ */ new Map();
@@ -6137,7 +6732,7 @@ var SchemaManager = class {
6137
6732
  };
6138
6733
  createSchemaPath = (inputPath, versionPath, apiPath, params) => {
6139
6734
  const suffix = paramsSuffix(params);
6140
- const extension = suffix ? ".json" : path8.extname(inputPath);
6735
+ const extension = suffix ? ".json" : path10.extname(inputPath);
6141
6736
  return joinUrl(
6142
6737
  this.config.basePath,
6143
6738
  apiPath,
@@ -6160,7 +6755,7 @@ var SchemaManager = class {
6160
6755
  // src/vite/plugin-config-reload.ts
6161
6756
  init_logger();
6162
6757
  init_loader();
6163
- import path11 from "node:path";
6758
+ import path13 from "node:path";
6164
6759
  import colors3 from "picocolors";
6165
6760
 
6166
6761
  // src/vite/plugin-navigation.ts
@@ -6170,7 +6765,7 @@ import { stringify as stringify3 } from "javascript-stringify";
6170
6765
  import { isElement } from "react-is";
6171
6766
 
6172
6767
  // src/config/validators/NavigationSchema.ts
6173
- import path9 from "node:path";
6768
+ import path11 from "node:path";
6174
6769
  import { glob } from "glob";
6175
6770
  import { fromMarkdown } from "mdast-util-from-markdown";
6176
6771
  import { mdxFromMarkdown } from "mdast-util-mdx";
@@ -6221,7 +6816,7 @@ var extractRichH1 = (content) => {
6221
6816
  }
6222
6817
  };
6223
6818
  var isNavigationItem = (item) => item !== void 0;
6224
- var toPosixPath = (filePath) => filePath.split(path9.win32.sep).join(path9.posix.sep);
6819
+ var toPosixPath = (filePath) => filePath.split(path11.win32.sep).join(path11.posix.sep);
6225
6820
  var NavigationResolver = class {
6226
6821
  rootDir;
6227
6822
  globPatterns;
@@ -6354,13 +6949,13 @@ init_invariant();
6354
6949
 
6355
6950
  // src/vite/debug.ts
6356
6951
  import { mkdir, writeFile } from "node:fs/promises";
6357
- import path10 from "node:path";
6952
+ import path12 from "node:path";
6358
6953
  async function writePluginDebugCode(rootDir, pluginName, code, extension = "js") {
6359
6954
  if (process.env.ZUDOKU_BUILD_DEBUG) {
6360
- const debugDir = path10.join(rootDir, "dist", "debug");
6955
+ const debugDir = path12.join(rootDir, "dist", "debug");
6361
6956
  await mkdir(debugDir, { recursive: true });
6362
6957
  await writeFile(
6363
- path10.join(debugDir, `${pluginName}.${extension}`),
6958
+ path12.join(debugDir, `${pluginName}.${extension}`),
6364
6959
  typeof code === "string" ? code : code.join("\n")
6365
6960
  );
6366
6961
  }
@@ -6471,7 +7066,7 @@ var viteConfigReloadPlugin = () => ({
6471
7066
  });
6472
7067
  logger.info(
6473
7068
  colors3.blue(
6474
- `Config ${path11.basename(currentConfig.__meta.configPath)} changed. Reloading...`
7069
+ `Config ${path13.basename(currentConfig.__meta.configPath)} changed. Reloading...`
6475
7070
  ),
6476
7071
  { timestamp: true }
6477
7072
  );
@@ -6485,11 +7080,11 @@ var viteApiPlugin = async () => {
6485
7080
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
6486
7081
  const initialConfig = getCurrentConfig();
6487
7082
  const zuploProcessors = ZuploEnv.isZuplo ? await runnerImport3(
6488
- path12.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
7083
+ path14.resolve(getZudokuRootDir(), "src/zuplo/with-zuplo-processors.ts")
6489
7084
  ).then((m) => m.module.default(initialConfig.__meta.rootDir)) : [];
6490
7085
  const buildConfig = await getBuildConfig();
6491
7086
  const buildProcessors = buildConfig?.processors ?? [];
6492
- const tmpStoreDir = path12.posix.join(
7087
+ const tmpStoreDir = path14.posix.join(
6493
7088
  initialConfig.__meta.rootDir,
6494
7089
  "node_modules/.apitogo/processed"
6495
7090
  );
@@ -6517,7 +7112,7 @@ var viteApiPlugin = async () => {
6517
7112
  const inputPath = pathMap.get(req.url);
6518
7113
  if (!inputPath) return next();
6519
7114
  const content = await fs3.readFile(inputPath, "utf-8");
6520
- const mimeType = path12.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
7115
+ const mimeType = path14.extname(inputPath).toLowerCase() === ".json" ? "application/json" : "application/x-yaml";
6521
7116
  res.setHeader("Content-Type", `${mimeType}; charset=utf-8`);
6522
7117
  return res.end(content);
6523
7118
  });
@@ -6705,8 +7300,8 @@ var viteApiPlugin = async () => {
6705
7300
  if (process.env.NODE_ENV !== "production") return;
6706
7301
  for (const [urlPath, inputPath] of pathMap) {
6707
7302
  const content = await fs3.readFile(inputPath, "utf-8");
6708
- const outputPath = path12.join(config2.__meta.rootDir, "dist", urlPath);
6709
- await fs3.mkdir(path12.dirname(outputPath), { recursive: true });
7303
+ const outputPath = path14.join(config2.__meta.rootDir, "dist", urlPath);
7304
+ await fs3.mkdir(path14.dirname(outputPath), { recursive: true });
6710
7305
  await fs3.writeFile(outputPath, content, "utf-8");
6711
7306
  }
6712
7307
  }
@@ -6749,7 +7344,7 @@ var plugin_auth_default = viteAuthPlugin;
6749
7344
 
6750
7345
  // src/vite/plugin-component.ts
6751
7346
  init_loader();
6752
- import path13 from "node:path";
7347
+ import path15 from "node:path";
6753
7348
  var viteAliasPlugin = () => {
6754
7349
  return {
6755
7350
  name: "zudoku-component-plugin",
@@ -6777,7 +7372,7 @@ var viteAliasPlugin = () => {
6777
7372
  ];
6778
7373
  const aliases = replacements.map(([find, replacement]) => ({
6779
7374
  find,
6780
- replacement: path13.posix.join(config2.__meta.moduleDir, replacement)
7375
+ replacement: path15.posix.join(config2.__meta.moduleDir, replacement)
6781
7376
  }));
6782
7377
  return config2.__meta.mode === "internal" || config2.__meta.mode === "standalone" ? { resolve: { alias: aliases } } : void 0;
6783
7378
  }
@@ -6801,17 +7396,33 @@ var viteConfigPlugin = () => {
6801
7396
  configResolved(resolvedConfig) {
6802
7397
  viteConfig = resolvedConfig;
6803
7398
  },
6804
- load(id) {
7399
+ async load(id) {
6805
7400
  if (id !== resolvedVirtualModuleId3) return;
6806
7401
  const configPath = getCurrentConfig().__meta.configPath;
6807
7402
  if (!configPath) {
6808
7403
  return `export default {};`;
6809
7404
  }
7405
+ const { config: loadedConfig } = await loadZudokuConfig(
7406
+ {
7407
+ mode: viteConfig.mode,
7408
+ command: viteConfig.command
7409
+ },
7410
+ viteConfig.root
7411
+ );
7412
+ const clientMeta = {
7413
+ rootDir: loadedConfig.__meta.rootDir,
7414
+ pricingEnabled: loadedConfig.__meta.pricingEnabled,
7415
+ authenticationEnabled: loadedConfig.__meta.authenticationEnabled,
7416
+ previewPlans: loadedConfig.__meta.previewPlans
7417
+ };
6810
7418
  return `
6811
7419
  import rawConfig from "${normalizePath(configPath)}";
6812
7420
  import { runPluginTransformConfig } from "@lukoweb/apitogo/plugins";
6813
7421
 
6814
- const config = await runPluginTransformConfig(rawConfig);
7422
+ const config = await runPluginTransformConfig({
7423
+ ...rawConfig,
7424
+ __meta: ${JSON.stringify(clientMeta)},
7425
+ });
6815
7426
  export default config;
6816
7427
  `;
6817
7428
  },
@@ -6914,7 +7525,7 @@ var viteDocMetadataPlugin = () => ({
6914
7525
 
6915
7526
  // src/vite/plugin-docs.ts
6916
7527
  init_loader();
6917
- import path14 from "node:path";
7528
+ import path16 from "node:path";
6918
7529
  import { glob as glob3 } from "glob";
6919
7530
  import globParent from "glob-parent";
6920
7531
  init_ZudokuConfig();
@@ -6983,7 +7594,7 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
6983
7594
  if (process.env.NODE_ENV !== "development") {
6984
7595
  const draftStatuses = await Promise.all(
6985
7596
  globbedFiles.map(async (file) => {
6986
- const absolutePath = path14.resolve(config2.__meta.rootDir, file);
7597
+ const absolutePath = path16.resolve(config2.__meta.rootDir, file);
6987
7598
  const { data } = await readFrontmatter(absolutePath);
6988
7599
  return { file, isDraft: data.draft === true };
6989
7600
  })
@@ -6996,9 +7607,9 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
6996
7607
  if (draftFiles.has(file)) {
6997
7608
  continue;
6998
7609
  }
6999
- const relativePath = path14.posix.relative(parent, file);
7610
+ const relativePath = path16.posix.relative(parent, file);
7000
7611
  const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
7001
- const filePath = options.absolute ? path14.resolve(config2.__meta.rootDir, file) : file;
7612
+ const filePath = options.absolute ? path16.resolve(config2.__meta.rootDir, file) : file;
7002
7613
  fileMapping[routePath] = filePath;
7003
7614
  }
7004
7615
  }
@@ -7062,7 +7673,7 @@ var viteDocsPlugin = () => {
7062
7673
  const globbedDocuments = {};
7063
7674
  for (const [routePath, file] of Object.entries(fileMapping)) {
7064
7675
  const importPath = ensureLeadingSlash(
7065
- path14.posix.join(globImportBasePath, file)
7676
+ path16.posix.join(globImportBasePath, file)
7066
7677
  );
7067
7678
  globbedDocuments[routePath] = importPath;
7068
7679
  }
@@ -7086,212 +7697,9 @@ var viteDocsPlugin = () => {
7086
7697
  var plugin_docs_default = viteDocsPlugin;
7087
7698
 
7088
7699
  // src/vite/plugin-local-manifest.ts
7089
- import path16 from "node:path";
7090
-
7091
- // src/config/local-manifest.ts
7092
- import { access, readFile as readFile2 } from "node:fs/promises";
7093
- import path15 from "node:path";
7094
- import { z as z10 } from "zod";
7095
- var DEV_PORTAL_MANIFEST_FILENAME = "apitogo.local.json";
7096
- var APITOGO_MANIFEST_BASE_FILENAME = "apitogo.json";
7097
- var APITOGO_MANIFEST_ENV_FILES = {
7098
- development: "apitogo.local.json",
7099
- production: "apitogo.prod.json"
7100
- };
7101
- var BillingPeriodSchema = z10.enum(["month", "year", "monthly", "annual"]);
7102
- var ManifestPlanInputSchema = z10.object({
7103
- sku: z10.string().min(1),
7104
- displayName: z10.string().min(1),
7105
- isFree: z10.boolean(),
7106
- priceAmount: z10.number().optional(),
7107
- priceCurrency: z10.string().optional(),
7108
- billingPeriod: BillingPeriodSchema.optional(),
7109
- limitsJson: z10.string().optional(),
7110
- includedActionKeys: z10.array(z10.string()).optional()
7111
- });
7112
- var DevPortalLocalManifestSchema = z10.object({
7113
- siteName: z10.string().optional(),
7114
- branding: z10.object({
7115
- title: z10.string().optional(),
7116
- logoUrl: z10.string().optional()
7117
- }).optional(),
7118
- pricing: z10.object({
7119
- enabled: z10.boolean().optional()
7120
- }).optional(),
7121
- plans: z10.array(ManifestPlanInputSchema).optional(),
7122
- backend: z10.object({
7123
- sourceDirectory: z10.string().optional(),
7124
- publishDirectory: z10.string().optional(),
7125
- openApiPath: z10.string().optional(),
7126
- runtime: z10.string().optional(),
7127
- runtimeVersion: z10.string().optional(),
7128
- deployed: z10.boolean().optional()
7129
- }).optional(),
7130
- gateway: z10.object({
7131
- authMode: z10.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
7132
- oidcMetadataUrl: z10.string().optional(),
7133
- oidcAllowedIssuers: z10.array(z10.string()).optional(),
7134
- oidcAudiences: z10.array(z10.string()).optional(),
7135
- limitsJson: z10.string().optional(),
7136
- publicHealthActionKey: z10.string().optional()
7137
- }).optional(),
7138
- projectId: z10.string().optional(),
7139
- projectName: z10.string().optional()
7140
- });
7141
- function isPricingEnabled(manifest) {
7142
- return manifest?.pricing?.enabled === true;
7143
- }
7144
- function manifestToPreviewCatalog(manifest) {
7145
- const plans = manifest?.plans;
7146
- const catalog = plansToPreviewCatalog(plans);
7147
- return {
7148
- pricingEnabled: isPricingEnabled(manifest),
7149
- plans: catalog.plans
7150
- };
7151
- }
7152
- function normalizeBillingPeriod(period) {
7153
- if (!period) {
7154
- return "monthly";
7155
- }
7156
- const normalized = period.toLowerCase();
7157
- if (normalized === "month") {
7158
- return "monthly";
7159
- }
7160
- if (normalized === "year") {
7161
- return "annual";
7162
- }
7163
- return normalized;
7164
- }
7165
- function plansToPreviewCatalog(plans) {
7166
- if (!plans?.length) {
7167
- return { plans: [] };
7168
- }
7169
- return {
7170
- plans: plans.map((plan) => ({
7171
- sku: plan.sku,
7172
- displayName: plan.displayName,
7173
- isFree: plan.isFree,
7174
- priceAmount: plan.priceAmount ?? 0,
7175
- priceCurrency: plan.priceCurrency ?? "usd",
7176
- billingPeriod: normalizeBillingPeriod(plan.billingPeriod),
7177
- limitsJson: plan.limitsJson ?? null,
7178
- includedActionKeys: plan.includedActionKeys ?? []
7179
- }))
7180
- };
7181
- }
7182
- function resolveManifestEnv(viteMode) {
7183
- return viteMode === "production" ? "production" : "development";
7184
- }
7185
- function mergePlansBySku(existing, patch) {
7186
- const bySku = /* @__PURE__ */ new Map();
7187
- for (const plan of existing ?? []) {
7188
- bySku.set(plan.sku, plan);
7189
- }
7190
- for (const plan of patch) {
7191
- const prior = bySku.get(plan.sku);
7192
- bySku.set(plan.sku, prior ? { ...prior, ...plan } : plan);
7193
- }
7194
- return Array.from(bySku.values());
7195
- }
7196
- function mergeManifest(base, override) {
7197
- const merged = { ...base, ...override };
7198
- if (override.branding) {
7199
- merged.branding = { ...base.branding, ...override.branding };
7200
- }
7201
- if (override.pricing) {
7202
- merged.pricing = { ...base.pricing, ...override.pricing };
7203
- }
7204
- if (override.backend) {
7205
- merged.backend = { ...base.backend, ...override.backend };
7206
- }
7207
- if (override.gateway) {
7208
- merged.gateway = { ...base.gateway, ...override.gateway };
7209
- }
7210
- if (override.plans) {
7211
- merged.plans = mergePlansBySku(base.plans, override.plans);
7212
- }
7213
- return merged;
7214
- }
7215
- function manifestFilePath(rootDir, filename) {
7216
- return path15.join(
7217
- path15.resolve(rootDir),
7218
- filename ?? DEV_PORTAL_MANIFEST_FILENAME
7219
- );
7220
- }
7221
- function manifestPathsForEnv(rootDir, env) {
7222
- const resolvedRoot = path15.resolve(rootDir);
7223
- const basePath = path15.join(resolvedRoot, APITOGO_MANIFEST_BASE_FILENAME);
7224
- const overridePath = path15.join(resolvedRoot, APITOGO_MANIFEST_ENV_FILES[env]);
7225
- return {
7226
- basePath,
7227
- overridePath,
7228
- watchPaths: [basePath, overridePath]
7229
- };
7230
- }
7231
- function parseLocalManifestJson(raw) {
7232
- try {
7233
- const parsed = JSON.parse(raw);
7234
- const result = DevPortalLocalManifestSchema.safeParse(parsed);
7235
- if (!result.success) {
7236
- return null;
7237
- }
7238
- return result.data;
7239
- } catch {
7240
- return null;
7241
- }
7242
- }
7243
- async function fileExists2(filePath) {
7244
- try {
7245
- await access(filePath);
7246
- return true;
7247
- } catch {
7248
- return false;
7249
- }
7250
- }
7251
- async function readManifestFile(rootDir, filename) {
7252
- const filePath = manifestFilePath(rootDir, filename);
7253
- try {
7254
- const raw = await readFile2(filePath, "utf8");
7255
- return parseLocalManifestJson(raw);
7256
- } catch {
7257
- return null;
7258
- }
7259
- }
7260
- async function readEffectiveManifest(rootDir, env) {
7261
- const { basePath, overridePath } = manifestPathsForEnv(rootDir, env);
7262
- const hasBase = await fileExists2(basePath);
7263
- const hasOverride = await fileExists2(overridePath);
7264
- if (!hasBase) {
7265
- const legacy = await readManifestFile(
7266
- rootDir,
7267
- APITOGO_MANIFEST_ENV_FILES.development
7268
- );
7269
- if (legacy) {
7270
- return legacy;
7271
- }
7272
- if (hasOverride) {
7273
- return readManifestFile(rootDir, APITOGO_MANIFEST_ENV_FILES[env]);
7274
- }
7275
- return null;
7276
- }
7277
- const base = await readManifestFile(rootDir, APITOGO_MANIFEST_BASE_FILENAME);
7278
- if (!base) {
7279
- return null;
7280
- }
7281
- if (!hasOverride) {
7282
- return base;
7283
- }
7284
- const override = await readManifestFile(
7285
- rootDir,
7286
- APITOGO_MANIFEST_ENV_FILES[env]
7287
- );
7288
- if (!override) {
7289
- return base;
7290
- }
7291
- return mergeManifest(base, override);
7292
- }
7293
-
7294
- // src/vite/plugin-local-manifest.ts
7700
+ init_apitogo_config_loader();
7701
+ init_local_manifest();
7702
+ import path17 from "node:path";
7295
7703
  var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
7296
7704
  var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
7297
7705
  var viteLocalManifestPlugin = () => {
@@ -7304,6 +7712,15 @@ var viteLocalManifestPlugin = () => {
7304
7712
  try {
7305
7713
  const manifest = await readEffectiveManifest(rootDir, env);
7306
7714
  catalog = manifestToPreviewCatalog(manifest);
7715
+ if (!catalog.plans.length) {
7716
+ const config2 = loadApitogoConfig(rootDir);
7717
+ catalog = {
7718
+ ...catalog,
7719
+ ...plansToPreviewCatalog(
7720
+ readPlanCatalogItems(config2)
7721
+ )
7722
+ };
7723
+ }
7307
7724
  } catch {
7308
7725
  }
7309
7726
  return `export default ${JSON.stringify(catalog)};`;
@@ -7332,8 +7749,8 @@ var viteLocalManifestPlugin = () => {
7332
7749
  server.watcher.add(watchPath);
7333
7750
  }
7334
7751
  server.watcher.on("change", async (changedPath) => {
7335
- const resolvedChanged = path16.resolve(changedPath);
7336
- if (!watchPaths.some((p) => path16.resolve(p) === resolvedChanged)) {
7752
+ const resolvedChanged = path17.resolve(changedPath);
7753
+ if (!watchPaths.some((p) => path17.resolve(p) === resolvedChanged)) {
7337
7754
  return;
7338
7755
  }
7339
7756
  const module = server.moduleGraph.getModuleById(
@@ -7360,7 +7777,7 @@ init_loader();
7360
7777
  init_ProtectedRoutesSchema();
7361
7778
  init_joinUrl();
7362
7779
  import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
7363
- import path17 from "node:path";
7780
+ import path18 from "node:path";
7364
7781
  import { matchPath } from "react-router";
7365
7782
  var processMarkdownFile = async (filePath) => {
7366
7783
  const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
@@ -7448,7 +7865,7 @@ var viteMarkdownExportPlugin = () => {
7448
7865
  if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
7449
7866
  return;
7450
7867
  }
7451
- const distDir = path17.join(
7868
+ const distDir = path18.join(
7452
7869
  config2.__meta.rootDir,
7453
7870
  "dist",
7454
7871
  config2.basePath ?? ""
@@ -7469,15 +7886,15 @@ var viteMarkdownExportPlugin = () => {
7469
7886
  content: finalMarkdown
7470
7887
  });
7471
7888
  const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
7472
- const outputPath = `${path17.join(distDir, ...segments)}.md`;
7473
- await mkdir2(path17.dirname(outputPath), { recursive: true });
7889
+ const outputPath = `${path18.join(distDir, ...segments)}.md`;
7890
+ await mkdir2(path18.dirname(outputPath), { recursive: true });
7474
7891
  await writeFile2(outputPath, finalMarkdown, "utf-8");
7475
7892
  } catch (error) {
7476
7893
  console.warn(`Failed to export markdown for ${routePath}:`, error);
7477
7894
  }
7478
7895
  }
7479
7896
  if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
7480
- const markdownInfoPath = path17.join(
7897
+ const markdownInfoPath = path18.join(
7481
7898
  config2.__meta.rootDir,
7482
7899
  "node_modules/.apitogo/markdown-info.json"
7483
7900
  );
@@ -7629,9 +8046,9 @@ var remarkCodeTabs = () => (tree) => {
7629
8046
  };
7630
8047
 
7631
8048
  // src/vite/mdx/remark-inject-filepath.ts
7632
- import path18 from "node:path";
8049
+ import path19 from "node:path";
7633
8050
  var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
7634
- const relativePath = path18.relative(rootDir, vfile.path).split(path18.sep).join(path18.posix.sep);
8051
+ const relativePath = path19.relative(rootDir, vfile.path).split(path19.sep).join(path19.posix.sep);
7635
8052
  tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
7636
8053
  };
7637
8054
 
@@ -7718,18 +8135,18 @@ var remarkLastModified = () => {
7718
8135
  };
7719
8136
 
7720
8137
  // src/vite/mdx/remark-link-rewrite.ts
7721
- import path19 from "node:path";
8138
+ import path20 from "node:path";
7722
8139
  import { visit as visit5 } from "unist-util-visit";
7723
8140
  var remarkLinkRewrite = (basePath = "") => (tree) => {
7724
8141
  visit5(tree, "link", (node) => {
7725
8142
  if (!node.url) return;
7726
8143
  if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
7727
8144
  node.url = node.url.replace(/\\/g, "/");
7728
- const base = path19.posix.join(basePath);
8145
+ const base = path20.posix.join(basePath);
7729
8146
  if (basePath && node.url.startsWith(base)) {
7730
8147
  node.url = node.url.slice(base.length);
7731
8148
  } else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
7732
- node.url = path19.posix.join("..", node.url);
8149
+ node.url = path20.posix.join("..", node.url);
7733
8150
  }
7734
8151
  node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
7735
8152
  });
@@ -7949,11 +8366,11 @@ var plugin_mdx_default = viteMdxPlugin;
7949
8366
 
7950
8367
  // src/vite/plugin-modules.ts
7951
8368
  init_loader();
7952
- import path20 from "node:path";
8369
+ import path21 from "node:path";
7953
8370
  import { normalizePath as normalizePath2 } from "vite";
7954
- var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
7955
- var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path20.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
7956
- var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path20.resolve(rootDir, pagePath));
8371
+ var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path21.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
8372
+ var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path21.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
8373
+ var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path21.resolve(rootDir, pagePath));
7957
8374
  var viteModulesPlugin = () => {
7958
8375
  const virtualModuleId4 = "virtual:zudoku-modules-plugin";
7959
8376
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -8074,7 +8491,7 @@ var plugin_modules_default = viteModulesPlugin;
8074
8491
 
8075
8492
  // src/vite/plugin-search.ts
8076
8493
  init_loader();
8077
- import path21 from "node:path";
8494
+ import path22 from "node:path";
8078
8495
  var viteSearchPlugin = () => {
8079
8496
  const virtualModuleId4 = "virtual:zudoku-search-plugin";
8080
8497
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -8092,7 +8509,7 @@ var viteSearchPlugin = () => {
8092
8509
  return resolvedVirtualModuleId5;
8093
8510
  }
8094
8511
  if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
8095
- return path21.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
8512
+ return path22.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
8096
8513
  }
8097
8514
  },
8098
8515
  async load(id) {
@@ -8234,10 +8651,10 @@ function vitePlugin() {
8234
8651
  var resolveMergedPublicDir = (rootDir, merged) => {
8235
8652
  if (merged.publicDir === false) return void 0;
8236
8653
  const rel = typeof merged.publicDir === "string" ? merged.publicDir : "public";
8237
- return path22.resolve(rootDir, rel);
8654
+ return path23.resolve(rootDir, rel);
8238
8655
  };
8239
- var getAppClientEntryPath = () => path22.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
8240
- var getAppServerEntryPath = () => path22.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
8656
+ var getAppClientEntryPath = () => path23.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
8657
+ var getAppServerEntryPath = () => path23.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
8241
8658
  var hasLoggedCdnInfo = false;
8242
8659
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
8243
8660
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -8267,7 +8684,7 @@ async function getViteConfig(dir, configEnv) {
8267
8684
  );
8268
8685
  if (ZuploEnv.isZuplo) {
8269
8686
  dotenv.config({
8270
- path: path22.resolve(config2.__meta.rootDir, "../.env.zuplo"),
8687
+ path: path23.resolve(config2.__meta.rootDir, "../.env.zuplo"),
8271
8688
  quiet: true
8272
8689
  });
8273
8690
  }
@@ -8326,8 +8743,8 @@ async function getViteConfig(dir, configEnv) {
8326
8743
  ssr: configEnv.isSsrBuild,
8327
8744
  sourcemap: true,
8328
8745
  target: "es2022",
8329
- outDir: path22.resolve(
8330
- path22.join(
8746
+ outDir: path23.resolve(
8747
+ path23.join(
8331
8748
  dir,
8332
8749
  "dist",
8333
8750
  config2.basePath ?? "",
@@ -8346,7 +8763,7 @@ async function getViteConfig(dir, configEnv) {
8346
8763
  },
8347
8764
  experimental: {
8348
8765
  renderBuiltUrl(filename) {
8349
- if (cdnUrl?.base && [".js", ".css"].includes(path22.extname(filename))) {
8766
+ if (cdnUrl?.base && [".js", ".css"].includes(path23.extname(filename))) {
8350
8767
  return joinUrl(cdnUrl.base, filename);
8351
8768
  }
8352
8769
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -8359,7 +8776,7 @@ async function getViteConfig(dir, configEnv) {
8359
8776
  esbuildOptions: {
8360
8777
  target: "es2022"
8361
8778
  },
8362
- entries: [path22.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
8779
+ entries: [path23.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
8363
8780
  exclude: [
8364
8781
  "@lukoweb/apitogo",
8365
8782
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -8465,7 +8882,7 @@ init_package_json();
8465
8882
  init_joinUrl();
8466
8883
  import assert from "node:assert";
8467
8884
  import { cp, mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
8468
- import path23 from "node:path";
8885
+ import path24 from "node:path";
8469
8886
  var pkgJson = getZudokuPackageJson();
8470
8887
  function generateOutput({
8471
8888
  config: config2,
@@ -8522,9 +8939,9 @@ async function writeOutput(dir, {
8522
8939
  rewrites
8523
8940
  }) {
8524
8941
  const output = generateOutput({ config: config2, redirects, rewrites });
8525
- const outputDir = process.env.VERCEL ? path23.join(dir, ".vercel/output") : path23.join(dir, "dist/.output");
8942
+ const outputDir = process.env.VERCEL ? path24.join(dir, ".vercel/output") : path24.join(dir, "dist/.output");
8526
8943
  await mkdir3(outputDir, { recursive: true });
8527
- const outputFile = path23.join(outputDir, "config.json");
8944
+ const outputFile = path24.join(outputDir, "config.json");
8528
8945
  await writeFile3(outputFile, JSON.stringify(output, null, 2), "utf-8");
8529
8946
  if (process.env.VERCEL) {
8530
8947
  console.log("Wrote Vercel output to", outputDir);
@@ -8534,9 +8951,9 @@ async function writeOutput(dir, {
8534
8951
  // src/vite/prerender/prerender.ts
8535
8952
  init_logger();
8536
8953
  init_file_exists();
8537
- import { readFile as readFile3, rm } from "node:fs/promises";
8954
+ import { readFile as readFile2, rm } from "node:fs/promises";
8538
8955
  import os from "node:os";
8539
- import path26 from "node:path";
8956
+ import path27 from "node:path";
8540
8957
  import { pathToFileURL } from "node:url";
8541
8958
  import { createIndex } from "pagefind";
8542
8959
  import colors7 from "picocolors";
@@ -8576,9 +8993,9 @@ function throttle(fn) {
8576
8993
 
8577
8994
  // src/vite/sitemap.ts
8578
8995
  init_joinUrl();
8579
- import { createWriteStream, existsSync } from "node:fs";
8996
+ import { createWriteStream, existsSync as existsSync2 } from "node:fs";
8580
8997
  import { mkdir as mkdir4 } from "node:fs/promises";
8581
- import path24 from "node:path";
8998
+ import path25 from "node:path";
8582
8999
  import colors5 from "picocolors";
8583
9000
  import { SitemapStream } from "sitemap";
8584
9001
  async function generateSitemap({
@@ -8592,11 +9009,11 @@ async function generateSitemap({
8592
9009
  return;
8593
9010
  }
8594
9011
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
8595
- const outputDir = path24.resolve(baseOutputDir, config2.outDir ?? "");
8596
- if (!existsSync(outputDir)) {
9012
+ const outputDir = path25.resolve(baseOutputDir, config2.outDir ?? "");
9013
+ if (!existsSync2(outputDir)) {
8597
9014
  await mkdir4(outputDir, { recursive: true });
8598
9015
  }
8599
- const sitemapOutputPath = path24.join(outputDir, "sitemap.xml");
9016
+ const sitemapOutputPath = path25.join(outputDir, "sitemap.xml");
8600
9017
  const writeStream = createWriteStream(sitemapOutputPath);
8601
9018
  sitemap.pipe(writeStream);
8602
9019
  let lastmod;
@@ -8626,14 +9043,14 @@ async function generateSitemap({
8626
9043
 
8627
9044
  // src/vite/prerender/utils.ts
8628
9045
  init_joinUrl();
8629
- var resolveRoutePath = (path38) => {
8630
- const segments = path38.split("/");
9046
+ var resolveRoutePath = (path39) => {
9047
+ const segments = path39.split("/");
8631
9048
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
8632
9049
  return void 0;
8633
9050
  }
8634
9051
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
8635
9052
  };
8636
- var isSkipped = (path38) => path38.includes("*") || /^\d+$/.test(path38);
9053
+ var isSkipped = (path39) => path39.includes("*") || /^\d+$/.test(path39);
8637
9054
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
8638
9055
  if (route.path && isSkipped(route.path)) return [];
8639
9056
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -8682,12 +9099,12 @@ var prerender = async ({
8682
9099
  serverConfigFilename,
8683
9100
  writeRedirects = true
8684
9101
  }) => {
8685
- const distDir = path26.join(dir, "dist", basePath);
9102
+ const distDir = path27.join(dir, "dist", basePath);
8686
9103
  const serverConfigPath = pathToFileURL(
8687
- path26.join(distDir, "server", serverConfigFilename)
9104
+ path27.join(distDir, "server", serverConfigFilename)
8688
9105
  ).href;
8689
9106
  const entryServerPath = pathToFileURL(
8690
- path26.join(distDir, "server/entry.server.js")
9107
+ path27.join(distDir, "server/entry.server.js")
8691
9108
  ).href;
8692
9109
  const rawConfig = await import(serverConfigPath).then(
8693
9110
  (m) => m.default
@@ -8772,7 +9189,7 @@ var prerender = async ({
8772
9189
  })
8773
9190
  );
8774
9191
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
8775
- outputPath: path26.join(distDir, "pagefind")
9192
+ outputPath: path27.join(distDir, "pagefind")
8776
9193
  });
8777
9194
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
8778
9195
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
@@ -8804,13 +9221,13 @@ var prerender = async ({
8804
9221
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
8805
9222
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
8806
9223
  const llmsConfig = docsConfig.llms ?? {};
8807
- const markdownInfoPath = path26.join(
9224
+ const markdownInfoPath = path27.join(
8808
9225
  dir,
8809
9226
  "node_modules/.apitogo/markdown-info.json"
8810
9227
  );
8811
9228
  let markdownFileInfos = [];
8812
9229
  if (await fileExists(markdownInfoPath)) {
8813
- const markdownInfoContent = await readFile3(markdownInfoPath, "utf-8");
9230
+ const markdownInfoContent = await readFile2(markdownInfoPath, "utf-8");
8814
9231
  markdownFileInfos = JSON.parse(markdownInfoContent);
8815
9232
  }
8816
9233
  if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
@@ -8895,7 +9312,7 @@ async function runBuild(options) {
8895
9312
  html,
8896
9313
  basePath: config2.basePath
8897
9314
  });
8898
- await rm2(path27.join(clientOutDir, "index.html"), { force: true });
9315
+ await rm2(path28.join(clientOutDir, "index.html"), { force: true });
8899
9316
  } else {
8900
9317
  await runPrerender({
8901
9318
  dir,
@@ -8919,7 +9336,7 @@ var runPrerender = async (options) => {
8919
9336
  serverConfigFilename,
8920
9337
  writeRedirects: process.env.VERCEL === void 0
8921
9338
  });
8922
- const indexHtml = path27.join(clientOutDir, "index.html");
9339
+ const indexHtml = path28.join(clientOutDir, "index.html");
8923
9340
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
8924
9341
  await writeFile5(indexHtml, html, "utf-8");
8925
9342
  }
@@ -8929,15 +9346,15 @@ var runPrerender = async (options) => {
8929
9346
  for (const statusPage of statusPages) {
8930
9347
  await rename(
8931
9348
  statusPage,
8932
- path27.join(dir, DIST_DIR, path27.basename(statusPage))
9349
+ path28.join(dir, DIST_DIR, path28.basename(statusPage))
8933
9350
  );
8934
9351
  }
8935
9352
  await rm2(serverOutDir, { recursive: true, force: true });
8936
9353
  if (process.env.VERCEL) {
8937
- await mkdir5(path27.join(dir, ".vercel/output/static"), { recursive: true });
9354
+ await mkdir5(path28.join(dir, ".vercel/output/static"), { recursive: true });
8938
9355
  await rename(
8939
- path27.join(dir, DIST_DIR),
8940
- path27.join(dir, ".vercel/output/static")
9356
+ path28.join(dir, DIST_DIR),
9357
+ path28.join(dir, ".vercel/output/static")
8941
9358
  );
8942
9359
  }
8943
9360
  await writeOutput(dir, {
@@ -8947,7 +9364,7 @@ var runPrerender = async (options) => {
8947
9364
  });
8948
9365
  if (ZuploEnv.isZuplo && issuer) {
8949
9366
  await writeFile5(
8950
- path27.join(dir, DIST_DIR, ".output/zuplo.json"),
9367
+ path28.join(dir, DIST_DIR, ".output/zuplo.json"),
8951
9368
  JSON.stringify({ issuer }, null, 2),
8952
9369
  "utf-8"
8953
9370
  );
@@ -8959,10 +9376,10 @@ var runPrerender = async (options) => {
8959
9376
  };
8960
9377
  var bundleSSREntry = async (options) => {
8961
9378
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
8962
- const tempEntryPath = path27.join(dir, "__ssr-entry.ts");
9379
+ const tempEntryPath = path28.join(dir, "__ssr-entry.ts");
8963
9380
  const packageRoot = getZudokuRootDir();
8964
- const templateContent = await readFile4(
8965
- path27.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
9381
+ const templateContent = await readFile3(
9382
+ path28.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
8966
9383
  "utf-8"
8967
9384
  );
8968
9385
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
@@ -8977,9 +9394,9 @@ var bundleSSREntry = async (options) => {
8977
9394
  platform: adapter === "node" ? "node" : "neutral",
8978
9395
  target: "es2022",
8979
9396
  format: "esm",
8980
- outfile: path27.join(serverOutDir, "entry.js"),
9397
+ outfile: path28.join(serverOutDir, "entry.js"),
8981
9398
  external: ["./entry.server.js", `./${serverConfigFilename}`],
8982
- nodePaths: [path27.join(packageRoot, "node_modules")],
9399
+ nodePaths: [path28.join(packageRoot, "node_modules")],
8983
9400
  banner: { js: "// Bundled SSR entry" }
8984
9401
  });
8985
9402
  } finally {
@@ -9034,11 +9451,11 @@ function textOrJson(text) {
9034
9451
  init_package_json();
9035
9452
 
9036
9453
  // src/cli/preview/handler.ts
9037
- import path28 from "node:path";
9454
+ import path29 from "node:path";
9038
9455
  import { preview as vitePreview } from "vite";
9039
9456
  var DEFAULT_PREVIEW_PORT = 4e3;
9040
9457
  async function preview(argv) {
9041
- const dir = path28.resolve(process.cwd(), argv.dir);
9458
+ const dir = path29.resolve(process.cwd(), argv.dir);
9042
9459
  const viteConfig = await getViteConfig(dir, {
9043
9460
  command: "serve",
9044
9461
  mode: "production",
@@ -9079,7 +9496,7 @@ async function build(argv) {
9079
9496
  printDiagnosticsToConsole("");
9080
9497
  printDiagnosticsToConsole("");
9081
9498
  }
9082
- const dir = path29.resolve(process.cwd(), argv.dir);
9499
+ const dir = path30.resolve(process.cwd(), argv.dir);
9083
9500
  try {
9084
9501
  await runBuild({
9085
9502
  dir,
@@ -9238,8 +9655,8 @@ var build_default = {
9238
9655
 
9239
9656
  // src/cli/configure-github-workflow/handler.ts
9240
9657
  import { constants } from "node:fs";
9241
- import { access as access2, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
9242
- import path30 from "node:path";
9658
+ import { access, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
9659
+ import path31 from "node:path";
9243
9660
  var APITOGO_DEPLOY_WORKFLOW_YAML = `name: Build and Deploy
9244
9661
 
9245
9662
  on:
@@ -9350,12 +9767,12 @@ jobs:
9350
9767
  run: apitogo deploy --deployment-token="$APITOGO_TOKEN" --json-only
9351
9768
  `;
9352
9769
  async function configureGithubWorkflow(argv) {
9353
- const dir = path30.resolve(process.cwd(), argv.dir);
9354
- const workflowDir = path30.join(dir, ".github", "workflows");
9355
- const workflowPath = path30.join(workflowDir, "apitogo-deploy.yml");
9770
+ const dir = path31.resolve(process.cwd(), argv.dir);
9771
+ const workflowDir = path31.join(dir, ".github", "workflows");
9772
+ const workflowPath = path31.join(workflowDir, "apitogo-deploy.yml");
9356
9773
  try {
9357
9774
  try {
9358
- await access2(workflowPath, constants.F_OK);
9775
+ await access(workflowPath, constants.F_OK);
9359
9776
  if (!argv.force) {
9360
9777
  await printCriticalFailureToConsoleAndExit(
9361
9778
  `Workflow file already exists: ${workflowPath}. Pass --force to overwrite.`
@@ -9424,15 +9841,15 @@ function applyJsonOnlyDeployQuietMode() {
9424
9841
  }
9425
9842
 
9426
9843
  // src/cli/deploy/handler.ts
9427
- import { access as access3, readFile as readFile5 } from "node:fs/promises";
9428
- import path31 from "node:path";
9844
+ import { access as access2, readFile as readFile4 } from "node:fs/promises";
9845
+ import path32 from "node:path";
9429
9846
  import { create as createTar } from "tar";
9430
9847
  var DEPLOY_ENDPOINT = "https://deploy-server-dotnet2-b3fkcaaraydbckfe.canadacentral-01.azurewebsites.net/deploy";
9431
9848
  var ARCHIVE_NAME = "dist.tgz";
9432
9849
  var createDeploymentArchive = async (dir) => {
9433
- const distDir = path31.join(dir, "dist");
9434
- await access3(distDir);
9435
- const archivePath = path31.join(dir, ARCHIVE_NAME);
9850
+ const distDir = path32.join(dir, "dist");
9851
+ await access2(distDir);
9852
+ const archivePath = path32.join(dir, ARCHIVE_NAME);
9436
9853
  await createTar(
9437
9854
  {
9438
9855
  cwd: dir,
@@ -9446,7 +9863,7 @@ var createDeploymentArchive = async (dir) => {
9446
9863
  };
9447
9864
  async function deploy(argv) {
9448
9865
  await build({ ...argv, preview: void 0 });
9449
- const dir = path31.resolve(process.cwd(), argv.dir);
9866
+ const dir = path32.resolve(process.cwd(), argv.dir);
9450
9867
  const deploymentToken = argv.deploymentToken?.trim() || process.env.npm_config_deployment_token?.trim();
9451
9868
  const env = argv.env?.trim() || process.env.npm_config_env?.trim() || "production";
9452
9869
  try {
@@ -9459,15 +9876,15 @@ async function deploy(argv) {
9459
9876
  const archivePath = await createDeploymentArchive(dir);
9460
9877
  if (!isJsonOnlyDeployEnv()) {
9461
9878
  printDiagnosticsToConsole(
9462
- `Uploading ${path31.basename(archivePath)} to ${env}...`
9879
+ `Uploading ${path32.basename(archivePath)} to ${env}...`
9463
9880
  );
9464
9881
  }
9465
- const archiveBuffer = await readFile5(archivePath);
9882
+ const archiveBuffer = await readFile4(archivePath);
9466
9883
  const formData = new FormData();
9467
9884
  formData.append(
9468
9885
  "file",
9469
9886
  new Blob([archiveBuffer], { type: "application/gzip" }),
9470
- path31.basename(archivePath)
9887
+ path32.basename(archivePath)
9471
9888
  );
9472
9889
  formData.append("deploymentToken", deploymentToken);
9473
9890
  formData.append("env", env);
@@ -9552,14 +9969,14 @@ var deploy_default = {
9552
9969
 
9553
9970
  // src/cli/dev/handler.ts
9554
9971
  init_joinUrl();
9555
- import path34 from "node:path";
9972
+ import path35 from "node:path";
9556
9973
 
9557
9974
  // src/vite/dev-server.ts
9558
9975
  init_logger();
9559
9976
  import fs4 from "node:fs/promises";
9560
9977
  import http from "node:http";
9561
9978
  import https from "node:https";
9562
- import path33 from "node:path";
9979
+ import path34 from "node:path";
9563
9980
  import { createHttpTerminator } from "http-terminator";
9564
9981
  import {
9565
9982
  createServer as createViteServer,
@@ -9592,7 +10009,7 @@ init_loader();
9592
10009
  // src/vite/pagefind-dev-index.ts
9593
10010
  init_invariant();
9594
10011
  init_joinUrl();
9595
- import path32 from "node:path";
10012
+ import path33 from "node:path";
9596
10013
  import { createIndex as createIndex2 } from "pagefind";
9597
10014
  import { isRunnableDevEnvironment } from "vite";
9598
10015
  async function* buildPagefindDevIndex(vite, config2) {
@@ -9645,7 +10062,7 @@ async function* buildPagefindDevIndex(vite, config2) {
9645
10062
  path: urlPath
9646
10063
  };
9647
10064
  }
9648
- const outputPath = path32.join(vite.config.publicDir, "pagefind");
10065
+ const outputPath = path33.join(vite.config.publicDir, "pagefind");
9649
10066
  await pagefindIndex.writeFiles({ outputPath });
9650
10067
  yield { type: "complete", success: true, indexed };
9651
10068
  }
@@ -9664,9 +10081,9 @@ var DevServer = class {
9664
10081
  this.protocol = "https";
9665
10082
  const { dir } = this.options;
9666
10083
  const [key, cert, ca] = await Promise.all([
9667
- fs4.readFile(path33.resolve(dir, config2.https.key)),
9668
- fs4.readFile(path33.resolve(dir, config2.https.cert)),
9669
- config2.https.ca ? fs4.readFile(path33.resolve(dir, config2.https.ca)) : void 0
10084
+ fs4.readFile(path34.resolve(dir, config2.https.key)),
10085
+ fs4.readFile(path34.resolve(dir, config2.https.cert)),
10086
+ config2.https.ca ? fs4.readFile(path34.resolve(dir, config2.https.ca)) : void 0
9670
10087
  ]);
9671
10088
  return https.createServer({ key, cert, ca });
9672
10089
  }
@@ -9683,7 +10100,7 @@ var DevServer = class {
9683
10100
  );
9684
10101
  const server = await this.createNodeServer(config2);
9685
10102
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
9686
- const publicRoot = path33.resolve(
10103
+ const publicRoot = path34.resolve(
9687
10104
  this.options.dir,
9688
10105
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
9689
10106
  );
@@ -9700,7 +10117,7 @@ var DevServer = class {
9700
10117
  // built-in transform middleware which would treat the path as a static asset.
9701
10118
  name: "apitogo:entry-client",
9702
10119
  configureServer(server2) {
9703
- const entryPath = path33.posix.join(
10120
+ const entryPath = path34.posix.join(
9704
10121
  server2.config.base,
9705
10122
  "/__z/entry.client.tsx"
9706
10123
  );
@@ -9865,7 +10282,7 @@ init_package_json();
9865
10282
  async function dev(argv) {
9866
10283
  const packageJson2 = getZudokuPackageJson();
9867
10284
  process.env.NODE_ENV = "development";
9868
- const dir = path34.resolve(process.cwd(), argv.dir);
10285
+ const dir = path35.resolve(process.cwd(), argv.dir);
9869
10286
  const server = new DevServer({
9870
10287
  dir,
9871
10288
  argPort: argv.port,
@@ -9949,15 +10366,15 @@ var dev_default = {
9949
10366
 
9950
10367
  // src/cli/make-config/handler.ts
9951
10368
  import { constants as constants3 } from "node:fs";
9952
- import { access as access5, mkdir as mkdir7, readFile as readFile7, writeFile as writeFile8 } from "node:fs/promises";
9953
- import path36 from "node:path";
10369
+ import { access as access4, mkdir as mkdir7, readFile as readFile6, writeFile as writeFile8 } from "node:fs/promises";
10370
+ import path37 from "node:path";
9954
10371
  import { glob as glob5 } from "glob";
9955
10372
 
9956
10373
  // src/cli/make-config/scaffold-project.ts
9957
10374
  init_package_json();
9958
10375
  import { constants as constants2 } from "node:fs";
9959
- import { access as access4, readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
9960
- import path35 from "node:path";
10376
+ import { access as access3, readFile as readFile5, writeFile as writeFile7 } from "node:fs/promises";
10377
+ import path36 from "node:path";
9961
10378
  import { glob as glob4 } from "glob";
9962
10379
  var OPENAPI_GLOBS = [
9963
10380
  "apis/openapi.json",
@@ -10017,9 +10434,9 @@ var findMatchingCurly = (source, startIndex) => {
10017
10434
  }
10018
10435
  throw new Error("Could not find matching closing brace for object.");
10019
10436
  };
10020
- var toPosix = (p) => p.split(path35.sep).join("/");
10437
+ var toPosix = (p) => p.split(path36.sep).join("/");
10021
10438
  var sanitizePackageName = (dir) => {
10022
- const base = path35.basename(path35.resolve(dir));
10439
+ const base = path36.basename(path36.resolve(dir));
10023
10440
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
10024
10441
  return s || "apitogo-site";
10025
10442
  };
@@ -10029,9 +10446,9 @@ var apitogoVersionRange = () => {
10029
10446
  };
10030
10447
  async function findOpenApiSpecPath(dir) {
10031
10448
  for (const rel of OPENAPI_GLOBS) {
10032
- const full = path35.join(dir, rel);
10449
+ const full = path36.join(dir, rel);
10033
10450
  try {
10034
- await access4(full, constants2.R_OK);
10451
+ await access3(full, constants2.R_OK);
10035
10452
  return toPosix(rel);
10036
10453
  } catch {
10037
10454
  }
@@ -10044,7 +10461,7 @@ async function findOpenApiSpecPath(dir) {
10044
10461
  return extra[0] ? toPosix(extra[0]) : null;
10045
10462
  }
10046
10463
  async function ensurePackageJson(dir) {
10047
- const pkgPath = path35.join(dir, "package.json");
10464
+ const pkgPath = path36.join(dir, "package.json");
10048
10465
  const apitogoVer = apitogoVersionRange();
10049
10466
  const baseDeps = {
10050
10467
  react: ">=19.0.0",
@@ -10057,7 +10474,7 @@ async function ensurePackageJson(dir) {
10057
10474
  preview: "apitogo preview"
10058
10475
  };
10059
10476
  try {
10060
- await access4(pkgPath, constants2.R_OK);
10477
+ await access3(pkgPath, constants2.R_OK);
10061
10478
  } catch (err) {
10062
10479
  const code = err.code;
10063
10480
  if (code !== "ENOENT") throw err;
@@ -10079,7 +10496,7 @@ async function ensurePackageJson(dir) {
10079
10496
  `, "utf8");
10080
10497
  return true;
10081
10498
  }
10082
- const raw = await readFile6(pkgPath, "utf8");
10499
+ const raw = await readFile5(pkgPath, "utf8");
10083
10500
  let pkg;
10084
10501
  try {
10085
10502
  pkg = JSON.parse(raw);
@@ -10107,9 +10524,9 @@ async function ensurePackageJson(dir) {
10107
10524
  return false;
10108
10525
  }
10109
10526
  async function ensureTsconfigJson(dir) {
10110
- const tsPath = path35.join(dir, "tsconfig.json");
10527
+ const tsPath = path36.join(dir, "tsconfig.json");
10111
10528
  try {
10112
- await access4(tsPath, constants2.R_OK);
10529
+ await access3(tsPath, constants2.R_OK);
10113
10530
  return false;
10114
10531
  } catch {
10115
10532
  const tsconfig = {
@@ -10189,7 +10606,7 @@ var CONFIG_FILENAMES = [
10189
10606
  ];
10190
10607
  var DEFAULT_NEW_CONFIG_FILENAME = "apitogo.config.tsx";
10191
10608
  var createTreeNode = () => ({ docs: [], children: /* @__PURE__ */ new Map() });
10192
- var toPosixPath2 = (value) => value.split(path36.sep).join(path36.posix.sep);
10609
+ var toPosixPath2 = (value) => value.split(path37.sep).join(path37.posix.sep);
10193
10610
  var toRoutePath = (relativeFile, pagesDir) => {
10194
10611
  const relativeNoExt = relativeFile.replace(/\.mdx?$/, "");
10195
10612
  const withoutPagesPrefix = relativeNoExt.replace(
@@ -10434,26 +10851,26 @@ export default config;
10434
10851
  `;
10435
10852
  };
10436
10853
  var ensureApitogoDeployWorkflow = async (dir) => {
10437
- const workflowPath = path36.join(
10854
+ const workflowPath = path37.join(
10438
10855
  dir,
10439
10856
  ".github",
10440
10857
  "workflows",
10441
10858
  "apitogo-deploy.yml"
10442
10859
  );
10443
10860
  try {
10444
- await access5(workflowPath, constants3.F_OK);
10861
+ await access4(workflowPath, constants3.F_OK);
10445
10862
  return false;
10446
10863
  } catch {
10447
10864
  }
10448
- await mkdir7(path36.join(dir, ".github", "workflows"), { recursive: true });
10865
+ await mkdir7(path37.join(dir, ".github", "workflows"), { recursive: true });
10449
10866
  await writeFile8(workflowPath, APITOGO_DEPLOY_WORKFLOW_YAML, "utf8");
10450
10867
  return true;
10451
10868
  };
10452
10869
  var findExistingConfigPath = async (dir) => {
10453
10870
  for (const filename of CONFIG_FILENAMES) {
10454
- const fullPath = path36.join(dir, filename);
10871
+ const fullPath = path37.join(dir, filename);
10455
10872
  try {
10456
- await readFile7(fullPath, "utf8");
10873
+ await readFile6(fullPath, "utf8");
10457
10874
  return fullPath;
10458
10875
  } catch {
10459
10876
  }
@@ -10461,7 +10878,7 @@ var findExistingConfigPath = async (dir) => {
10461
10878
  return null;
10462
10879
  };
10463
10880
  async function makeConfig(argv) {
10464
- const dir = path36.resolve(process.cwd(), argv.dir);
10881
+ const dir = path37.resolve(process.cwd(), argv.dir);
10465
10882
  const pagesDir = toPosixPath2(
10466
10883
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
10467
10884
  );
@@ -10480,7 +10897,7 @@ async function makeConfig(argv) {
10480
10897
  let configPath = await findExistingConfigPath(dir);
10481
10898
  let createdNew = false;
10482
10899
  if (!configPath) {
10483
- configPath = path36.join(dir, DEFAULT_NEW_CONFIG_FILENAME);
10900
+ configPath = path37.join(dir, DEFAULT_NEW_CONFIG_FILENAME);
10484
10901
  await writeFile8(
10485
10902
  configPath,
10486
10903
  buildNewConfigContents(pagesDir, openApiSpecPath),
@@ -10500,7 +10917,7 @@ async function makeConfig(argv) {
10500
10917
  if (routePaths.length === 0) {
10501
10918
  throw new Error(`No .md or .mdx files found under '${pagesDir}'.`);
10502
10919
  }
10503
- let originalConfig = await readFile7(configPath, "utf8");
10920
+ let originalConfig = await readFile6(configPath, "utf8");
10504
10921
  if (!createdNew && openApiSpecPath) {
10505
10922
  originalConfig = insertApisIfMissing(
10506
10923
  originalConfig,
@@ -10521,7 +10938,7 @@ async function makeConfig(argv) {
10521
10938
  await writeFile8(configPath, withRedirects, "utf8");
10522
10939
  const action = createdNew ? "Initialized" : "Updated";
10523
10940
  printResultToConsole(
10524
- `${action} ${path36.basename(configPath)} from ${pagesDir}/ (navigation and redirects; other top-level settings preserved unless newly scaffolded).`
10941
+ `${action} ${path37.basename(configPath)} from ${pagesDir}/ (navigation and redirects; other top-level settings preserved unless newly scaffolded).`
10525
10942
  );
10526
10943
  const createdWorkflow = await ensureApitogoDeployWorkflow(dir);
10527
10944
  if (createdWorkflow) {
@@ -10663,8 +11080,8 @@ var remove_default = {
10663
11080
  };
10664
11081
 
10665
11082
  // src/cli/common/outdated.ts
10666
- import { existsSync as existsSync2, mkdirSync } from "node:fs";
10667
- import { readFile as readFile8, writeFile as writeFile9 } from "node:fs/promises";
11083
+ import { existsSync as existsSync3, mkdirSync } from "node:fs";
11084
+ import { readFile as readFile7, writeFile as writeFile9 } from "node:fs/promises";
10668
11085
  import { join } from "node:path";
10669
11086
  import colors10 from "picocolors";
10670
11087
  import { gt } from "semver";
@@ -10714,12 +11131,12 @@ function box(message, {
10714
11131
 
10715
11132
  // src/cli/common/xdg/lib.ts
10716
11133
  import { homedir } from "node:os";
10717
- import path37 from "node:path";
11134
+ import path38 from "node:path";
10718
11135
  function defineDirectoryWithFallback(xdgName, fallback) {
10719
11136
  if (process.env[xdgName]) {
10720
11137
  return process.env[xdgName];
10721
11138
  } else {
10722
- return path37.join(homedir(), fallback);
11139
+ return path38.join(homedir(), fallback);
10723
11140
  }
10724
11141
  }
10725
11142
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -10734,15 +11151,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
10734
11151
  "XDG_DATA_HOME",
10735
11152
  ".local/state"
10736
11153
  );
10737
- var ZUDOKU_XDG_CONFIG_HOME = path37.join(
11154
+ var ZUDOKU_XDG_CONFIG_HOME = path38.join(
10738
11155
  XDG_CONFIG_HOME,
10739
11156
  CLI_XDG_FOLDER_NAME
10740
11157
  );
10741
- var ZUDOKU_XDG_DATA_HOME = path37.join(
11158
+ var ZUDOKU_XDG_DATA_HOME = path38.join(
10742
11159
  XDG_DATA_HOME,
10743
11160
  CLI_XDG_FOLDER_NAME
10744
11161
  );
10745
- var ZUDOKU_XDG_STATE_HOME = path37.join(
11162
+ var ZUDOKU_XDG_STATE_HOME = path38.join(
10746
11163
  XDG_STATE_HOME,
10747
11164
  CLI_XDG_FOLDER_NAME
10748
11165
  );
@@ -10787,14 +11204,14 @@ async function getLatestVersion() {
10787
11204
  return void 0;
10788
11205
  }
10789
11206
  async function getVersionCheckInfo() {
10790
- if (!existsSync2(ZUDOKU_XDG_STATE_HOME)) {
11207
+ if (!existsSync3(ZUDOKU_XDG_STATE_HOME)) {
10791
11208
  mkdirSync(ZUDOKU_XDG_STATE_HOME, { recursive: true });
10792
11209
  }
10793
11210
  const versionCheckPath = join(ZUDOKU_XDG_STATE_HOME, VERSION_CHECK_FILE);
10794
11211
  let versionCheckInfo;
10795
- if (existsSync2(versionCheckPath)) {
11212
+ if (existsSync3(versionCheckPath)) {
10796
11213
  try {
10797
- versionCheckInfo = await readFile8(versionCheckPath, "utf-8").then(
11214
+ versionCheckInfo = await readFile7(versionCheckPath, "utf-8").then(
10798
11215
  JSON.parse
10799
11216
  );
10800
11217
  } catch {