@lukoweb/apitogo 0.1.53 → 0.1.55

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 (47) hide show
  1. package/dist/cli/cli.js +686 -373
  2. package/dist/declarations/config/apitogo-config-core.d.ts +14 -4
  3. package/dist/declarations/config/landing-manifest.d.ts +76 -0
  4. package/dist/declarations/config/local-manifest.d.ts +91 -1
  5. package/dist/declarations/config/validators/ModulesSchema.d.ts +227 -0
  6. package/dist/declarations/config/validators/ZudokuConfig.d.ts +84 -2
  7. package/dist/declarations/lib/authentication/header-nav-filter.d.ts +4 -0
  8. package/dist/declarations/lib/authentication/providers/dev-portal-auth-pages.d.ts +15 -0
  9. package/dist/declarations/lib/authentication/providers/dev-portal-constants.d.ts +19 -1
  10. package/dist/declarations/lib/authentication/providers/dev-portal-utils.d.ts +5 -1
  11. package/dist/declarations/lib/authentication/providers/dev-portal.d.ts +5 -0
  12. package/dist/declarations/lib/components/HeaderAuthActions.d.ts +3 -0
  13. package/dist/declarations/lib/components/SiteTitle.d.ts +6 -0
  14. package/dist/declarations/lib/components/ThemeSwitch.d.ts +3 -1
  15. package/dist/declarations/lib/components/TopNavigation.d.ts +1 -1
  16. package/dist/declarations/lib/core/ZudokuContext.d.ts +1 -0
  17. package/dist/flat-config.d.ts +61 -1
  18. package/package.json +1 -1
  19. package/src/app/main.css +2 -2
  20. package/src/config/apitogo-config-core.ts +140 -11
  21. package/src/config/apitogo-config-loader.browser.ts +17 -0
  22. package/src/config/apitogo-config-loader.node.ts +28 -8
  23. package/src/config/build-apitogo-config.ts +13 -4
  24. package/src/config/landing-manifest.ts +11 -0
  25. package/src/config/landing-openapi-showcase.ts +115 -0
  26. package/src/config/loader.ts +17 -3
  27. package/src/config/local-manifest.ts +146 -11
  28. package/src/config/resolve-modules.ts +22 -1
  29. package/src/config/validators/ModulesSchema.ts +84 -0
  30. package/src/config/validators/ZudokuConfig.ts +26 -1
  31. package/src/lib/authentication/auth-header-nav.ts +5 -15
  32. package/src/lib/authentication/header-nav-filter.ts +36 -0
  33. package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +499 -0
  34. package/src/lib/authentication/providers/dev-portal-constants.ts +15 -1
  35. package/src/lib/authentication/providers/dev-portal-utils.ts +128 -3
  36. package/src/lib/authentication/providers/dev-portal.tsx +51 -6
  37. package/src/lib/components/Header.tsx +49 -39
  38. package/src/lib/components/HeaderAuthActions.tsx +36 -0
  39. package/src/lib/components/HeaderNavigation.tsx +11 -9
  40. package/src/lib/components/MobileTopNavigation.tsx +43 -24
  41. package/src/lib/components/SiteTitle.tsx +20 -0
  42. package/src/lib/components/ThemeSwitch.tsx +36 -2
  43. package/src/lib/components/TopNavigation.tsx +20 -33
  44. package/src/lib/core/ZudokuContext.ts +1 -0
  45. package/src/vite/config.ts +21 -0
  46. package/src/vite/plugin-auth.ts +4 -1
  47. package/src/vite/plugin-config.ts +39 -4
package/dist/cli/cli.js CHANGED
@@ -64,39 +64,25 @@ function applyAuthenticationHeaderNav(config2) {
64
64
  }
65
65
  const authNavEnabled = config2.__meta?.authenticationEnabled === true;
66
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
- };
67
+ if (authNavEnabled) {
68
+ return config2;
79
69
  }
80
- if (navigation.some((item) => "to" in item && item.to === LOGIN_NAV_PATH)) {
70
+ const filtered = withoutLoginNavigation(navigation);
71
+ if (filtered.length === navigation.length) {
81
72
  return config2;
82
73
  }
83
74
  return {
84
75
  ...config2,
85
76
  header: {
86
77
  ...config2.header,
87
- navigation: [...navigation, LOGIN_HEADER_NAV_ITEM]
78
+ navigation: filtered
88
79
  }
89
80
  };
90
81
  }
91
- var LOGIN_NAV_PATH, LOGIN_HEADER_NAV_ITEM;
82
+ var LOGIN_NAV_PATH;
92
83
  var init_auth_header_nav = __esm({
93
84
  "src/lib/authentication/auth-header-nav.ts"() {
94
85
  LOGIN_NAV_PATH = "/signin";
95
- LOGIN_HEADER_NAV_ITEM = {
96
- label: "Login",
97
- to: LOGIN_NAV_PATH,
98
- display: "anon"
99
- };
100
86
  }
101
87
  });
102
88
 
@@ -393,6 +379,7 @@ function normalizeApitogoConfig(config2) {
393
379
  delete normalized.projectName;
394
380
  migratePlanCatalog(normalized);
395
381
  syncBillingEnabled(normalized);
382
+ syncAuthentication(normalized);
396
383
  return normalized;
397
384
  }
398
385
  function isBillingEnabled(config2) {
@@ -402,6 +389,63 @@ function isBillingEnabled(config2) {
402
389
  );
403
390
  return plans?.enabled === true;
404
391
  }
392
+ function isUserPanelEnabled(normalized) {
393
+ const modules = asRecord(normalized.modules);
394
+ const userPanel = asRecord(modules?.userPanel);
395
+ if (userPanel?.enabled === true) {
396
+ return true;
397
+ }
398
+ const dashboard = asRecord(userPanel?.dashboard);
399
+ const userManagement = asRecord(userPanel?.userManagement);
400
+ const apiKeys = asRecord(userPanel?.apiKeys);
401
+ const plans = asRecord(userPanel?.plans);
402
+ return dashboard?.enabled === true || userManagement?.enabled === true || apiKeys?.enabled === true || plans?.enabled === true;
403
+ }
404
+ function syncAuthentication(normalized) {
405
+ const userPanelEnabled = isUserPanelEnabled(normalized);
406
+ const authentication = asRecord(normalized.authentication);
407
+ if (!userPanelEnabled && !authentication) {
408
+ return;
409
+ }
410
+ const auth = authentication ?? {};
411
+ auth.enabled = userPanelEnabled;
412
+ auth.type = "dev-portal";
413
+ if (userPanelEnabled) {
414
+ const native = asRecord(auth.native) ?? {};
415
+ if (native.enabled === void 0) {
416
+ native.enabled = true;
417
+ }
418
+ auth.native = native;
419
+ if (!Array.isArray(auth.providers)) {
420
+ auth.providers = [];
421
+ }
422
+ }
423
+ normalized.authentication = auth;
424
+ }
425
+ function stripAuthenticationSecrets(authentication) {
426
+ const {
427
+ gateway: _gateway,
428
+ oidc: _oidc,
429
+ stripe: _stripe,
430
+ type: _type,
431
+ email,
432
+ providers,
433
+ ...authPublic
434
+ } = authentication;
435
+ const emailRecord = asRecord(email);
436
+ if (emailRecord) {
437
+ const { connectionString: _connectionString, ...emailPublic } = emailRecord;
438
+ authPublic.email = emailPublic;
439
+ }
440
+ if (Array.isArray(providers)) {
441
+ authPublic.providers = providers.map((entry) => {
442
+ const provider = asRecord(entry) ?? {};
443
+ const { clientSecret: _clientSecret, ...providerPublic } = provider;
444
+ return providerPublic;
445
+ });
446
+ }
447
+ return authPublic;
448
+ }
405
449
  function syncBillingEnabled(normalized) {
406
450
  const legacyPricing = asRecord(normalized.pricing);
407
451
  const modules = ensureModules(normalized);
@@ -430,13 +474,7 @@ function deriveManifestFields(config2) {
430
474
  if (key === "authentication") {
431
475
  const authentication2 = asRecord(normalized.authentication);
432
476
  if (authentication2) {
433
- const {
434
- gateway: _gateway,
435
- oidc: _oidc,
436
- stripe: _stripe,
437
- ...authPublic
438
- } = authentication2;
439
- manifest.authentication = authPublic;
477
+ manifest.authentication = stripAuthenticationSecrets(authentication2);
440
478
  }
441
479
  continue;
442
480
  }
@@ -456,6 +494,17 @@ function deriveManifestFields(config2) {
456
494
  }
457
495
  continue;
458
496
  }
497
+ if (key === "landing") {
498
+ const modules = asRecord(normalized.modules);
499
+ const landing = asRecord(modules?.landing);
500
+ if (landing?.content || landing?.enabled !== void 0) {
501
+ manifest.landing = {
502
+ enabled: typeof landing.enabled === "boolean" ? landing.enabled : void 0,
503
+ content: landing.content
504
+ };
505
+ }
506
+ continue;
507
+ }
459
508
  if (normalized[key] !== void 0) {
460
509
  manifest[key] = normalized[key];
461
510
  }
@@ -473,7 +522,28 @@ function extractManifest(config2) {
473
522
  const manifest = deriveManifestFields(config2);
474
523
  return Object.keys(manifest).length > 0 ? manifest : null;
475
524
  }
476
- var APITOGO_CONFIG_FILENAME, ENV_PREFIX, DERIVED_MANIFEST_KEYS;
525
+ function extractSiteConfig(config2) {
526
+ if (!config2 || typeof config2 !== "object") {
527
+ return {};
528
+ }
529
+ const normalized = normalizeApitogoConfig(config2);
530
+ const siteConfig = {};
531
+ for (const key of SITE_CONFIG_KEYS) {
532
+ if (normalized[key] !== void 0) {
533
+ siteConfig[key] = normalized[key];
534
+ }
535
+ }
536
+ if (normalized.authentication !== void 0) {
537
+ siteConfig.authentication = normalized.authentication;
538
+ }
539
+ const modulesDocs = asRecord(asRecord(normalized.modules)?.docs);
540
+ if (modulesDocs) {
541
+ const { enabled: _enabled, ...docsConfig } = modulesDocs;
542
+ siteConfig.docs = docsConfig;
543
+ }
544
+ return siteConfig;
545
+ }
546
+ var APITOGO_CONFIG_FILENAME, ENV_PREFIX, DERIVED_MANIFEST_KEYS, SITE_CONFIG_KEYS;
477
547
  var init_apitogo_config_core = __esm({
478
548
  "src/config/apitogo-config-core.ts"() {
479
549
  APITOGO_CONFIG_FILENAME = "apitogo.config.json";
@@ -486,7 +556,25 @@ var init_apitogo_config_core = __esm({
486
556
  "plans",
487
557
  "backend",
488
558
  "gateway",
489
- "projectId"
559
+ "projectId",
560
+ "landing"
561
+ ];
562
+ SITE_CONFIG_KEYS = [
563
+ "site",
564
+ "metadata",
565
+ "modules",
566
+ "navigation",
567
+ "apis",
568
+ "redirects",
569
+ "theme",
570
+ "search",
571
+ "llms",
572
+ "protectedRoutes",
573
+ "slots",
574
+ "mdx",
575
+ "catalogs",
576
+ "versions",
577
+ "options"
490
578
  ];
491
579
  }
492
580
  });
@@ -519,18 +607,277 @@ var init_apitogo_config_loader = __esm({
519
607
  }
520
608
  });
521
609
 
610
+ // src/config/build-apitogo-config.ts
611
+ function mergeOptionalRecord(...records) {
612
+ const merged = Object.assign({}, ...records.filter(Boolean));
613
+ return Object.keys(merged).length > 0 ? merged : void 0;
614
+ }
615
+ function buildApitogoConfig({
616
+ plugins,
617
+ plans: _legacyPlans,
618
+ ...jsonOverrides
619
+ } = {}) {
620
+ const jsonConfig = normalizeApitogoConfig({
621
+ ...jsonOverrides,
622
+ ..._legacyPlans !== void 0 ? { plans: _legacyPlans } : {}
623
+ });
624
+ const siteConfig = extractSiteConfig(jsonConfig);
625
+ const { plans: _rootPlans, ...restOverrides } = jsonOverrides;
626
+ const authentication = mergeOptionalRecord(
627
+ siteConfig.authentication,
628
+ jsonOverrides.authentication
629
+ );
630
+ return {
631
+ ...siteConfig,
632
+ ...restOverrides,
633
+ plugins,
634
+ ...authentication ? { authentication } : {},
635
+ site: {
636
+ ...siteConfig.site,
637
+ ...jsonOverrides.site
638
+ },
639
+ metadata: {
640
+ ...siteConfig.metadata,
641
+ ...jsonOverrides.metadata
642
+ },
643
+ docs: {
644
+ ...siteConfig.docs,
645
+ ...jsonOverrides.docs
646
+ },
647
+ modules: {
648
+ ...jsonConfig.modules,
649
+ ...jsonOverrides.modules
650
+ }
651
+ };
652
+ }
653
+ var init_build_apitogo_config = __esm({
654
+ "src/config/build-apitogo-config.ts"() {
655
+ init_apitogo_config_core();
656
+ }
657
+ });
658
+
522
659
  // src/config/file-exists.ts
523
660
  import { stat } from "node:fs/promises";
524
661
  var fileExists;
525
662
  var init_file_exists = __esm({
526
663
  "src/config/file-exists.ts"() {
527
- fileExists = (path39) => stat(path39).then(() => true).catch(() => false);
664
+ fileExists = (path40) => stat(path40).then(() => true).catch(() => false);
665
+ }
666
+ });
667
+
668
+ // src/config/validators/ModulesSchema.ts
669
+ import { z as z3 } from "zod";
670
+ var ModuleToggleSchema, DocsModuleSchema, LandingLinkSchema, LandingFeatureSchema, LandingCodeExampleSchema, LandingHeroSchema, LandingTickerItemSchema, LandingTickerSchema, LandingTrustSchema, LandingApiShowcaseItemSchema, LandingApiShowcaseSchema, LandingPricingCtaSchema, LandingContentSchema, DashboardContentSchema, ProfileContentSchema, PlanTierSchema, PlansContentSchema, SubmodulePageFields, LandingModuleSchema, UserManagementModuleSchema, ApiKeysModuleSchema, PlanCatalogItemSchema, PlansModuleSchema, DashboardModuleSchema, UserPanelModuleSchema, ModulesSchema;
671
+ var init_ModulesSchema = __esm({
672
+ "src/config/validators/ModulesSchema.ts"() {
673
+ ModuleToggleSchema = z3.object({
674
+ enabled: z3.boolean().describe("Whether this module is active in the application.")
675
+ }).partial();
676
+ DocsModuleSchema = ModuleToggleSchema.extend({
677
+ files: z3.union([z3.string(), z3.array(z3.string())]).optional(),
678
+ publishMarkdown: z3.boolean().optional(),
679
+ defaultOptions: z3.object({
680
+ toc: z3.boolean(),
681
+ copyPage: z3.boolean().optional(),
682
+ disablePager: z3.boolean(),
683
+ showLastModified: z3.boolean(),
684
+ suggestEdit: z3.object({
685
+ url: z3.string(),
686
+ text: z3.string().optional()
687
+ }).optional()
688
+ }).partial().optional(),
689
+ llms: z3.object({
690
+ llmsTxt: z3.boolean().optional(),
691
+ llmsTxtFull: z3.boolean().optional(),
692
+ includeProtected: z3.boolean().optional()
693
+ }).optional()
694
+ });
695
+ LandingLinkSchema = z3.object({
696
+ label: z3.string(),
697
+ href: z3.string()
698
+ });
699
+ LandingFeatureSchema = z3.object({
700
+ title: z3.string(),
701
+ description: z3.string(),
702
+ icon: z3.string().optional()
703
+ });
704
+ LandingCodeExampleSchema = z3.object({
705
+ filename: z3.string().optional(),
706
+ language: z3.string().optional(),
707
+ code: z3.string()
708
+ }).optional();
709
+ LandingHeroSchema = z3.object({
710
+ title: z3.string().optional(),
711
+ subtitle: z3.string().optional(),
712
+ description: z3.string().optional(),
713
+ badge: z3.string().optional(),
714
+ highlights: z3.array(z3.string()).optional(),
715
+ codeExample: LandingCodeExampleSchema
716
+ }).optional();
717
+ LandingTickerItemSchema = z3.object({
718
+ label: z3.string(),
719
+ value: z3.string(),
720
+ change: z3.string().optional()
721
+ });
722
+ LandingTickerSchema = z3.object({
723
+ enabled: z3.boolean().optional(),
724
+ items: z3.array(LandingTickerItemSchema).optional()
725
+ }).optional();
726
+ LandingTrustSchema = z3.object({
727
+ enabled: z3.boolean().optional(),
728
+ title: z3.string().optional(),
729
+ logos: z3.array(z3.string()).optional()
730
+ }).optional();
731
+ LandingApiShowcaseItemSchema = z3.object({
732
+ name: z3.string(),
733
+ path: z3.string(),
734
+ icon: z3.string().optional(),
735
+ latency: z3.string().optional(),
736
+ summary: z3.string().optional()
737
+ });
738
+ LandingApiShowcaseSchema = z3.object({
739
+ enabled: z3.boolean().optional(),
740
+ title: z3.string().optional(),
741
+ subtitle: z3.string().optional(),
742
+ browseAllHref: z3.string().optional(),
743
+ browseAllLabel: z3.string().optional(),
744
+ autoFromOpenApi: z3.boolean().optional(),
745
+ items: z3.array(LandingApiShowcaseItemSchema).optional()
746
+ }).optional();
747
+ LandingPricingCtaSchema = z3.object({
748
+ enabled: z3.boolean().optional(),
749
+ title: z3.string().optional(),
750
+ description: z3.string().optional(),
751
+ primaryAction: LandingLinkSchema.optional(),
752
+ secondaryAction: LandingLinkSchema.optional()
753
+ }).optional();
754
+ LandingContentSchema = z3.object({
755
+ hero: LandingHeroSchema,
756
+ features: z3.array(LandingFeatureSchema).optional(),
757
+ primaryAction: LandingLinkSchema.optional(),
758
+ secondaryAction: LandingLinkSchema.optional(),
759
+ ticker: LandingTickerSchema,
760
+ trust: LandingTrustSchema,
761
+ apiShowcase: LandingApiShowcaseSchema,
762
+ pricingCta: LandingPricingCtaSchema,
763
+ showPoweredBy: z3.boolean().optional()
764
+ }).optional();
765
+ DashboardContentSchema = z3.object({
766
+ title: z3.string().optional(),
767
+ subtitle: z3.string().optional(),
768
+ description: z3.string().optional(),
769
+ quickLinks: z3.array(LandingLinkSchema).optional()
770
+ }).optional();
771
+ ProfileContentSchema = z3.object({
772
+ title: z3.string().optional(),
773
+ description: z3.string().optional()
774
+ }).optional();
775
+ PlanTierSchema = z3.object({
776
+ name: z3.string(),
777
+ price: z3.string().optional(),
778
+ description: z3.string().optional()
779
+ });
780
+ PlansContentSchema = z3.object({
781
+ title: z3.string().optional(),
782
+ description: z3.string().optional(),
783
+ tiers: z3.array(PlanTierSchema).optional()
784
+ }).optional();
785
+ SubmodulePageFields = {
786
+ page: z3.string().optional().describe(
787
+ "Path to a custom page component file, relative to the project root."
788
+ ),
789
+ component: z3.custom().optional().describe("Custom React component for this sub-module page.")
790
+ };
791
+ LandingModuleSchema = ModuleToggleSchema.extend({
792
+ path: z3.string().default("/").describe("Route path for the landing page."),
793
+ component: z3.custom().optional().describe("Custom React component for the landing page."),
794
+ page: z3.string().optional().describe(
795
+ "Path to a custom landing page component file, relative to the project root."
796
+ ),
797
+ layout: z3.enum(["default", "landing", "none"]).default("landing").describe(
798
+ "Layout wrapper: landing (header + footer), default (docs layout), or none."
799
+ ),
800
+ content: LandingContentSchema.describe(
801
+ "Default landing page content when no custom component is provided."
802
+ )
803
+ });
804
+ UserManagementModuleSchema = ModuleToggleSchema.extend({
805
+ routes: z3.object({
806
+ login: z3.string().default("/signin"),
807
+ register: z3.string().default("/signup"),
808
+ profile: z3.string().default("profile"),
809
+ logout: z3.string().default("/signout")
810
+ }).partial().optional(),
811
+ page: SubmodulePageFields.page,
812
+ component: SubmodulePageFields.component,
813
+ content: ProfileContentSchema.describe(
814
+ "Default profile page content when no custom component is provided."
815
+ )
816
+ });
817
+ ApiKeysModuleSchema = ModuleToggleSchema.extend({
818
+ path: z3.string().default("settings/api-keys").describe("Route path for API key management.")
819
+ });
820
+ PlanCatalogItemSchema = z3.object({
821
+ sku: z3.string(),
822
+ displayName: z3.string(),
823
+ priceAmount: z3.number().default(0),
824
+ priceCurrency: z3.string().optional(),
825
+ billingPeriod: z3.string().optional(),
826
+ limitsJson: z3.string().optional(),
827
+ includedActionKeys: z3.array(z3.string()).optional()
828
+ });
829
+ PlansModuleSchema = ModuleToggleSchema.extend({
830
+ path: z3.string().default("plans").describe("Route path for plans and subscription management."),
831
+ page: SubmodulePageFields.page,
832
+ component: SubmodulePageFields.component,
833
+ content: PlansContentSchema.describe(
834
+ "Default plans page content when no custom component is provided."
835
+ ),
836
+ items: z3.array(PlanCatalogItemSchema).optional().describe(
837
+ "Gateway plan catalog for /pricing preview and publish (canonical storage)."
838
+ )
839
+ });
840
+ DashboardModuleSchema = ModuleToggleSchema.extend({
841
+ path: z3.string().default("dashboard").describe("Route path for the user dashboard."),
842
+ page: SubmodulePageFields.page,
843
+ component: SubmodulePageFields.component,
844
+ content: DashboardContentSchema.describe(
845
+ "Default dashboard page content when no custom component is provided."
846
+ )
847
+ });
848
+ UserPanelModuleSchema = ModuleToggleSchema.extend({
849
+ basePath: z3.string().default("/account").describe("Base path prefix for user panel routes."),
850
+ dashboard: DashboardModuleSchema.optional(),
851
+ userManagement: UserManagementModuleSchema.optional(),
852
+ apiKeys: ApiKeysModuleSchema.optional(),
853
+ plans: PlansModuleSchema.optional()
854
+ });
855
+ ModulesSchema = z3.object({
856
+ docs: DocsModuleSchema.optional().describe(
857
+ "Documentation module \u2014 MD/MDX pages and OpenAPI reference."
858
+ ),
859
+ landing: LandingModuleSchema.optional().describe(
860
+ "Landing page module \u2014 marketing or home page."
861
+ ),
862
+ userPanel: UserPanelModuleSchema.optional().describe(
863
+ "User panel module \u2014 authenticated user area with sub-modules."
864
+ )
865
+ }).optional();
866
+ }
867
+ });
868
+
869
+ // src/config/landing-manifest.ts
870
+ var LandingManifestContentSchema;
871
+ var init_landing_manifest = __esm({
872
+ "src/config/landing-manifest.ts"() {
873
+ init_ModulesSchema();
874
+ LandingManifestContentSchema = LandingContentSchema;
528
875
  }
529
876
  });
530
877
 
531
878
  // src/config/local-manifest.ts
532
879
  import path3 from "node:path";
533
- import { z as z3 } from "zod";
880
+ import { z as z4 } from "zod";
534
881
  function isPricingEnabled(manifest) {
535
882
  return manifest?.pricing?.enabled === true;
536
883
  }
@@ -619,200 +966,69 @@ var BillingPeriodSchema, ManifestPlanInputSchema, DevPortalLocalManifestSchema;
619
966
  var init_local_manifest = __esm({
620
967
  "src/config/local-manifest.ts"() {
621
968
  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(),
969
+ init_landing_manifest();
970
+ BillingPeriodSchema = z4.enum(["month", "year", "monthly", "annual"]);
971
+ ManifestPlanInputSchema = z4.object({
972
+ sku: z4.string().min(1),
973
+ displayName: z4.string().min(1),
974
+ priceAmount: z4.number().default(0),
975
+ priceCurrency: z4.string().optional(),
628
976
  billingPeriod: BillingPeriodSchema.optional(),
629
- limitsJson: z3.string().optional(),
630
- includedActionKeys: z3.array(z3.string()).optional()
977
+ limitsJson: z4.string().optional(),
978
+ includedActionKeys: z4.array(z4.string()).optional()
631
979
  });
632
- DevPortalLocalManifestSchema = z3.object({
633
- siteName: z3.string().optional(),
634
- branding: z3.object({
635
- title: z3.string().optional(),
636
- logoUrl: z3.string().optional()
980
+ DevPortalLocalManifestSchema = z4.object({
981
+ siteName: z4.string().optional(),
982
+ branding: z4.object({
983
+ title: z4.string().optional(),
984
+ logoUrl: z4.string().optional()
637
985
  }).optional(),
638
- pricing: z3.object({
639
- enabled: z3.boolean().optional()
986
+ pricing: z4.object({
987
+ enabled: z4.boolean().optional()
640
988
  }).optional(),
641
- authentication: z3.object({
642
- enabled: z3.boolean().optional(),
643
- type: z3.string().optional(),
644
- apiBaseUrl: z3.string().optional()
989
+ authentication: z4.object({
990
+ enabled: z4.boolean().optional(),
991
+ apiBaseUrl: z4.string().optional(),
992
+ native: z4.object({
993
+ enabled: z4.boolean().optional()
994
+ }).optional(),
995
+ email: z4.object({
996
+ provider: z4.string().optional(),
997
+ from: z4.string().optional()
998
+ }).optional(),
999
+ providers: z4.array(
1000
+ z4.object({
1001
+ id: z4.string().min(1),
1002
+ displayName: z4.string().optional(),
1003
+ authority: z4.string().optional(),
1004
+ clientId: z4.string().optional(),
1005
+ scopes: z4.string().optional()
1006
+ })
1007
+ ).optional()
645
1008
  }).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()
1009
+ plans: z4.array(ManifestPlanInputSchema).optional(),
1010
+ backend: z4.object({
1011
+ sourceDirectory: z4.string().optional(),
1012
+ publishDirectory: z4.string().optional(),
1013
+ openApiPath: z4.string().optional(),
1014
+ runtime: z4.string().optional(),
1015
+ runtimeVersion: z4.string().optional(),
1016
+ deployed: z4.boolean().optional()
654
1017
  }).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()
1018
+ gateway: z4.object({
1019
+ authMode: z4.enum(["platformManagedEntra", "bringYourOwnOidc"]).optional(),
1020
+ oidcMetadataUrl: z4.string().optional(),
1021
+ oidcAllowedIssuers: z4.array(z4.string()).optional(),
1022
+ oidcAudiences: z4.array(z4.string()).optional(),
1023
+ limitsJson: z4.string().optional(),
1024
+ publicHealthActionKey: z4.string().optional()
662
1025
  }).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;
671
- var init_ModulesSchema = __esm({
672
- "src/config/validators/ModulesSchema.ts"() {
673
- ModuleToggleSchema = z4.object({
674
- enabled: z4.boolean().describe("Whether this module is active in the application.")
675
- }).partial();
676
- DocsModuleSchema = ModuleToggleSchema.extend({
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()
687
- }).optional()
688
- }).partial().optional(),
689
- llms: z4.object({
690
- llmsTxt: z4.boolean().optional(),
691
- llmsTxtFull: z4.boolean().optional(),
692
- includeProtected: z4.boolean().optional()
1026
+ projectId: z4.string().optional(),
1027
+ landing: z4.object({
1028
+ enabled: z4.boolean().optional(),
1029
+ content: LandingManifestContentSchema
693
1030
  }).optional()
694
1031
  });
695
- LandingLinkSchema = z4.object({
696
- label: z4.string(),
697
- href: z4.string()
698
- });
699
- LandingFeatureSchema = z4.object({
700
- title: z4.string(),
701
- description: z4.string()
702
- });
703
- LandingHeroSchema = z4.object({
704
- title: z4.string().optional(),
705
- subtitle: z4.string().optional(),
706
- description: z4.string().optional()
707
- }).optional();
708
- LandingContentSchema = z4.object({
709
- hero: LandingHeroSchema,
710
- features: z4.array(LandingFeatureSchema).optional(),
711
- primaryAction: LandingLinkSchema.optional(),
712
- secondaryAction: LandingLinkSchema.optional(),
713
- showPoweredBy: z4.boolean().optional()
714
- }).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()
720
- }).optional();
721
- ProfileContentSchema = z4.object({
722
- title: z4.string().optional(),
723
- description: z4.string().optional()
724
- }).optional();
725
- PlanTierSchema = z4.object({
726
- name: z4.string(),
727
- price: z4.string().optional(),
728
- description: z4.string().optional()
729
- });
730
- PlansContentSchema = z4.object({
731
- title: z4.string().optional(),
732
- description: z4.string().optional(),
733
- tiers: z4.array(PlanTierSchema).optional()
734
- }).optional();
735
- SubmodulePageFields = {
736
- page: z4.string().optional().describe(
737
- "Path to a custom page component file, relative to the project root."
738
- ),
739
- component: z4.custom().optional().describe("Custom React component for this sub-module page.")
740
- };
741
- LandingModuleSchema = ModuleToggleSchema.extend({
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(
745
- "Path to a custom landing page component file, relative to the project root."
746
- ),
747
- layout: z4.enum(["default", "landing", "none"]).default("landing").describe(
748
- "Layout wrapper: landing (header + footer), default (docs layout), or none."
749
- ),
750
- content: LandingContentSchema.describe(
751
- "Default landing page content when no custom component is provided."
752
- )
753
- });
754
- UserManagementModuleSchema = ModuleToggleSchema.extend({
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")
760
- }).partial().optional(),
761
- page: SubmodulePageFields.page,
762
- component: SubmodulePageFields.component,
763
- content: ProfileContentSchema.describe(
764
- "Default profile page content when no custom component is provided."
765
- )
766
- });
767
- ApiKeysModuleSchema = ModuleToggleSchema.extend({
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()
778
- });
779
- PlansModuleSchema = ModuleToggleSchema.extend({
780
- path: z4.string().default("plans").describe("Route path for plans and subscription management."),
781
- page: SubmodulePageFields.page,
782
- component: SubmodulePageFields.component,
783
- content: PlansContentSchema.describe(
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)."
788
- )
789
- });
790
- DashboardModuleSchema = ModuleToggleSchema.extend({
791
- path: z4.string().default("dashboard").describe("Route path for the user dashboard."),
792
- page: SubmodulePageFields.page,
793
- component: SubmodulePageFields.component,
794
- content: DashboardContentSchema.describe(
795
- "Default dashboard page content when no custom component is provided."
796
- )
797
- });
798
- UserPanelModuleSchema = ModuleToggleSchema.extend({
799
- basePath: z4.string().default("/account").describe("Base path prefix for user panel routes."),
800
- dashboard: DashboardModuleSchema.optional(),
801
- userManagement: UserManagementModuleSchema.optional(),
802
- apiKeys: ApiKeysModuleSchema.optional(),
803
- plans: PlansModuleSchema.optional()
804
- });
805
- ModulesSchema = z4.object({
806
- docs: DocsModuleSchema.optional().describe(
807
- "Documentation module \u2014 MD/MDX pages and OpenAPI reference."
808
- ),
809
- landing: LandingModuleSchema.optional().describe(
810
- "Landing page module \u2014 marketing or home page."
811
- ),
812
- userPanel: UserPanelModuleSchema.optional().describe(
813
- "User panel module \u2014 authenticated user area with sub-modules."
814
- )
815
- }).optional();
816
1032
  }
817
1033
  });
818
1034
 
@@ -849,11 +1065,14 @@ var init_resolve_modules = __esm({
849
1065
  ];
850
1066
  resolveLandingContent = (config2, content) => {
851
1067
  const siteTitle = config2.metadata?.applicationName ?? config2.site?.title ?? "APIToGo";
852
- return {
1068
+ const resolved = {
853
1069
  hero: {
854
1070
  title: content?.hero?.title ?? siteTitle,
855
1071
  subtitle: content?.hero?.subtitle ?? "Developer portal",
856
- description: content?.hero?.description ?? config2.metadata?.description ?? "Ship beautiful API documentation and developer experiences with APIToGo."
1072
+ description: content?.hero?.description ?? config2.metadata?.description ?? "Ship beautiful API documentation and developer experiences with APIToGo.",
1073
+ badge: content?.hero?.badge,
1074
+ highlights: content?.hero?.highlights,
1075
+ codeExample: content?.hero?.codeExample
857
1076
  },
858
1077
  features: content?.features ?? DEFAULT_LANDING_FEATURES,
859
1078
  primaryAction: content?.primaryAction ?? {
@@ -866,6 +1085,19 @@ var init_resolve_modules = __esm({
866
1085
  },
867
1086
  showPoweredBy: content?.showPoweredBy
868
1087
  };
1088
+ if (content?.ticker && content.ticker.enabled !== false) {
1089
+ resolved.ticker = content.ticker;
1090
+ }
1091
+ if (content?.trust && content.trust.enabled !== false) {
1092
+ resolved.trust = content.trust;
1093
+ }
1094
+ if (content?.apiShowcase && content.apiShowcase.enabled !== false) {
1095
+ resolved.apiShowcase = content.apiShowcase;
1096
+ }
1097
+ if (content?.pricingCta && content.pricingCta.enabled !== false) {
1098
+ resolved.pricingCta = content.pricingCta;
1099
+ }
1100
+ return resolved;
869
1101
  };
870
1102
  DEFAULT_DASHBOARD_QUICK_LINKS = [
871
1103
  { label: "Documentation", href: "/introduction" },
@@ -4094,8 +4326,26 @@ var init_ZudokuConfig = __esm({
4094
4326
  redirectToAfterSignOut: z9.string().optional()
4095
4327
  }),
4096
4328
  z9.object({
4097
- type: z9.literal("dev-portal"),
4329
+ type: z9.literal("dev-portal").optional().default("dev-portal"),
4098
4330
  apiBaseUrl: z9.string().optional(),
4331
+ native: z9.object({
4332
+ enabled: z9.boolean().optional()
4333
+ }).optional(),
4334
+ email: z9.object({
4335
+ provider: z9.string().optional(),
4336
+ from: z9.string().optional(),
4337
+ connectionString: z9.string().optional()
4338
+ }).optional(),
4339
+ providers: z9.array(
4340
+ z9.object({
4341
+ id: z9.string().min(1),
4342
+ displayName: z9.string().optional(),
4343
+ authority: z9.string().optional(),
4344
+ clientId: z9.string().optional(),
4345
+ clientSecret: z9.string().optional(),
4346
+ scopes: z9.string().optional()
4347
+ })
4348
+ ).optional(),
4099
4349
  redirectToAfterSignUp: z9.string().optional(),
4100
4350
  redirectToAfterSignIn: z9.string().optional(),
4101
4351
  redirectToAfterSignOut: z9.string().optional()
@@ -4149,6 +4399,7 @@ var init_ZudokuConfig = __esm({
4149
4399
  });
4150
4400
  SiteSchema = z9.object({
4151
4401
  title: z9.string(),
4402
+ showTitleInHeader: z9.boolean().optional(),
4152
4403
  logoUrl: z9.string(),
4153
4404
  dir: z9.enum(["ltr", "rtl"]).optional(),
4154
4405
  logo: LogoSchema,
@@ -4293,7 +4544,17 @@ async function loadZudokuConfigWithMeta(rootDir) {
4293
4544
  perEnvironmentStartEndDuringDev: true
4294
4545
  }
4295
4546
  });
4296
- const config2 = module.default;
4547
+ const importedConfig = module.default;
4548
+ let config2;
4549
+ try {
4550
+ const fileConfig = loadApitogoConfig(rootDir);
4551
+ config2 = buildApitogoConfig({
4552
+ ...fileConfig,
4553
+ plugins: importedConfig.plugins
4554
+ });
4555
+ } catch {
4556
+ config2 = importedConfig;
4557
+ }
4297
4558
  validateConfig(config2, configPath);
4298
4559
  const configWithMetadata = {
4299
4560
  ...config2,
@@ -4304,7 +4565,7 @@ async function loadZudokuConfigWithMeta(rootDir) {
4304
4565
  dependencies,
4305
4566
  configPath
4306
4567
  },
4307
- __resolvedModules: resolveModulesConfig(config2)
4568
+ __resolvedModules: resolveModulesConfig(config2, { rootDir })
4308
4569
  };
4309
4570
  return configWithMetadata;
4310
4571
  }
@@ -4414,7 +4675,9 @@ async function loadZudokuConfig(configEnv, rootDir) {
4414
4675
  ...transformedConfig.__meta,
4415
4676
  ...configWithManifestMeta.__meta
4416
4677
  },
4417
- __resolvedModules: resolveModulesConfig(transformedConfig)
4678
+ __resolvedModules: resolveModulesConfig(transformedConfig, {
4679
+ rootDir: transformedConfig.__meta.rootDir
4680
+ })
4418
4681
  };
4419
4682
  if (!process.env.APITOGO_JSON_ONLY) {
4420
4683
  logger.info(
@@ -4442,6 +4705,7 @@ var init_loader = __esm({
4442
4705
  init_transform_config();
4443
4706
  init_invariant();
4444
4707
  init_apitogo_config_loader();
4708
+ init_build_apitogo_config();
4445
4709
  init_file_exists();
4446
4710
  init_local_manifest();
4447
4711
  init_resolve_modules();
@@ -4481,7 +4745,7 @@ __export(llms_exports, {
4481
4745
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
4482
4746
  });
4483
4747
  import { writeFile as writeFile4 } from "node:fs/promises";
4484
- import path26 from "node:path";
4748
+ import path27 from "node:path";
4485
4749
  import colors6 from "picocolors";
4486
4750
  async function generateLlmsTxtFiles({
4487
4751
  markdownFileInfos,
@@ -4516,7 +4780,7 @@ async function generateLlmsTxtFiles({
4516
4780
  }
4517
4781
  }
4518
4782
  const llmsTxt2 = llmsTxtParts.join("\n");
4519
- await writeFile4(path26.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
4783
+ await writeFile4(path27.join(baseOutputDir, "llms.txt"), llmsTxt2, "utf-8");
4520
4784
  if (process.env.APITOGO_JSON_ONLY !== "1") {
4521
4785
  console.log(colors6.blue("\u2713 generated llms.txt"));
4522
4786
  }
@@ -4544,7 +4808,7 @@ ${info.content}
4544
4808
  }
4545
4809
  const llmsFull = llmsFullParts.join("\n");
4546
4810
  await writeFile4(
4547
- path26.join(baseOutputDir, "llms-full.txt"),
4811
+ path27.join(baseOutputDir, "llms-full.txt"),
4548
4812
  llmsFull,
4549
4813
  "utf-8"
4550
4814
  );
@@ -4565,11 +4829,11 @@ import { hideBin } from "yargs/helpers";
4565
4829
  import yargs from "yargs/yargs";
4566
4830
 
4567
4831
  // src/cli/build/handler.ts
4568
- import path30 from "node:path";
4832
+ import path31 from "node:path";
4569
4833
 
4570
4834
  // src/vite/build.ts
4571
4835
  import { mkdir as mkdir5, readFile as readFile3, rename, rm as rm2, writeFile as writeFile5 } from "node:fs/promises";
4572
- import path28 from "node:path";
4836
+ import path29 from "node:path";
4573
4837
  import { build as esbuild } from "esbuild";
4574
4838
  import { build as viteBuild, mergeConfig as mergeConfig3 } from "vite";
4575
4839
 
@@ -4705,7 +4969,7 @@ init_invariant();
4705
4969
  init_joinUrl();
4706
4970
 
4707
4971
  // src/vite/config.ts
4708
- import path23 from "node:path";
4972
+ import path24 from "node:path";
4709
4973
  import dotenv from "dotenv";
4710
4974
  import colors4 from "picocolors";
4711
4975
  import {
@@ -4716,7 +4980,7 @@ import {
4716
4980
  // package.json
4717
4981
  var package_default = {
4718
4982
  name: "@lukoweb/apitogo",
4719
- version: "0.1.53",
4983
+ version: "0.1.55",
4720
4984
  type: "module",
4721
4985
  sideEffects: [
4722
4986
  "**/*.css",
@@ -5485,14 +5749,14 @@ var flattenAllOf = (schema2) => {
5485
5749
  };
5486
5750
 
5487
5751
  // src/lib/util/traverse.ts
5488
- var traverse = (specification, transform, path39 = []) => {
5489
- const transformed = transform(specification, path39);
5752
+ var traverse = (specification, transform, path40 = []) => {
5753
+ const transformed = transform(specification, path40);
5490
5754
  if (typeof transformed !== "object" || transformed === null) {
5491
5755
  return transformed;
5492
5756
  }
5493
5757
  const result = Array.isArray(transformed) ? [] : {};
5494
5758
  for (const [key, value] of Object.entries(transformed)) {
5495
- const currentPath = [...path39, key];
5759
+ const currentPath = [...path40, key];
5496
5760
  if (Array.isArray(value)) {
5497
5761
  result[key] = value.map(
5498
5762
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -5520,9 +5784,9 @@ var resolveLocalRef = (schema2, ref) => {
5520
5784
  if (schemaCache?.has(ref)) {
5521
5785
  return schemaCache.get(ref);
5522
5786
  }
5523
- const path39 = ref.split("/").slice(1);
5787
+ const path40 = ref.split("/").slice(1);
5524
5788
  let current = schema2;
5525
- for (const segment of path39) {
5789
+ for (const segment of path40) {
5526
5790
  if (!current || typeof current !== "object") {
5527
5791
  current = null;
5528
5792
  }
@@ -5541,7 +5805,7 @@ var dereference = async (schema2, resolvers = []) => {
5541
5805
  }
5542
5806
  const cloned = structuredClone(schema2);
5543
5807
  const visited = /* @__PURE__ */ new Set();
5544
- const resolve = async (current, path39) => {
5808
+ const resolve = async (current, path40) => {
5545
5809
  if (isIndexableObject(current)) {
5546
5810
  if (visited.has(current)) {
5547
5811
  return CIRCULAR_REF;
@@ -5549,7 +5813,7 @@ var dereference = async (schema2, resolvers = []) => {
5549
5813
  visited.add(current);
5550
5814
  if (Array.isArray(current)) {
5551
5815
  for (let index = 0; index < current.length; index++) {
5552
- current[index] = await resolve(current[index], `${path39}/${index}`);
5816
+ current[index] = await resolve(current[index], `${path40}/${index}`);
5553
5817
  }
5554
5818
  } else {
5555
5819
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -5560,13 +5824,13 @@ var dereference = async (schema2, resolvers = []) => {
5560
5824
  for (const resolver of resolvers) {
5561
5825
  const resolved = await resolver($ref);
5562
5826
  if (resolved) {
5563
- result2 = await resolve(resolved, path39);
5827
+ result2 = await resolve(resolved, path40);
5564
5828
  break;
5565
5829
  }
5566
5830
  }
5567
5831
  if (result2 === void 0) {
5568
5832
  const resolved = await resolveLocalRef(cloned, $ref);
5569
- result2 = await resolve(resolved, path39);
5833
+ result2 = await resolve(resolved, path40);
5570
5834
  }
5571
5835
  if (hasSiblings) {
5572
5836
  if (result2 === CIRCULAR_REF) {
@@ -5579,7 +5843,7 @@ var dereference = async (schema2, resolvers = []) => {
5579
5843
  return result2;
5580
5844
  }
5581
5845
  for (const key in current) {
5582
- current[key] = await resolve(current[key], `${path39}/${key}`);
5846
+ current[key] = await resolve(current[key], `${path40}/${key}`);
5583
5847
  }
5584
5848
  }
5585
5849
  visited.delete(current);
@@ -5618,9 +5882,9 @@ var upgradeSchema = (schema2) => {
5618
5882
  }
5619
5883
  return sub;
5620
5884
  });
5621
- schema2 = traverse(schema2, (sub, path39) => {
5885
+ schema2 = traverse(schema2, (sub, path40) => {
5622
5886
  if (sub.example !== void 0) {
5623
- if (isSchemaPath(path39 ?? [])) {
5887
+ if (isSchemaPath(path40 ?? [])) {
5624
5888
  sub.examples = [sub.example];
5625
5889
  } else {
5626
5890
  sub.examples = {
@@ -5633,11 +5897,11 @@ var upgradeSchema = (schema2) => {
5633
5897
  }
5634
5898
  return sub;
5635
5899
  });
5636
- schema2 = traverse(schema2, (schema3, path39) => {
5900
+ schema2 = traverse(schema2, (schema3, path40) => {
5637
5901
  if (schema3.type === "object" && schema3.properties !== void 0) {
5638
- const parentPath = path39?.slice(0, -1);
5902
+ const parentPath = path40?.slice(0, -1);
5639
5903
  const isMultipart = parentPath?.some((segment, index) => {
5640
- return segment === "content" && path39?.[index + 1] === "multipart/form-data";
5904
+ return segment === "content" && path40?.[index + 1] === "multipart/form-data";
5641
5905
  });
5642
5906
  if (isMultipart) {
5643
5907
  const entries = Object.entries(schema3.properties);
@@ -5651,8 +5915,8 @@ var upgradeSchema = (schema2) => {
5651
5915
  }
5652
5916
  return schema3;
5653
5917
  });
5654
- schema2 = traverse(schema2, (schema3, path39) => {
5655
- if (path39?.includes("content") && path39.includes("application/octet-stream")) {
5918
+ schema2 = traverse(schema2, (schema3, path40) => {
5919
+ if (path40?.includes("content") && path40.includes("application/octet-stream")) {
5656
5920
  return {};
5657
5921
  }
5658
5922
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -5678,11 +5942,11 @@ var upgradeSchema = (schema2) => {
5678
5942
  }
5679
5943
  return sub;
5680
5944
  });
5681
- schema2 = traverse(schema2, (schema3, path39) => {
5945
+ schema2 = traverse(schema2, (schema3, path40) => {
5682
5946
  if (schema3.type === "string" && schema3.format === "byte") {
5683
- const parentPath = path39?.slice(0, -1);
5947
+ const parentPath = path40?.slice(0, -1);
5684
5948
  const contentMediaType = parentPath?.find(
5685
- (_, index) => path39?.[index - 1] === "content"
5949
+ (_, index) => path40?.[index - 1] === "content"
5686
5950
  );
5687
5951
  return {
5688
5952
  type: "string",
@@ -5694,7 +5958,7 @@ var upgradeSchema = (schema2) => {
5694
5958
  });
5695
5959
  return schema2;
5696
5960
  };
5697
- function isSchemaPath(path39) {
5961
+ function isSchemaPath(path40) {
5698
5962
  const schemaLocations = [
5699
5963
  ["components", "schemas"],
5700
5964
  "properties",
@@ -5707,10 +5971,10 @@ function isSchemaPath(path39) {
5707
5971
  ];
5708
5972
  return schemaLocations.some((location) => {
5709
5973
  if (Array.isArray(location)) {
5710
- return location.every((segment, index) => path39[index] === segment);
5974
+ return location.every((segment, index) => path40[index] === segment);
5711
5975
  }
5712
- return path39.includes(location);
5713
- }) || path39.includes("schema") || path39.some((segment) => segment.endsWith("Schema"));
5976
+ return path40.includes(location);
5977
+ }) || path40.includes("schema") || path40.some((segment) => segment.endsWith("Schema"));
5714
5978
  }
5715
5979
 
5716
5980
  // src/lib/oas/parser/index.ts
@@ -5792,13 +6056,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
5792
6056
  "anyOf",
5793
6057
  "oneOf"
5794
6058
  ]);
5795
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path39 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
6059
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path40 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
5796
6060
  if (obj === null || typeof obj !== "object") return obj;
5797
6061
  const refPath = obj.__$ref;
5798
6062
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
5799
6063
  if (isCircular) {
5800
6064
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
5801
- const circularProp = path39.find((p) => !OPENAPI_PROPS.has(p)) || path39[0];
6065
+ const circularProp = path40.find((p) => !OPENAPI_PROPS.has(p)) || path40[0];
5802
6066
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
5803
6067
  }
5804
6068
  if (refs.has(obj)) return refs.get(obj);
@@ -5808,7 +6072,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
5808
6072
  value,
5809
6073
  currentPath,
5810
6074
  refs,
5811
- [...path39, key],
6075
+ [...path40, key],
5812
6076
  currentRefPaths
5813
6077
  );
5814
6078
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -5843,7 +6107,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
5843
6107
  var getAllTags = (schema2) => {
5844
6108
  const rootTags = schema2.tags ?? [];
5845
6109
  const operations = Object.values(schema2.paths ?? {}).flatMap(
5846
- (path39) => HttpMethods.map((k) => path39?.[k]).filter((op) => op != null)
6110
+ (path40) => HttpMethods.map((k) => path40?.[k]).filter((op) => op != null)
5847
6111
  );
5848
6112
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
5849
6113
  const hasUntaggedOperations = operations.some(
@@ -5898,7 +6162,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
5898
6162
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
5899
6163
  var getAllOperations = (paths) => {
5900
6164
  const operations = Object.entries(paths ?? {}).flatMap(
5901
- ([path39, value]) => HttpMethods.flatMap((method) => {
6165
+ ([path40, value]) => HttpMethods.flatMap((method) => {
5902
6166
  if (!value?.[method]) return [];
5903
6167
  const operation = value[method];
5904
6168
  const pathParameters = value.parameters ?? [];
@@ -5918,7 +6182,7 @@ var getAllOperations = (paths) => {
5918
6182
  return {
5919
6183
  ...operation,
5920
6184
  method,
5921
- path: path39,
6185
+ path: path40,
5922
6186
  parameters,
5923
6187
  servers,
5924
6188
  tags: operation.tags ?? []
@@ -6276,8 +6540,8 @@ var Schema = builder.objectRef("Schema").implement({
6276
6540
  }),
6277
6541
  paths: t.field({
6278
6542
  type: [PathItem],
6279
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path39, value]) => ({
6280
- path: path39,
6543
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path40, value]) => ({
6544
+ path: path40,
6281
6545
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
6282
6546
  methods: Object.keys(value)
6283
6547
  }))
@@ -6424,7 +6688,7 @@ init_joinUrl();
6424
6688
 
6425
6689
  // src/vite/api/schema-codegen.ts
6426
6690
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
6427
- var getSegmentsFromPath = (path39) => path39.split("/").slice(1).map(unescapeJsonPointer);
6691
+ var getSegmentsFromPath = (path40) => path40.split("/").slice(1).map(unescapeJsonPointer);
6428
6692
  var createLocalRefMap = (obj) => {
6429
6693
  const refMap = /* @__PURE__ */ new Map();
6430
6694
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -6455,16 +6719,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
6455
6719
  /"__refMap\+Siblings:(.*?)"/g,
6456
6720
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
6457
6721
  );
6458
- var lookup = (schema2, path39, filePath) => {
6459
- const parts = getSegmentsFromPath(path39);
6722
+ var lookup = (schema2, path40, filePath) => {
6723
+ const parts = getSegmentsFromPath(path40);
6460
6724
  let val = schema2;
6461
6725
  for (const part of parts) {
6462
6726
  while (val.$ref?.startsWith("#/")) {
6463
- val = val.$ref === path39 ? val : lookup(schema2, val.$ref, filePath);
6727
+ val = val.$ref === path40 ? val : lookup(schema2, val.$ref, filePath);
6464
6728
  }
6465
6729
  if (val[part] === void 0) {
6466
6730
  throw new Error(
6467
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path39}`
6731
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path40}`
6468
6732
  );
6469
6733
  }
6470
6734
  val = val[part];
@@ -6709,8 +6973,8 @@ var SchemaManager = class {
6709
6973
  }
6710
6974
  }
6711
6975
  };
6712
- getLatestSchema = (path39) => this.processedSchemas[path39]?.at(0);
6713
- getSchemasForPath = (path39) => this.processedSchemas[path39];
6976
+ getLatestSchema = (path40) => this.processedSchemas[path40]?.at(0);
6977
+ getSchemasForPath = (path40) => this.processedSchemas[path40];
6714
6978
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
6715
6979
  getUrlToFilePathMap = () => {
6716
6980
  const map = /* @__PURE__ */ new Map();
@@ -7325,7 +7589,7 @@ var viteAuthPlugin = () => {
7325
7589
  async load(id) {
7326
7590
  if (id === resolvedVirtualModuleId5) {
7327
7591
  const config2 = getCurrentConfig();
7328
- if (!config2.authentication || config2.__meta.mode === "standalone") {
7592
+ if (!config2.authentication?.type || config2.__meta.mode === "standalone") {
7329
7593
  return `export const configuredAuthProvider = undefined;`;
7330
7594
  }
7331
7595
  return [
@@ -7381,17 +7645,43 @@ var viteAliasPlugin = () => {
7381
7645
  var plugin_component_default = viteAliasPlugin;
7382
7646
 
7383
7647
  // src/vite/plugin-config.ts
7648
+ init_package_json();
7384
7649
  init_loader();
7650
+ import path16 from "node:path";
7385
7651
  import { normalizePath } from "vite";
7386
7652
  var virtualModuleId3 = "virtual:zudoku-config";
7387
7653
  var resolvedVirtualModuleId3 = `\0${virtualModuleId3}`;
7654
+ var browserConfigLoaderPath = path16.join(
7655
+ getZudokuRootDir(),
7656
+ "src/config/apitogo-config-loader.browser.ts"
7657
+ );
7658
+ function serializeClientConfig(config2) {
7659
+ const {
7660
+ plugins: _plugins,
7661
+ __meta: _meta,
7662
+ __resolvedModules,
7663
+ ...rest
7664
+ } = config2;
7665
+ return JSON.stringify(
7666
+ { ...rest, __resolvedModules },
7667
+ (_key, value) => typeof value === "function" ? void 0 : value
7668
+ );
7669
+ }
7388
7670
  var viteConfigPlugin = () => {
7389
7671
  let viteConfig;
7390
7672
  return {
7391
7673
  name: "zudoku-config-plugin",
7392
- resolveId(id) {
7393
- if (id !== virtualModuleId3) return;
7394
- return resolvedVirtualModuleId3;
7674
+ resolveId(source, _importer, options) {
7675
+ if (source === virtualModuleId3) {
7676
+ return resolvedVirtualModuleId3;
7677
+ }
7678
+ if (!source.includes("apitogo-config-loader.node")) {
7679
+ return;
7680
+ }
7681
+ const isServerEnvironment = options?.ssr === true || this.environment?.config?.consumer === "server";
7682
+ if (!isServerEnvironment) {
7683
+ return browserConfigLoaderPath;
7684
+ }
7395
7685
  },
7396
7686
  configResolved(resolvedConfig) {
7397
7687
  viteConfig = resolvedConfig;
@@ -7419,8 +7709,11 @@ var viteConfigPlugin = () => {
7419
7709
  import rawConfig from "${normalizePath(configPath)}";
7420
7710
  import { runPluginTransformConfig } from "@lukoweb/apitogo/plugins";
7421
7711
 
7712
+ const embeddedConfig = ${serializeClientConfig(loadedConfig)};
7713
+
7422
7714
  const config = await runPluginTransformConfig({
7423
- ...rawConfig,
7715
+ ...embeddedConfig,
7716
+ plugins: rawConfig?.plugins ?? embeddedConfig.plugins ?? [],
7424
7717
  __meta: ${JSON.stringify(clientMeta)},
7425
7718
  });
7426
7719
  export default config;
@@ -7525,7 +7818,7 @@ var viteDocMetadataPlugin = () => ({
7525
7818
 
7526
7819
  // src/vite/plugin-docs.ts
7527
7820
  init_loader();
7528
- import path16 from "node:path";
7821
+ import path17 from "node:path";
7529
7822
  import { glob as glob3 } from "glob";
7530
7823
  import globParent from "glob-parent";
7531
7824
  init_ZudokuConfig();
@@ -7594,7 +7887,7 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
7594
7887
  if (process.env.NODE_ENV !== "development") {
7595
7888
  const draftStatuses = await Promise.all(
7596
7889
  globbedFiles.map(async (file) => {
7597
- const absolutePath = path16.resolve(config2.__meta.rootDir, file);
7890
+ const absolutePath = path17.resolve(config2.__meta.rootDir, file);
7598
7891
  const { data } = await readFrontmatter(absolutePath);
7599
7892
  return { file, isDraft: data.draft === true };
7600
7893
  })
@@ -7607,9 +7900,9 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
7607
7900
  if (draftFiles.has(file)) {
7608
7901
  continue;
7609
7902
  }
7610
- const relativePath = path16.posix.relative(parent, file);
7903
+ const relativePath = path17.posix.relative(parent, file);
7611
7904
  const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
7612
- const filePath = options.absolute ? path16.resolve(config2.__meta.rootDir, file) : file;
7905
+ const filePath = options.absolute ? path17.resolve(config2.__meta.rootDir, file) : file;
7613
7906
  fileMapping[routePath] = filePath;
7614
7907
  }
7615
7908
  }
@@ -7673,7 +7966,7 @@ var viteDocsPlugin = () => {
7673
7966
  const globbedDocuments = {};
7674
7967
  for (const [routePath, file] of Object.entries(fileMapping)) {
7675
7968
  const importPath = ensureLeadingSlash(
7676
- path16.posix.join(globImportBasePath, file)
7969
+ path17.posix.join(globImportBasePath, file)
7677
7970
  );
7678
7971
  globbedDocuments[routePath] = importPath;
7679
7972
  }
@@ -7699,7 +7992,7 @@ var plugin_docs_default = viteDocsPlugin;
7699
7992
  // src/vite/plugin-local-manifest.ts
7700
7993
  init_apitogo_config_loader();
7701
7994
  init_local_manifest();
7702
- import path17 from "node:path";
7995
+ import path18 from "node:path";
7703
7996
  var APITOGO_LOCAL_MANIFEST_VIRTUAL_ID = "virtual:apitogo-local-manifest";
7704
7997
  var resolvedVirtualModuleId4 = `\0${APITOGO_LOCAL_MANIFEST_VIRTUAL_ID}`;
7705
7998
  var viteLocalManifestPlugin = () => {
@@ -7749,8 +8042,8 @@ var viteLocalManifestPlugin = () => {
7749
8042
  server.watcher.add(watchPath);
7750
8043
  }
7751
8044
  server.watcher.on("change", async (changedPath) => {
7752
- const resolvedChanged = path17.resolve(changedPath);
7753
- if (!watchPaths.some((p) => path17.resolve(p) === resolvedChanged)) {
8045
+ const resolvedChanged = path18.resolve(changedPath);
8046
+ if (!watchPaths.some((p) => path18.resolve(p) === resolvedChanged)) {
7754
8047
  return;
7755
8048
  }
7756
8049
  const module = server.moduleGraph.getModuleById(
@@ -7777,7 +8070,7 @@ init_loader();
7777
8070
  init_ProtectedRoutesSchema();
7778
8071
  init_joinUrl();
7779
8072
  import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
7780
- import path18 from "node:path";
8073
+ import path19 from "node:path";
7781
8074
  import { matchPath } from "react-router";
7782
8075
  var processMarkdownFile = async (filePath) => {
7783
8076
  const { content: markdownContent, data: frontmatter } = await readFrontmatter(filePath);
@@ -7865,7 +8158,7 @@ var viteMarkdownExportPlugin = () => {
7865
8158
  if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
7866
8159
  return;
7867
8160
  }
7868
- const distDir = path18.join(
8161
+ const distDir = path19.join(
7869
8162
  config2.__meta.rootDir,
7870
8163
  "dist",
7871
8164
  config2.basePath ?? ""
@@ -7886,15 +8179,15 @@ var viteMarkdownExportPlugin = () => {
7886
8179
  content: finalMarkdown
7887
8180
  });
7888
8181
  const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
7889
- const outputPath = `${path18.join(distDir, ...segments)}.md`;
7890
- await mkdir2(path18.dirname(outputPath), { recursive: true });
8182
+ const outputPath = `${path19.join(distDir, ...segments)}.md`;
8183
+ await mkdir2(path19.dirname(outputPath), { recursive: true });
7891
8184
  await writeFile2(outputPath, finalMarkdown, "utf-8");
7892
8185
  } catch (error) {
7893
8186
  console.warn(`Failed to export markdown for ${routePath}:`, error);
7894
8187
  }
7895
8188
  }
7896
8189
  if (config2.docs?.llms?.llmsTxt || config2.docs?.llms?.llmsTxtFull) {
7897
- const markdownInfoPath = path18.join(
8190
+ const markdownInfoPath = path19.join(
7898
8191
  config2.__meta.rootDir,
7899
8192
  "node_modules/.apitogo/markdown-info.json"
7900
8193
  );
@@ -8046,9 +8339,9 @@ var remarkCodeTabs = () => (tree) => {
8046
8339
  };
8047
8340
 
8048
8341
  // src/vite/mdx/remark-inject-filepath.ts
8049
- import path19 from "node:path";
8342
+ import path20 from "node:path";
8050
8343
  var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
8051
- const relativePath = path19.relative(rootDir, vfile.path).split(path19.sep).join(path19.posix.sep);
8344
+ const relativePath = path20.relative(rootDir, vfile.path).split(path20.sep).join(path20.posix.sep);
8052
8345
  tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
8053
8346
  };
8054
8347
 
@@ -8135,18 +8428,18 @@ var remarkLastModified = () => {
8135
8428
  };
8136
8429
 
8137
8430
  // src/vite/mdx/remark-link-rewrite.ts
8138
- import path20 from "node:path";
8431
+ import path21 from "node:path";
8139
8432
  import { visit as visit5 } from "unist-util-visit";
8140
8433
  var remarkLinkRewrite = (basePath = "") => (tree) => {
8141
8434
  visit5(tree, "link", (node) => {
8142
8435
  if (!node.url) return;
8143
8436
  if (node.url.startsWith("http") || node.url.startsWith("mailto:")) return;
8144
8437
  node.url = node.url.replace(/\\/g, "/");
8145
- const base = path20.posix.join(basePath);
8438
+ const base = path21.posix.join(basePath);
8146
8439
  if (basePath && node.url.startsWith(base)) {
8147
8440
  node.url = node.url.slice(base.length);
8148
8441
  } else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
8149
- node.url = path20.posix.join("..", node.url);
8442
+ node.url = path21.posix.join("..", node.url);
8150
8443
  }
8151
8444
  node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
8152
8445
  });
@@ -8366,11 +8659,11 @@ var plugin_mdx_default = viteMdxPlugin;
8366
8659
 
8367
8660
  // src/vite/plugin-modules.ts
8368
8661
  init_loader();
8369
- import path21 from "node:path";
8662
+ import path22 from "node:path";
8370
8663
  import { normalizePath as normalizePath2 } from "vite";
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));
8664
+ var getLandingModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path22.join(moduleDir, "../module-landing/src/index.tsx")) : "@lukoweb/apitogo-module-landing";
8665
+ var getUserPanelModuleImport = (moduleDir, mode) => mode === "internal" ? normalizePath2(path22.join(moduleDir, "../module-user-panel/src/index.tsx")) : "@lukoweb/apitogo-module-user-panel";
8666
+ var resolveProjectPageImport = (rootDir, pagePath) => normalizePath2(path22.resolve(rootDir, pagePath));
8374
8667
  var viteModulesPlugin = () => {
8375
8668
  const virtualModuleId4 = "virtual:zudoku-modules-plugin";
8376
8669
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -8491,7 +8784,7 @@ var plugin_modules_default = viteModulesPlugin;
8491
8784
 
8492
8785
  // src/vite/plugin-search.ts
8493
8786
  init_loader();
8494
- import path22 from "node:path";
8787
+ import path23 from "node:path";
8495
8788
  var viteSearchPlugin = () => {
8496
8789
  const virtualModuleId4 = "virtual:zudoku-search-plugin";
8497
8790
  const resolvedVirtualModuleId5 = `\0${virtualModuleId4}`;
@@ -8509,7 +8802,7 @@ var viteSearchPlugin = () => {
8509
8802
  return resolvedVirtualModuleId5;
8510
8803
  }
8511
8804
  if (id === "/pagefind/pagefind.js" && resolvedViteConfig?.publicDir) {
8512
- return path22.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
8805
+ return path23.join(resolvedViteConfig.publicDir, "pagefind/pagefind.js");
8513
8806
  }
8514
8807
  },
8515
8808
  async load(id) {
@@ -8648,13 +8941,17 @@ function vitePlugin() {
8648
8941
  }
8649
8942
 
8650
8943
  // src/vite/config.ts
8944
+ var browserConfigLoaderPath2 = path24.join(
8945
+ getZudokuRootDir(),
8946
+ "src/config/apitogo-config-loader.browser.ts"
8947
+ );
8651
8948
  var resolveMergedPublicDir = (rootDir, merged) => {
8652
8949
  if (merged.publicDir === false) return void 0;
8653
8950
  const rel = typeof merged.publicDir === "string" ? merged.publicDir : "public";
8654
- return path23.resolve(rootDir, rel);
8951
+ return path24.resolve(rootDir, rel);
8655
8952
  };
8656
- var getAppClientEntryPath = () => path23.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
8657
- var getAppServerEntryPath = () => path23.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
8953
+ var getAppClientEntryPath = () => path24.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
8954
+ var getAppServerEntryPath = () => path24.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
8658
8955
  var hasLoggedCdnInfo = false;
8659
8956
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
8660
8957
  var defineEnvVars = (vars) => Object.fromEntries(
@@ -8684,7 +8981,7 @@ async function getViteConfig(dir, configEnv) {
8684
8981
  );
8685
8982
  if (ZuploEnv.isZuplo) {
8686
8983
  dotenv.config({
8687
- path: path23.resolve(config2.__meta.rootDir, "../.env.zuplo"),
8984
+ path: path24.resolve(config2.__meta.rootDir, "../.env.zuplo"),
8688
8985
  quiet: true
8689
8986
  });
8690
8987
  }
@@ -8705,6 +9002,22 @@ async function getViteConfig(dir, configEnv) {
8705
9002
  "@mdx-js/react": import.meta.resolve("@mdx-js/react")
8706
9003
  }
8707
9004
  },
9005
+ environments: {
9006
+ client: {
9007
+ resolve: {
9008
+ alias: {
9009
+ [path24.join(
9010
+ getZudokuRootDir(),
9011
+ "src/config/apitogo-config-loader.node.ts"
9012
+ )]: browserConfigLoaderPath2,
9013
+ [path24.join(
9014
+ getZudokuRootDir(),
9015
+ "src/config/apitogo-config-loader.node.js"
9016
+ )]: browserConfigLoaderPath2
9017
+ }
9018
+ }
9019
+ }
9020
+ },
8708
9021
  define: {
8709
9022
  "process.env.ZUDOKU_VERSION": JSON.stringify(package_default.version),
8710
9023
  "process.env.IS_ZUPLO": ZuploEnv.isZuplo,
@@ -8743,8 +9056,8 @@ async function getViteConfig(dir, configEnv) {
8743
9056
  ssr: configEnv.isSsrBuild,
8744
9057
  sourcemap: true,
8745
9058
  target: "es2022",
8746
- outDir: path23.resolve(
8747
- path23.join(
9059
+ outDir: path24.resolve(
9060
+ path24.join(
8748
9061
  dir,
8749
9062
  "dist",
8750
9063
  config2.basePath ?? "",
@@ -8763,7 +9076,7 @@ async function getViteConfig(dir, configEnv) {
8763
9076
  },
8764
9077
  experimental: {
8765
9078
  renderBuiltUrl(filename) {
8766
- if (cdnUrl?.base && [".js", ".css"].includes(path23.extname(filename))) {
9079
+ if (cdnUrl?.base && [".js", ".css"].includes(path24.extname(filename))) {
8767
9080
  return joinUrl(cdnUrl.base, filename);
8768
9081
  }
8769
9082
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -8776,7 +9089,7 @@ async function getViteConfig(dir, configEnv) {
8776
9089
  esbuildOptions: {
8777
9090
  target: "es2022"
8778
9091
  },
8779
- entries: [path23.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
9092
+ entries: [path24.posix.join(getZudokuRootDir(), "src/{app,lib}/**")],
8780
9093
  exclude: [
8781
9094
  "@lukoweb/apitogo",
8782
9095
  "@lukoweb/apitogo-plugin-dev-portal-billing"
@@ -8882,7 +9195,7 @@ init_package_json();
8882
9195
  init_joinUrl();
8883
9196
  import assert from "node:assert";
8884
9197
  import { cp, mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
8885
- import path24 from "node:path";
9198
+ import path25 from "node:path";
8886
9199
  var pkgJson = getZudokuPackageJson();
8887
9200
  function generateOutput({
8888
9201
  config: config2,
@@ -8939,9 +9252,9 @@ async function writeOutput(dir, {
8939
9252
  rewrites
8940
9253
  }) {
8941
9254
  const output = generateOutput({ config: config2, redirects, rewrites });
8942
- const outputDir = process.env.VERCEL ? path24.join(dir, ".vercel/output") : path24.join(dir, "dist/.output");
9255
+ const outputDir = process.env.VERCEL ? path25.join(dir, ".vercel/output") : path25.join(dir, "dist/.output");
8943
9256
  await mkdir3(outputDir, { recursive: true });
8944
- const outputFile = path24.join(outputDir, "config.json");
9257
+ const outputFile = path25.join(outputDir, "config.json");
8945
9258
  await writeFile3(outputFile, JSON.stringify(output, null, 2), "utf-8");
8946
9259
  if (process.env.VERCEL) {
8947
9260
  console.log("Wrote Vercel output to", outputDir);
@@ -8953,7 +9266,7 @@ init_logger();
8953
9266
  init_file_exists();
8954
9267
  import { readFile as readFile2, rm } from "node:fs/promises";
8955
9268
  import os from "node:os";
8956
- import path27 from "node:path";
9269
+ import path28 from "node:path";
8957
9270
  import { pathToFileURL } from "node:url";
8958
9271
  import { createIndex } from "pagefind";
8959
9272
  import colors7 from "picocolors";
@@ -8995,7 +9308,7 @@ function throttle(fn) {
8995
9308
  init_joinUrl();
8996
9309
  import { createWriteStream, existsSync as existsSync2 } from "node:fs";
8997
9310
  import { mkdir as mkdir4 } from "node:fs/promises";
8998
- import path25 from "node:path";
9311
+ import path26 from "node:path";
8999
9312
  import colors5 from "picocolors";
9000
9313
  import { SitemapStream } from "sitemap";
9001
9314
  async function generateSitemap({
@@ -9009,11 +9322,11 @@ async function generateSitemap({
9009
9322
  return;
9010
9323
  }
9011
9324
  const sitemap = new SitemapStream({ hostname: config2.siteUrl });
9012
- const outputDir = path25.resolve(baseOutputDir, config2.outDir ?? "");
9325
+ const outputDir = path26.resolve(baseOutputDir, config2.outDir ?? "");
9013
9326
  if (!existsSync2(outputDir)) {
9014
9327
  await mkdir4(outputDir, { recursive: true });
9015
9328
  }
9016
- const sitemapOutputPath = path25.join(outputDir, "sitemap.xml");
9329
+ const sitemapOutputPath = path26.join(outputDir, "sitemap.xml");
9017
9330
  const writeStream = createWriteStream(sitemapOutputPath);
9018
9331
  sitemap.pipe(writeStream);
9019
9332
  let lastmod;
@@ -9043,14 +9356,14 @@ async function generateSitemap({
9043
9356
 
9044
9357
  // src/vite/prerender/utils.ts
9045
9358
  init_joinUrl();
9046
- var resolveRoutePath = (path39) => {
9047
- const segments = path39.split("/");
9359
+ var resolveRoutePath = (path40) => {
9360
+ const segments = path40.split("/");
9048
9361
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
9049
9362
  return void 0;
9050
9363
  }
9051
9364
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
9052
9365
  };
9053
- var isSkipped = (path39) => path39.includes("*") || /^\d+$/.test(path39);
9366
+ var isSkipped = (path40) => path40.includes("*") || /^\d+$/.test(path40);
9054
9367
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
9055
9368
  if (route.path && isSkipped(route.path)) return [];
9056
9369
  const routePath = route.path ? resolveRoutePath(route.path) : void 0;
@@ -9099,12 +9412,12 @@ var prerender = async ({
9099
9412
  serverConfigFilename,
9100
9413
  writeRedirects = true
9101
9414
  }) => {
9102
- const distDir = path27.join(dir, "dist", basePath);
9415
+ const distDir = path28.join(dir, "dist", basePath);
9103
9416
  const serverConfigPath = pathToFileURL(
9104
- path27.join(distDir, "server", serverConfigFilename)
9417
+ path28.join(distDir, "server", serverConfigFilename)
9105
9418
  ).href;
9106
9419
  const entryServerPath = pathToFileURL(
9107
- path27.join(distDir, "server/entry.server.js")
9420
+ path28.join(distDir, "server/entry.server.js")
9108
9421
  ).href;
9109
9422
  const rawConfig = await import(serverConfigPath).then(
9110
9423
  (m) => m.default
@@ -9189,7 +9502,7 @@ var prerender = async ({
9189
9502
  })
9190
9503
  );
9191
9504
  const pagefindWriteResult = await pagefindIndex?.writeFiles({
9192
- outputPath: path27.join(distDir, "pagefind")
9505
+ outputPath: path28.join(distDir, "pagefind")
9193
9506
  });
9194
9507
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
9195
9508
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
@@ -9221,7 +9534,7 @@ var prerender = async ({
9221
9534
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
9222
9535
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
9223
9536
  const llmsConfig = docsConfig.llms ?? {};
9224
- const markdownInfoPath = path27.join(
9537
+ const markdownInfoPath = path28.join(
9225
9538
  dir,
9226
9539
  "node_modules/.apitogo/markdown-info.json"
9227
9540
  );
@@ -9312,7 +9625,7 @@ async function runBuild(options) {
9312
9625
  html,
9313
9626
  basePath: config2.basePath
9314
9627
  });
9315
- await rm2(path28.join(clientOutDir, "index.html"), { force: true });
9628
+ await rm2(path29.join(clientOutDir, "index.html"), { force: true });
9316
9629
  } else {
9317
9630
  await runPrerender({
9318
9631
  dir,
@@ -9336,7 +9649,7 @@ var runPrerender = async (options) => {
9336
9649
  serverConfigFilename,
9337
9650
  writeRedirects: process.env.VERCEL === void 0
9338
9651
  });
9339
- const indexHtml = path28.join(clientOutDir, "index.html");
9652
+ const indexHtml = path29.join(clientOutDir, "index.html");
9340
9653
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
9341
9654
  await writeFile5(indexHtml, html, "utf-8");
9342
9655
  }
@@ -9346,15 +9659,15 @@ var runPrerender = async (options) => {
9346
9659
  for (const statusPage of statusPages) {
9347
9660
  await rename(
9348
9661
  statusPage,
9349
- path28.join(dir, DIST_DIR, path28.basename(statusPage))
9662
+ path29.join(dir, DIST_DIR, path29.basename(statusPage))
9350
9663
  );
9351
9664
  }
9352
9665
  await rm2(serverOutDir, { recursive: true, force: true });
9353
9666
  if (process.env.VERCEL) {
9354
- await mkdir5(path28.join(dir, ".vercel/output/static"), { recursive: true });
9667
+ await mkdir5(path29.join(dir, ".vercel/output/static"), { recursive: true });
9355
9668
  await rename(
9356
- path28.join(dir, DIST_DIR),
9357
- path28.join(dir, ".vercel/output/static")
9669
+ path29.join(dir, DIST_DIR),
9670
+ path29.join(dir, ".vercel/output/static")
9358
9671
  );
9359
9672
  }
9360
9673
  await writeOutput(dir, {
@@ -9364,7 +9677,7 @@ var runPrerender = async (options) => {
9364
9677
  });
9365
9678
  if (ZuploEnv.isZuplo && issuer) {
9366
9679
  await writeFile5(
9367
- path28.join(dir, DIST_DIR, ".output/zuplo.json"),
9680
+ path29.join(dir, DIST_DIR, ".output/zuplo.json"),
9368
9681
  JSON.stringify({ issuer }, null, 2),
9369
9682
  "utf-8"
9370
9683
  );
@@ -9376,10 +9689,10 @@ var runPrerender = async (options) => {
9376
9689
  };
9377
9690
  var bundleSSREntry = async (options) => {
9378
9691
  const { dir, adapter, serverOutDir, serverConfigFilename, html, basePath } = options;
9379
- const tempEntryPath = path28.join(dir, "__ssr-entry.ts");
9692
+ const tempEntryPath = path29.join(dir, "__ssr-entry.ts");
9380
9693
  const packageRoot = getZudokuRootDir();
9381
9694
  const templateContent = await readFile3(
9382
- path28.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
9695
+ path29.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
9383
9696
  "utf-8"
9384
9697
  );
9385
9698
  const entryContent = templateContent.replace('"__TEMPLATE__"', JSON.stringify(html)).replace('"__CONFIG_FILE__"', JSON.stringify(`./${serverConfigFilename}`)).replace(
@@ -9394,9 +9707,9 @@ var bundleSSREntry = async (options) => {
9394
9707
  platform: adapter === "node" ? "node" : "neutral",
9395
9708
  target: "es2022",
9396
9709
  format: "esm",
9397
- outfile: path28.join(serverOutDir, "entry.js"),
9710
+ outfile: path29.join(serverOutDir, "entry.js"),
9398
9711
  external: ["./entry.server.js", `./${serverConfigFilename}`],
9399
- nodePaths: [path28.join(packageRoot, "node_modules")],
9712
+ nodePaths: [path29.join(packageRoot, "node_modules")],
9400
9713
  banner: { js: "// Bundled SSR entry" }
9401
9714
  });
9402
9715
  } finally {
@@ -9451,11 +9764,11 @@ function textOrJson(text) {
9451
9764
  init_package_json();
9452
9765
 
9453
9766
  // src/cli/preview/handler.ts
9454
- import path29 from "node:path";
9767
+ import path30 from "node:path";
9455
9768
  import { preview as vitePreview } from "vite";
9456
9769
  var DEFAULT_PREVIEW_PORT = 4e3;
9457
9770
  async function preview(argv) {
9458
- const dir = path29.resolve(process.cwd(), argv.dir);
9771
+ const dir = path30.resolve(process.cwd(), argv.dir);
9459
9772
  const viteConfig = await getViteConfig(dir, {
9460
9773
  command: "serve",
9461
9774
  mode: "production",
@@ -9496,7 +9809,7 @@ async function build(argv) {
9496
9809
  printDiagnosticsToConsole("");
9497
9810
  printDiagnosticsToConsole("");
9498
9811
  }
9499
- const dir = path30.resolve(process.cwd(), argv.dir);
9812
+ const dir = path31.resolve(process.cwd(), argv.dir);
9500
9813
  try {
9501
9814
  await runBuild({
9502
9815
  dir,
@@ -9656,7 +9969,7 @@ var build_default = {
9656
9969
  // src/cli/configure-github-workflow/handler.ts
9657
9970
  import { constants } from "node:fs";
9658
9971
  import { access, mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
9659
- import path31 from "node:path";
9972
+ import path32 from "node:path";
9660
9973
  var APITOGO_DEPLOY_WORKFLOW_YAML = `name: Build and Deploy
9661
9974
 
9662
9975
  on:
@@ -9767,9 +10080,9 @@ jobs:
9767
10080
  run: apitogo deploy --deployment-token="$APITOGO_TOKEN" --json-only
9768
10081
  `;
9769
10082
  async function configureGithubWorkflow(argv) {
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");
10083
+ const dir = path32.resolve(process.cwd(), argv.dir);
10084
+ const workflowDir = path32.join(dir, ".github", "workflows");
10085
+ const workflowPath = path32.join(workflowDir, "apitogo-deploy.yml");
9773
10086
  try {
9774
10087
  try {
9775
10088
  await access(workflowPath, constants.F_OK);
@@ -9842,14 +10155,14 @@ function applyJsonOnlyDeployQuietMode() {
9842
10155
 
9843
10156
  // src/cli/deploy/handler.ts
9844
10157
  import { access as access2, readFile as readFile4 } from "node:fs/promises";
9845
- import path32 from "node:path";
10158
+ import path33 from "node:path";
9846
10159
  import { create as createTar } from "tar";
9847
10160
  var DEPLOY_ENDPOINT = "https://deploy-server-dotnet2-b3fkcaaraydbckfe.canadacentral-01.azurewebsites.net/deploy";
9848
10161
  var ARCHIVE_NAME = "dist.tgz";
9849
10162
  var createDeploymentArchive = async (dir) => {
9850
- const distDir = path32.join(dir, "dist");
10163
+ const distDir = path33.join(dir, "dist");
9851
10164
  await access2(distDir);
9852
- const archivePath = path32.join(dir, ARCHIVE_NAME);
10165
+ const archivePath = path33.join(dir, ARCHIVE_NAME);
9853
10166
  await createTar(
9854
10167
  {
9855
10168
  cwd: dir,
@@ -9863,7 +10176,7 @@ var createDeploymentArchive = async (dir) => {
9863
10176
  };
9864
10177
  async function deploy(argv) {
9865
10178
  await build({ ...argv, preview: void 0 });
9866
- const dir = path32.resolve(process.cwd(), argv.dir);
10179
+ const dir = path33.resolve(process.cwd(), argv.dir);
9867
10180
  const deploymentToken = argv.deploymentToken?.trim() || process.env.npm_config_deployment_token?.trim();
9868
10181
  const env = argv.env?.trim() || process.env.npm_config_env?.trim() || "production";
9869
10182
  try {
@@ -9876,7 +10189,7 @@ async function deploy(argv) {
9876
10189
  const archivePath = await createDeploymentArchive(dir);
9877
10190
  if (!isJsonOnlyDeployEnv()) {
9878
10191
  printDiagnosticsToConsole(
9879
- `Uploading ${path32.basename(archivePath)} to ${env}...`
10192
+ `Uploading ${path33.basename(archivePath)} to ${env}...`
9880
10193
  );
9881
10194
  }
9882
10195
  const archiveBuffer = await readFile4(archivePath);
@@ -9884,7 +10197,7 @@ async function deploy(argv) {
9884
10197
  formData.append(
9885
10198
  "file",
9886
10199
  new Blob([archiveBuffer], { type: "application/gzip" }),
9887
- path32.basename(archivePath)
10200
+ path33.basename(archivePath)
9888
10201
  );
9889
10202
  formData.append("deploymentToken", deploymentToken);
9890
10203
  formData.append("env", env);
@@ -9969,14 +10282,14 @@ var deploy_default = {
9969
10282
 
9970
10283
  // src/cli/dev/handler.ts
9971
10284
  init_joinUrl();
9972
- import path35 from "node:path";
10285
+ import path36 from "node:path";
9973
10286
 
9974
10287
  // src/vite/dev-server.ts
9975
10288
  init_logger();
9976
10289
  import fs4 from "node:fs/promises";
9977
10290
  import http from "node:http";
9978
10291
  import https from "node:https";
9979
- import path34 from "node:path";
10292
+ import path35 from "node:path";
9980
10293
  import { createHttpTerminator } from "http-terminator";
9981
10294
  import {
9982
10295
  createServer as createViteServer,
@@ -10009,7 +10322,7 @@ init_loader();
10009
10322
  // src/vite/pagefind-dev-index.ts
10010
10323
  init_invariant();
10011
10324
  init_joinUrl();
10012
- import path33 from "node:path";
10325
+ import path34 from "node:path";
10013
10326
  import { createIndex as createIndex2 } from "pagefind";
10014
10327
  import { isRunnableDevEnvironment } from "vite";
10015
10328
  async function* buildPagefindDevIndex(vite, config2) {
@@ -10062,7 +10375,7 @@ async function* buildPagefindDevIndex(vite, config2) {
10062
10375
  path: urlPath
10063
10376
  };
10064
10377
  }
10065
- const outputPath = path33.join(vite.config.publicDir, "pagefind");
10378
+ const outputPath = path34.join(vite.config.publicDir, "pagefind");
10066
10379
  await pagefindIndex.writeFiles({ outputPath });
10067
10380
  yield { type: "complete", success: true, indexed };
10068
10381
  }
@@ -10081,9 +10394,9 @@ var DevServer = class {
10081
10394
  this.protocol = "https";
10082
10395
  const { dir } = this.options;
10083
10396
  const [key, cert, ca] = await Promise.all([
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
10397
+ fs4.readFile(path35.resolve(dir, config2.https.key)),
10398
+ fs4.readFile(path35.resolve(dir, config2.https.cert)),
10399
+ config2.https.ca ? fs4.readFile(path35.resolve(dir, config2.https.ca)) : void 0
10087
10400
  ]);
10088
10401
  return https.createServer({ key, cert, ca });
10089
10402
  }
@@ -10100,7 +10413,7 @@ var DevServer = class {
10100
10413
  );
10101
10414
  const server = await this.createNodeServer(config2);
10102
10415
  if (config2.search?.type === "pagefind" && viteConfig.publicDir !== false) {
10103
- const publicRoot = path34.resolve(
10416
+ const publicRoot = path35.resolve(
10104
10417
  this.options.dir,
10105
10418
  typeof viteConfig.publicDir === "string" ? viteConfig.publicDir : "public"
10106
10419
  );
@@ -10117,7 +10430,7 @@ var DevServer = class {
10117
10430
  // built-in transform middleware which would treat the path as a static asset.
10118
10431
  name: "apitogo:entry-client",
10119
10432
  configureServer(server2) {
10120
- const entryPath = path34.posix.join(
10433
+ const entryPath = path35.posix.join(
10121
10434
  server2.config.base,
10122
10435
  "/__z/entry.client.tsx"
10123
10436
  );
@@ -10282,7 +10595,7 @@ init_package_json();
10282
10595
  async function dev(argv) {
10283
10596
  const packageJson2 = getZudokuPackageJson();
10284
10597
  process.env.NODE_ENV = "development";
10285
- const dir = path35.resolve(process.cwd(), argv.dir);
10598
+ const dir = path36.resolve(process.cwd(), argv.dir);
10286
10599
  const server = new DevServer({
10287
10600
  dir,
10288
10601
  argPort: argv.port,
@@ -10367,14 +10680,14 @@ var dev_default = {
10367
10680
  // src/cli/make-config/handler.ts
10368
10681
  import { constants as constants3 } from "node:fs";
10369
10682
  import { access as access4, mkdir as mkdir7, readFile as readFile6, writeFile as writeFile8 } from "node:fs/promises";
10370
- import path37 from "node:path";
10683
+ import path38 from "node:path";
10371
10684
  import { glob as glob5 } from "glob";
10372
10685
 
10373
10686
  // src/cli/make-config/scaffold-project.ts
10374
10687
  init_package_json();
10375
10688
  import { constants as constants2 } from "node:fs";
10376
10689
  import { access as access3, readFile as readFile5, writeFile as writeFile7 } from "node:fs/promises";
10377
- import path36 from "node:path";
10690
+ import path37 from "node:path";
10378
10691
  import { glob as glob4 } from "glob";
10379
10692
  var OPENAPI_GLOBS = [
10380
10693
  "apis/openapi.json",
@@ -10434,9 +10747,9 @@ var findMatchingCurly = (source, startIndex) => {
10434
10747
  }
10435
10748
  throw new Error("Could not find matching closing brace for object.");
10436
10749
  };
10437
- var toPosix = (p) => p.split(path36.sep).join("/");
10750
+ var toPosix = (p) => p.split(path37.sep).join("/");
10438
10751
  var sanitizePackageName = (dir) => {
10439
- const base = path36.basename(path36.resolve(dir));
10752
+ const base = path37.basename(path37.resolve(dir));
10440
10753
  const s = base.toLowerCase().replace(/[^a-z0-9-_.]/g, "-").replace(/^-+|-+$/g, "");
10441
10754
  return s || "apitogo-site";
10442
10755
  };
@@ -10446,7 +10759,7 @@ var apitogoVersionRange = () => {
10446
10759
  };
10447
10760
  async function findOpenApiSpecPath(dir) {
10448
10761
  for (const rel of OPENAPI_GLOBS) {
10449
- const full = path36.join(dir, rel);
10762
+ const full = path37.join(dir, rel);
10450
10763
  try {
10451
10764
  await access3(full, constants2.R_OK);
10452
10765
  return toPosix(rel);
@@ -10461,7 +10774,7 @@ async function findOpenApiSpecPath(dir) {
10461
10774
  return extra[0] ? toPosix(extra[0]) : null;
10462
10775
  }
10463
10776
  async function ensurePackageJson(dir) {
10464
- const pkgPath = path36.join(dir, "package.json");
10777
+ const pkgPath = path37.join(dir, "package.json");
10465
10778
  const apitogoVer = apitogoVersionRange();
10466
10779
  const baseDeps = {
10467
10780
  react: ">=19.0.0",
@@ -10524,7 +10837,7 @@ async function ensurePackageJson(dir) {
10524
10837
  return false;
10525
10838
  }
10526
10839
  async function ensureTsconfigJson(dir) {
10527
- const tsPath = path36.join(dir, "tsconfig.json");
10840
+ const tsPath = path37.join(dir, "tsconfig.json");
10528
10841
  try {
10529
10842
  await access3(tsPath, constants2.R_OK);
10530
10843
  return false;
@@ -10606,7 +10919,7 @@ var CONFIG_FILENAMES = [
10606
10919
  ];
10607
10920
  var DEFAULT_NEW_CONFIG_FILENAME = "apitogo.config.tsx";
10608
10921
  var createTreeNode = () => ({ docs: [], children: /* @__PURE__ */ new Map() });
10609
- var toPosixPath2 = (value) => value.split(path37.sep).join(path37.posix.sep);
10922
+ var toPosixPath2 = (value) => value.split(path38.sep).join(path38.posix.sep);
10610
10923
  var toRoutePath = (relativeFile, pagesDir) => {
10611
10924
  const relativeNoExt = relativeFile.replace(/\.mdx?$/, "");
10612
10925
  const withoutPagesPrefix = relativeNoExt.replace(
@@ -10851,7 +11164,7 @@ export default config;
10851
11164
  `;
10852
11165
  };
10853
11166
  var ensureApitogoDeployWorkflow = async (dir) => {
10854
- const workflowPath = path37.join(
11167
+ const workflowPath = path38.join(
10855
11168
  dir,
10856
11169
  ".github",
10857
11170
  "workflows",
@@ -10862,13 +11175,13 @@ var ensureApitogoDeployWorkflow = async (dir) => {
10862
11175
  return false;
10863
11176
  } catch {
10864
11177
  }
10865
- await mkdir7(path37.join(dir, ".github", "workflows"), { recursive: true });
11178
+ await mkdir7(path38.join(dir, ".github", "workflows"), { recursive: true });
10866
11179
  await writeFile8(workflowPath, APITOGO_DEPLOY_WORKFLOW_YAML, "utf8");
10867
11180
  return true;
10868
11181
  };
10869
11182
  var findExistingConfigPath = async (dir) => {
10870
11183
  for (const filename of CONFIG_FILENAMES) {
10871
- const fullPath = path37.join(dir, filename);
11184
+ const fullPath = path38.join(dir, filename);
10872
11185
  try {
10873
11186
  await readFile6(fullPath, "utf8");
10874
11187
  return fullPath;
@@ -10878,7 +11191,7 @@ var findExistingConfigPath = async (dir) => {
10878
11191
  return null;
10879
11192
  };
10880
11193
  async function makeConfig(argv) {
10881
- const dir = path37.resolve(process.cwd(), argv.dir);
11194
+ const dir = path38.resolve(process.cwd(), argv.dir);
10882
11195
  const pagesDir = toPosixPath2(
10883
11196
  argv.pagesDir.replace(/^[./]+/, "").replace(/\/+$/, "")
10884
11197
  );
@@ -10897,7 +11210,7 @@ async function makeConfig(argv) {
10897
11210
  let configPath = await findExistingConfigPath(dir);
10898
11211
  let createdNew = false;
10899
11212
  if (!configPath) {
10900
- configPath = path37.join(dir, DEFAULT_NEW_CONFIG_FILENAME);
11213
+ configPath = path38.join(dir, DEFAULT_NEW_CONFIG_FILENAME);
10901
11214
  await writeFile8(
10902
11215
  configPath,
10903
11216
  buildNewConfigContents(pagesDir, openApiSpecPath),
@@ -10938,7 +11251,7 @@ async function makeConfig(argv) {
10938
11251
  await writeFile8(configPath, withRedirects, "utf8");
10939
11252
  const action = createdNew ? "Initialized" : "Updated";
10940
11253
  printResultToConsole(
10941
- `${action} ${path37.basename(configPath)} from ${pagesDir}/ (navigation and redirects; other top-level settings preserved unless newly scaffolded).`
11254
+ `${action} ${path38.basename(configPath)} from ${pagesDir}/ (navigation and redirects; other top-level settings preserved unless newly scaffolded).`
10942
11255
  );
10943
11256
  const createdWorkflow = await ensureApitogoDeployWorkflow(dir);
10944
11257
  if (createdWorkflow) {
@@ -11131,12 +11444,12 @@ function box(message, {
11131
11444
 
11132
11445
  // src/cli/common/xdg/lib.ts
11133
11446
  import { homedir } from "node:os";
11134
- import path38 from "node:path";
11447
+ import path39 from "node:path";
11135
11448
  function defineDirectoryWithFallback(xdgName, fallback) {
11136
11449
  if (process.env[xdgName]) {
11137
11450
  return process.env[xdgName];
11138
11451
  } else {
11139
- return path38.join(homedir(), fallback);
11452
+ return path39.join(homedir(), fallback);
11140
11453
  }
11141
11454
  }
11142
11455
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -11151,15 +11464,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
11151
11464
  "XDG_DATA_HOME",
11152
11465
  ".local/state"
11153
11466
  );
11154
- var ZUDOKU_XDG_CONFIG_HOME = path38.join(
11467
+ var ZUDOKU_XDG_CONFIG_HOME = path39.join(
11155
11468
  XDG_CONFIG_HOME,
11156
11469
  CLI_XDG_FOLDER_NAME
11157
11470
  );
11158
- var ZUDOKU_XDG_DATA_HOME = path38.join(
11471
+ var ZUDOKU_XDG_DATA_HOME = path39.join(
11159
11472
  XDG_DATA_HOME,
11160
11473
  CLI_XDG_FOLDER_NAME
11161
11474
  );
11162
- var ZUDOKU_XDG_STATE_HOME = path38.join(
11475
+ var ZUDOKU_XDG_STATE_HOME = path39.join(
11163
11476
  XDG_STATE_HOME,
11164
11477
  CLI_XDG_FOLDER_NAME
11165
11478
  );