zudoku 0.71.9 → 0.72.0

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 (144) hide show
  1. package/dist/cli/cli.js +127 -94
  2. package/dist/cli/worker.js +5 -4
  3. package/dist/declarations/app/utils/createRedirectRoutes.d.ts +1 -1
  4. package/dist/declarations/config/config.d.ts +1 -1
  5. package/dist/declarations/config/loader.d.ts +1 -1
  6. package/dist/declarations/config/validators/{validate.d.ts → ZudokuConfig.d.ts} +44 -0
  7. package/dist/declarations/lib/authentication/AuthenticationPlugin.d.ts +1 -6
  8. package/dist/declarations/lib/components/AiAssistantMenuItems.d.ts +6 -0
  9. package/dist/declarations/lib/core/ZudokuContext.d.ts +3 -1
  10. package/dist/declarations/lib/core/plugins.d.ts +1 -1
  11. package/dist/declarations/lib/core/transform-config.d.ts +1 -1
  12. package/dist/declarations/lib/plugins/api-keys/index.d.ts +1 -1
  13. package/dist/declarations/lib/plugins/markdown/index.d.ts +1 -1
  14. package/dist/declarations/lib/plugins/openapi/schema/SchemaView.d.ts +1 -1
  15. package/dist/declarations/lib/plugins/search-pagefind/index.d.ts +1 -1
  16. package/dist/declarations/lib/testing/index.d.ts +1 -1
  17. package/dist/declarations/zuplo/with-zuplo.d.ts +1 -1
  18. package/dist/flat-config.d.ts +6 -0
  19. package/docs/components/alert.mdx +130 -0
  20. package/docs/components/badge.mdx +70 -0
  21. package/docs/components/button.mdx +132 -0
  22. package/docs/components/callout.mdx +112 -0
  23. package/docs/components/card.mdx +104 -0
  24. package/docs/components/checkbox.mdx +72 -0
  25. package/docs/components/client-only.mdx +79 -0
  26. package/docs/components/code-tabs.mdx +179 -0
  27. package/docs/components/dialog.mdx +167 -0
  28. package/docs/components/head.mdx +200 -0
  29. package/docs/components/icons.mdx +27 -0
  30. package/docs/components/input.mdx +96 -0
  31. package/docs/components/label.mdx +86 -0
  32. package/docs/components/link.mdx +242 -0
  33. package/docs/components/markdown.mdx +151 -0
  34. package/docs/components/mermaid.mdx +81 -0
  35. package/docs/components/playground.mdx +87 -0
  36. package/docs/components/secret.mdx +79 -0
  37. package/docs/components/select.mdx +176 -0
  38. package/docs/components/shadcn.mdx +73 -0
  39. package/docs/components/slider.mdx +108 -0
  40. package/docs/components/slot.mdx +119 -0
  41. package/docs/components/stepper.mdx +138 -0
  42. package/docs/components/switch.mdx +96 -0
  43. package/docs/components/syntax-highlight.mdx +602 -0
  44. package/docs/components/textarea.mdx +78 -0
  45. package/docs/components/tooltip.mdx +195 -0
  46. package/docs/components/typography.mdx +61 -0
  47. package/docs/concepts/auth-provider-api-identities.md +109 -0
  48. package/docs/configuration/ai-assistants.md +65 -0
  49. package/docs/configuration/api-catalog.md +109 -0
  50. package/docs/configuration/api-reference.md +397 -0
  51. package/docs/configuration/authentication-auth0.md +174 -0
  52. package/docs/configuration/authentication-azure-ad.md +238 -0
  53. package/docs/configuration/authentication-clerk.md +110 -0
  54. package/docs/configuration/authentication-firebase.md +62 -0
  55. package/docs/configuration/authentication-pingfederate.md +136 -0
  56. package/docs/configuration/authentication-supabase.md +226 -0
  57. package/docs/configuration/authentication.md +199 -0
  58. package/docs/configuration/build-configuration.mdx +147 -0
  59. package/docs/configuration/docs.md +282 -0
  60. package/docs/configuration/footer.mdx +214 -0
  61. package/docs/configuration/llms.md +90 -0
  62. package/docs/configuration/navigation.mdx +408 -0
  63. package/docs/configuration/overview.md +380 -0
  64. package/docs/configuration/protected-routes.md +150 -0
  65. package/docs/configuration/search.md +170 -0
  66. package/docs/configuration/sentry.mdx +44 -0
  67. package/docs/configuration/site.md +124 -0
  68. package/docs/configuration/slots.mdx +125 -0
  69. package/docs/configuration/vite-config.md +18 -0
  70. package/docs/custom-plugins.md +288 -0
  71. package/docs/customization/colors-theme.mdx +275 -0
  72. package/docs/customization/fonts.md +110 -0
  73. package/docs/deploy/apache-nginx.md +41 -0
  74. package/docs/deploy/cloudflare-pages.md +75 -0
  75. package/docs/deploy/direct-upload.md +18 -0
  76. package/docs/deploy/github-pages.md +50 -0
  77. package/docs/deploy/vercel.md +103 -0
  78. package/docs/deploy/zuplo.md +110 -0
  79. package/docs/deployment.md +21 -0
  80. package/docs/extending/events.md +124 -0
  81. package/docs/guides/custom-pages.md +106 -0
  82. package/docs/guides/environment-variables.md +99 -0
  83. package/docs/guides/managing-api-keys-and-identities.md +172 -0
  84. package/docs/guides/mermaid.mdx +70 -0
  85. package/docs/guides/navigation-migration.md +87 -0
  86. package/docs/guides/navigation-rules.mdx +197 -0
  87. package/docs/guides/processors.mdx +234 -0
  88. package/docs/guides/static-files.md +55 -0
  89. package/docs/guides/transforming-examples.md +156 -0
  90. package/docs/guides/using-multiple-apis.md +87 -0
  91. package/docs/markdown/admonitions.md +128 -0
  92. package/docs/markdown/code-blocks.md +196 -0
  93. package/docs/markdown/frontmatter.md +173 -0
  94. package/docs/markdown/mdx.md +68 -0
  95. package/docs/markdown/overview.md +275 -0
  96. package/docs/plugins.md +5 -0
  97. package/docs/quickstart.md +57 -0
  98. package/docs/writing.mdx +72 -0
  99. package/package.json +10 -8
  100. package/src/app/demo.tsx +1 -1
  101. package/src/app/main.tsx +1 -0
  102. package/src/app/standalone.tsx +1 -1
  103. package/src/app/utils/createRedirectRoutes.ts +1 -1
  104. package/src/config/config.ts +1 -1
  105. package/src/config/loader.ts +2 -2
  106. package/src/config/validators/NavigationSchema.ts +1 -1
  107. package/src/config/validators/{validate.ts → ZudokuConfig.ts} +26 -0
  108. package/src/lib/auth/issuer.ts +1 -1
  109. package/src/lib/authentication/AuthenticationPlugin.tsx +1 -9
  110. package/src/lib/authentication/components/OAuthErrorPage.tsx +6 -10
  111. package/src/lib/authentication/providers/openid.tsx +14 -1
  112. package/src/lib/components/AiAssistantMenuItems.tsx +102 -0
  113. package/src/lib/components/DeveloperHint.tsx +1 -1
  114. package/src/lib/components/Footer.tsx +1 -1
  115. package/src/lib/components/Header.tsx +11 -4
  116. package/src/lib/components/Layout.tsx +2 -2
  117. package/src/lib/components/MobileTopNavigation.tsx +17 -3
  118. package/src/lib/core/RouteGuard.tsx +6 -5
  119. package/src/lib/core/ZudokuContext.ts +6 -1
  120. package/src/lib/core/plugins.ts +1 -1
  121. package/src/lib/core/transform-config.ts +1 -1
  122. package/src/lib/oas/parser/dereference/index.ts +24 -6
  123. package/src/lib/plugins/api-keys/index.tsx +1 -1
  124. package/src/lib/plugins/markdown/MdxPage.tsx +24 -46
  125. package/src/lib/plugins/markdown/index.tsx +1 -1
  126. package/src/lib/plugins/openapi/DownloadSchemaButton.tsx +8 -24
  127. package/src/lib/plugins/openapi/playground/Playground.tsx +3 -2
  128. package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +17 -7
  129. package/src/lib/plugins/openapi/schema/SchemaView.tsx +193 -72
  130. package/src/lib/plugins/search-pagefind/index.tsx +1 -1
  131. package/src/lib/testing/index.tsx +2 -2
  132. package/src/lib/util/joinUrl.ts +6 -3
  133. package/src/lib/util/problemJson.ts +36 -1
  134. package/src/vite/api/SchemaManager.ts +1 -1
  135. package/src/vite/api/schema-codegen.ts +63 -94
  136. package/src/vite/config.ts +1 -1
  137. package/src/vite/plugin-docs.ts +1 -1
  138. package/src/vite/plugin-markdown-export.ts +7 -6
  139. package/src/vite/plugin-theme.ts +1 -1
  140. package/src/vite/prerender/prerender.ts +13 -4
  141. package/src/vite/prerender/worker.ts +1 -1
  142. package/src/vite/sitemap.ts +1 -1
  143. package/src/zuplo/with-zuplo.ts +1 -1
  144. package/src/ts.ts +0 -92
package/dist/cli/cli.js CHANGED
@@ -2814,14 +2814,15 @@ var init_joinUrl = __esm({
2814
2814
  ).map((part) => `${part}`).filter((part) => part);
2815
2815
  parseParts = (parts) => {
2816
2816
  const partsStr = parts.join("/");
2817
- const [, prefix = "", pathname = ""] = partsStr.match(defaultUrlRegExp) ?? [];
2817
+ const [, prefix = "", pathname = "", query = ""] = partsStr.match(defaultUrlRegExp) ?? [];
2818
2818
  return {
2819
2819
  prefix,
2820
- pathname: pathname.split("/").filter((part) => part !== "")
2820
+ pathname: pathname.split("/").filter((part) => part !== ""),
2821
+ query
2821
2822
  };
2822
2823
  };
2823
2824
  buildUrl = (parsedParts) => {
2824
- const { prefix, pathname } = parsedParts;
2825
+ const { prefix, pathname, query } = parsedParts;
2825
2826
  let url = prefix;
2826
2827
  if (pathname.length > 0) {
2827
2828
  if (url) {
@@ -2833,7 +2834,7 @@ var init_joinUrl = __esm({
2833
2834
  } else if (!url) {
2834
2835
  url = "/";
2835
2836
  }
2836
- return url;
2837
+ return url + query;
2837
2838
  };
2838
2839
  joinUrl = (...parts) => {
2839
2840
  const normalizedParts = normalizeParts(parts);
@@ -2885,9 +2886,9 @@ var init_ProtectedRoutesSchema = __esm({
2885
2886
  }
2886
2887
  });
2887
2888
 
2888
- // src/config/validators/validate.ts
2889
- var validate_exports = {};
2890
- __export(validate_exports, {
2889
+ // src/config/validators/ZudokuConfig.ts
2890
+ var ZudokuConfig_exports = {};
2891
+ __export(ZudokuConfig_exports, {
2891
2892
  CdnUrlSchema: () => CdnUrlSchema,
2892
2893
  DocsConfigSchema: () => DocsConfigSchema,
2893
2894
  FooterSchema: () => FooterSchema,
@@ -2912,9 +2913,9 @@ ${z7.prettifyError(validationResult.error)}`
2912
2913
  console.log(colors.yellow(z7.prettifyError(validationResult.error)));
2913
2914
  }
2914
2915
  }
2915
- var ThemeSchema, ApiCatalogCategorySchema, LanguageOption, 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;
2916
- var init_validate = __esm({
2917
- "src/config/validators/validate.ts"() {
2916
+ 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;
2917
+ var init_ZudokuConfig = __esm({
2918
+ "src/config/validators/ZudokuConfig.ts"() {
2918
2919
  init_plugin_theme();
2919
2920
  init_HeaderNavigationSchema();
2920
2921
  init_InputNavigationSchema();
@@ -2949,6 +2950,19 @@ var init_validate = __esm({
2949
2950
  value: z7.string().min(1),
2950
2951
  label: z7.string().min(1)
2951
2952
  });
2953
+ AiAssistantCustomSchema = z7.object({
2954
+ label: z7.string(),
2955
+ icon: z7.custom().optional(),
2956
+ url: z7.union([
2957
+ z7.string(),
2958
+ z7.custom((val) => typeof val === "function")
2959
+ ])
2960
+ });
2961
+ AiAssistantPresets = ["claude", "chatgpt"];
2962
+ AiAssistantsSchema = z7.union([
2963
+ z7.literal(false),
2964
+ z7.array(z7.union([z7.enum(AiAssistantPresets), AiAssistantCustomSchema]))
2965
+ ]).optional();
2952
2966
  ApiOptionsSchema = z7.object({
2953
2967
  examplesLanguage: z7.string(),
2954
2968
  supportedLanguages: z7.array(LanguageOption),
@@ -3012,7 +3026,8 @@ var init_validate = __esm({
3012
3026
  src: z7.object({ light: z7.string(), dark: z7.string() }),
3013
3027
  alt: z7.string().optional(),
3014
3028
  width: z7.string().or(z7.number()).optional(),
3015
- href: z7.string().optional()
3029
+ href: z7.string().optional(),
3030
+ reloadDocument: z7.boolean().optional()
3016
3031
  });
3017
3032
  FooterSocialIcons = [
3018
3033
  "reddit",
@@ -3385,6 +3400,7 @@ var init_validate = __esm({
3385
3400
  apis: z7.union([ApiSchema, z7.array(ApiSchema)]),
3386
3401
  catalogs: z7.union([ApiCatalogSchema, z7.array(ApiCatalogSchema)]),
3387
3402
  apiKeys: ApiKeysSchema,
3403
+ aiAssistants: AiAssistantsSchema,
3388
3404
  redirects: z7.array(Redirect),
3389
3405
  sitemap: SiteMapSchema,
3390
3406
  enableStatusPages: z7.boolean().optional(),
@@ -3536,7 +3552,7 @@ var init_loader = __esm({
3536
3552
  init_transform_config();
3537
3553
  init_invariant();
3538
3554
  init_file_exists();
3539
- init_validate();
3555
+ init_ZudokuConfig();
3540
3556
  zudokuConfigFiles = [
3541
3557
  "zudoku.config.js",
3542
3558
  "zudoku.config.jsx",
@@ -3794,7 +3810,7 @@ import {
3794
3810
  // package.json
3795
3811
  var package_default = {
3796
3812
  name: "zudoku",
3797
- version: "0.71.8",
3813
+ version: "0.71.10",
3798
3814
  type: "module",
3799
3815
  sideEffects: [
3800
3816
  "**/*.css",
@@ -3813,7 +3829,8 @@ var package_default = {
3813
3829
  "dist",
3814
3830
  "cli.js",
3815
3831
  "src",
3816
- "client.d.ts"
3832
+ "client.d.ts",
3833
+ "docs"
3817
3834
  ],
3818
3835
  bin: {
3819
3836
  zudoku: "./cli.js"
@@ -3854,17 +3871,17 @@ var package_default = {
3854
3871
  "./vite": "./src/vite/index.ts",
3855
3872
  "./app/*": "./src/app/*",
3856
3873
  "./hooks": "./src/lib/hooks/index.ts",
3857
- "./main.css": "./src/app/main.css",
3858
3874
  "./processors/*": "./src/lib/plugins/openapi/processors/*.ts",
3859
3875
  "./with-zuplo": "./src/zuplo/with-zuplo.ts",
3860
3876
  "./testing": "./src/lib/testing/index.tsx"
3861
3877
  },
3862
3878
  scripts: {
3863
3879
  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",
3880
+ postbuild: "tsx scripts/check-external-deps.ts",
3864
3881
  typecheck: "tsc --project tsconfig.app.json --noEmit",
3865
3882
  "generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
3866
3883
  "build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
3867
- prepublishOnly: "tsx scripts/generate-publish-exports.ts",
3884
+ prepublishOnly: "tsx scripts/generate-publish-exports.ts && publint .",
3868
3885
  postpublish: "git checkout -- package.json",
3869
3886
  clean: "rm -rf dist",
3870
3887
  codegen: "graphql-codegen --config ./src/codegen.ts"
@@ -3910,7 +3927,7 @@ var package_default = {
3910
3927
  "@shikijs/transformers": "3.23.0",
3911
3928
  "@tailwindcss/typography": "0.5.19",
3912
3929
  "@tailwindcss/vite": "4.2.1",
3913
- "@tanem/react-nprogress": "5.0.63",
3930
+ "@tanem/react-nprogress": "6.0.2",
3914
3931
  "@tanstack/react-query": "5.90.21",
3915
3932
  "@types/react": "catalog:",
3916
3933
  "@types/react-dom": "catalog:",
@@ -3924,8 +3941,8 @@ var package_default = {
3924
3941
  clsx: "2.1.1",
3925
3942
  cmdk: "1.1.1",
3926
3943
  dotenv: "17.3.1",
3927
- esbuild: "0.27.3",
3928
3944
  "embla-carousel-react": "8.6.0",
3945
+ esbuild: "^0.27.4",
3929
3946
  "estree-util-is-identifier-name": "3.0.0",
3930
3947
  "estree-util-value-to-estree": "3.5.0",
3931
3948
  "fast-equals": "6.0.0",
@@ -3967,7 +3984,7 @@ var package_default = {
3967
3984
  "rehype-slug": "6.0.0",
3968
3985
  "remark-comment": "1.0.0",
3969
3986
  "remark-directive": "3.0.1",
3970
- "remark-directive-rehype": "0.4.2",
3987
+ "remark-directive-rehype": "1.0.0",
3971
3988
  "remark-frontmatter": "5.0.0",
3972
3989
  "remark-gfm": "4.0.1",
3973
3990
  "remark-mdx-frontmatter": "5.2.0",
@@ -3984,10 +4001,10 @@ var package_default = {
3984
4001
  vaul: "1.1.2",
3985
4002
  vfile: "6.0.3",
3986
4003
  vite: "7.3.1",
3987
- yaml: "2.8.2",
4004
+ yaml: "2.8.3",
3988
4005
  yargs: "18.0.0",
3989
4006
  zod: "4.3.6",
3990
- zustand: "5.0.11"
4007
+ zustand: "5.0.12"
3991
4008
  },
3992
4009
  devDependencies: {
3993
4010
  "@clerk/clerk-js": "^5.125.3",
@@ -4010,6 +4027,7 @@ var package_default = {
4010
4027
  "@types/yargs": "17.0.35",
4011
4028
  "@vitest/coverage-v8": "4.0.18",
4012
4029
  "happy-dom": "catalog:",
4030
+ "oxc-parser": "^0.119.0",
4013
4031
  react: "catalog:",
4014
4032
  "react-dom": "catalog:",
4015
4033
  tsx: "4.21.0",
@@ -4047,7 +4065,7 @@ var package_default = {
4047
4065
  init_logger();
4048
4066
  init_package_json();
4049
4067
  init_loader();
4050
- init_validate();
4068
+ init_ZudokuConfig();
4051
4069
  init_joinUrl();
4052
4070
 
4053
4071
  // src/vite/package-root.ts
@@ -4448,13 +4466,30 @@ var dereference = async (schema2, resolvers = []) => {
4448
4466
  }
4449
4467
  } else {
4450
4468
  if ("$ref" in current && typeof current.$ref === "string") {
4451
- current.__$ref = current.$ref;
4469
+ const { $ref, ...siblings } = current;
4470
+ current.__$ref = $ref;
4471
+ const hasSiblings = Object.keys(siblings).length > 0;
4472
+ let result2;
4452
4473
  for (const resolver of resolvers) {
4453
- const resolved2 = await resolver(current.$ref);
4454
- if (resolved2) return await resolve(resolved2, path29);
4474
+ const resolved = await resolver($ref);
4475
+ if (resolved) {
4476
+ result2 = await resolve(resolved, path29);
4477
+ break;
4478
+ }
4479
+ }
4480
+ if (result2 === void 0) {
4481
+ const resolved = await resolveLocalRef(cloned, $ref);
4482
+ result2 = await resolve(resolved, path29);
4483
+ }
4484
+ if (hasSiblings) {
4485
+ if (result2 === CIRCULAR_REF) {
4486
+ return { ...siblings };
4487
+ }
4488
+ if (isIndexableObject(result2)) {
4489
+ return { ...result2, ...siblings };
4490
+ }
4455
4491
  }
4456
- const resolved = await resolveLocalRef(cloned, current.$ref);
4457
- return await resolve(resolved, path29);
4492
+ return result2;
4458
4493
  }
4459
4494
  for (const key in current) {
4460
4495
  current[key] = await resolve(current[key], `${path29}/${key}`);
@@ -5306,17 +5341,15 @@ var getSegmentsFromPath = (path29) => path29.split("/").slice(1).map(unescapeJso
5306
5341
  var createLocalRefMap = (obj) => {
5307
5342
  const refMap = /* @__PURE__ */ new Map();
5308
5343
  const siblingsMap = /* @__PURE__ */ new Map();
5309
- let refCounter = 0;
5310
- let siblingCounter = 0;
5311
5344
  traverse(obj, (node) => {
5312
5345
  if (typeof node.$ref === "string" && node.$ref.startsWith("#/")) {
5313
5346
  if (!refMap.has(node.$ref)) {
5314
- refMap.set(node.$ref, refCounter++);
5347
+ refMap.set(node.$ref, refMap.size);
5315
5348
  }
5316
- const { $ref, ...otherProps } = node;
5317
- if (Object.keys(otherProps).length > 0) {
5318
- const uniqueKey = `${$ref}__${siblingCounter++}`;
5319
- siblingsMap.set(uniqueKey, { refPath: $ref, siblings: otherProps });
5349
+ const { $ref, ...siblings } = node;
5350
+ if (Object.keys(siblings).length > 0) {
5351
+ const uniqueKey = `${$ref}__${siblingsMap.size}`;
5352
+ siblingsMap.set(uniqueKey, { refPath: $ref, siblings });
5320
5353
  node.__uniqueRefKey = uniqueKey;
5321
5354
  }
5322
5355
  }
@@ -5324,20 +5357,16 @@ var createLocalRefMap = (obj) => {
5324
5357
  });
5325
5358
  return { refMap, siblingsMap };
5326
5359
  };
5327
- var setRefMarkers = (obj, refMap, ignoreSiblings = false) => traverse(obj, (node) => {
5360
+ var setRefMarkers = (obj, refMap) => traverse(obj, (node) => {
5328
5361
  const { $ref, __uniqueRefKey } = node;
5329
- if ($ref && typeof $ref === "string" && refMap.has($ref)) {
5330
- if (ignoreSiblings || !__uniqueRefKey) {
5331
- return `__refMap:${$ref}`;
5332
- }
5333
- return `__refMap+Siblings:${__uniqueRefKey}`;
5362
+ if (typeof $ref === "string" && refMap.has($ref)) {
5363
+ return __uniqueRefKey ? `__refMap+Siblings:${__uniqueRefKey}` : `__refMap:${$ref}`;
5334
5364
  }
5335
5365
  return node;
5336
5366
  });
5337
- var replaceRefMarkers = (code) => code.replace(/"__refMap:(.*?)"/g, '__refMap["$1"]');
5338
- var replaceSiblingRefMarkers = (code, mergedRefs) => code.replace(
5367
+ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__refMap["$1"]').replace(
5339
5368
  /"__refMap\+Siblings:(.*?)"/g,
5340
- (_, uniqueKey) => mergedRefs.get(uniqueKey) ?? `__refMap["${uniqueKey}"]`
5369
+ (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
5341
5370
  );
5342
5371
  var lookup = (schema2, path29, filePath) => {
5343
5372
  const parts = getSegmentsFromPath(path29);
@@ -5355,53 +5384,48 @@ var lookup = (schema2, path29, filePath) => {
5355
5384
  }
5356
5385
  return val;
5357
5386
  };
5387
+ var stringify = (obj, indent = 2) => JSON.stringify(obj, null, indent);
5358
5388
  var generateCode = (schema2, filePath) => {
5359
5389
  const { refMap, siblingsMap } = createLocalRefMap(schema2);
5360
5390
  const lines = [];
5361
- const str = (obj, indent = 2) => JSON.stringify(obj, null, indent);
5362
- lines.push(
5363
- `const __refs = Array.from({ length: ${refMap.size} }, () => ({}));`
5364
- );
5365
5391
  lines.push(
5392
+ `const __refs = Array.from({ length: ${refMap.size} }, () => ({}));`,
5366
5393
  "const __refMap = {",
5367
5394
  Array.from(refMap).map(([refPath, index]) => ` "${refPath}": __refs[${index}]`).join(",\n"),
5368
5395
  "};",
5369
5396
  "const __refMapPaths = Object.keys(__refMap);"
5370
5397
  );
5371
- const assignBaseRefs = () => {
5372
- for (const [refPath, index] of refMap) {
5373
- const value = lookup(schema2, refPath, filePath);
5374
- if (!value) {
5375
- console.warn(`Could not find value for refPath: ${refPath}`);
5376
- continue;
5377
- }
5378
- const transformedValue = setRefMarkers(value, refMap, true);
5379
- lines.push(
5380
- `Object.assign(__refs[${index}], ${replaceRefMarkers(str(transformedValue))});`,
5381
- `Object.defineProperty(__refs[${index}], "__$ref", { value: __refMapPaths[${index}], enumerable: false });`
5382
- );
5383
- }
5384
- };
5385
- const createMergedRefs = () => {
5386
- if (siblingsMap.size === 0) return;
5387
- const mergedRefs2 = /* @__PURE__ */ new Map();
5388
- let mergedCounter = 0;
5389
- for (const [uniqueKey, { refPath, siblings }] of siblingsMap) {
5390
- const varName = `__merged_${mergedCounter++}`;
5391
- mergedRefs2.set(uniqueKey, varName);
5392
- const refIndex = refMap.get(refPath);
5393
- lines.push(
5394
- `const ${varName} = Object.assign({}, __refMap["${refPath}"], ${str(siblings)});`,
5395
- `Object.defineProperty(${varName}, "__$ref", { value: __refMapPaths[${refIndex}], enumerable: false });`
5396
- );
5398
+ const mergedRefs = /* @__PURE__ */ new Map();
5399
+ for (const uniqueKey of siblingsMap.keys()) {
5400
+ const varName = `__merged_${mergedRefs.size}`;
5401
+ mergedRefs.set(uniqueKey, varName);
5402
+ lines.push(`const ${varName} = {};`);
5403
+ }
5404
+ const toCode = (obj) => replaceMarkers(stringify(setRefMarkers(obj, refMap)), mergedRefs);
5405
+ const deferred = [];
5406
+ for (const [refPath, index] of refMap) {
5407
+ const value = lookup(schema2, refPath, filePath);
5408
+ if (!value) {
5409
+ console.warn(`Could not find value for refPath: ${refPath}`);
5410
+ continue;
5397
5411
  }
5398
- return mergedRefs2;
5399
- };
5400
- assignBaseRefs();
5401
- const mergedRefs = createMergedRefs();
5402
- const transformed = setRefMarkers(schema2, refMap);
5403
- let finalCode = replaceRefMarkers(str(transformed));
5404
- if (mergedRefs) finalCode = replaceSiblingRefMarkers(finalCode, mergedRefs);
5412
+ const siblingEntry = value.__uniqueRefKey && siblingsMap.get(value.__uniqueRefKey);
5413
+ const target = siblingEntry ? deferred : lines;
5414
+ target.push(
5415
+ siblingEntry ? `Object.assign(__refs[${index}], __refMap["${siblingEntry.refPath}"], ${stringify(siblingEntry.siblings)});` : `Object.assign(__refs[${index}], ${toCode(value)});`,
5416
+ `Object.defineProperty(__refs[${index}], "__$ref", { value: __refMapPaths[${index}], enumerable: false });`
5417
+ );
5418
+ }
5419
+ lines.push(...deferred);
5420
+ for (const [uniqueKey, { refPath, siblings }] of siblingsMap) {
5421
+ const varName = mergedRefs.get(uniqueKey);
5422
+ const refIndex = refMap.get(refPath);
5423
+ lines.push(
5424
+ `Object.assign(${varName}, __refMap["${refPath}"], ${stringify(siblings)});`,
5425
+ `Object.defineProperty(${varName}, "__$ref", { value: __refMapPaths[${refIndex}], enumerable: false });`
5426
+ );
5427
+ }
5428
+ const finalCode = toCode(schema2);
5405
5429
  lines.push(`export const schema = ${finalCode};`);
5406
5430
  return lines.join("\n");
5407
5431
  };
@@ -5650,7 +5674,7 @@ import colors3 from "picocolors";
5650
5674
  // src/vite/plugin-navigation.ts
5651
5675
  init_loader();
5652
5676
  init_icon_types();
5653
- import { stringify as stringify2 } from "javascript-stringify";
5677
+ import { stringify as stringify3 } from "javascript-stringify";
5654
5678
  import { isElement } from "react-is";
5655
5679
 
5656
5680
  // src/config/validators/NavigationSchema.ts
@@ -5663,10 +5687,10 @@ import { mdxjs } from "micromark-extension-mdxjs";
5663
5687
  // src/lib/util/readFrontmatter.ts
5664
5688
  import { readFile } from "node:fs/promises";
5665
5689
  import matter from "gray-matter";
5666
- import { parse, stringify } from "yaml";
5690
+ import { parse, stringify as stringify2 } from "yaml";
5667
5691
  var yaml = {
5668
5692
  parse: (input) => parse(input) ?? {},
5669
- stringify: (obj) => stringify(obj)
5693
+ stringify: (obj) => stringify2(obj)
5670
5694
  };
5671
5695
  var readFrontmatter = async (filePath) => {
5672
5696
  const content = await readFile(filePath, "utf-8");
@@ -5675,7 +5699,7 @@ var readFrontmatter = async (filePath) => {
5675
5699
  };
5676
5700
 
5677
5701
  // src/config/validators/NavigationSchema.ts
5678
- init_validate();
5702
+ init_ZudokuConfig();
5679
5703
  var extractTitleFromContent = (content) => content.match(/^\s*#\s(.*)$/m)?.at(1);
5680
5704
  var isMdxJsxElement = (node) => node.type === "mdxJsxTextElement";
5681
5705
  var mdastToString = (node) => {
@@ -5877,7 +5901,7 @@ var viteNavigationPlugin = () => {
5877
5901
  );
5878
5902
  const collectedIcons = /* @__PURE__ */ new Set();
5879
5903
  let hasMissingIcon = false;
5880
- const stringifyWithIcons = (value) => stringify2(
5904
+ const stringifyWithIcons = (value) => stringify3(
5881
5905
  value,
5882
5906
  (value2, _indent, next, key) => {
5883
5907
  if (isElement(value2)) return void 0;
@@ -6393,7 +6417,7 @@ init_loader();
6393
6417
  import path13 from "node:path";
6394
6418
  import { glob as glob3 } from "glob";
6395
6419
  import globParent from "glob-parent";
6396
- init_validate();
6420
+ init_ZudokuConfig();
6397
6421
 
6398
6422
  // src/lib/components/navigation/utils.ts
6399
6423
  import { cva } from "class-variance-authority";
@@ -6581,6 +6605,10 @@ ${markdownContent}`;
6581
6605
  description: frontmatter.description
6582
6606
  };
6583
6607
  };
6608
+ var getMarkdownOutputPath = (distDir, routePath) => {
6609
+ const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
6610
+ return `${path14.join(distDir, ...segments)}.md`;
6611
+ };
6584
6612
  var viteMarkdownExportPlugin = () => {
6585
6613
  let markdownFiles = {};
6586
6614
  let markdownFileInfos = [];
@@ -6674,8 +6702,7 @@ var viteMarkdownExportPlugin = () => {
6674
6702
  description,
6675
6703
  content: finalMarkdown
6676
6704
  });
6677
- const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
6678
- const outputPath = `${path14.join(distDir, ...segments)}.md`;
6705
+ const outputPath = getMarkdownOutputPath(distDir, routePath);
6679
6706
  await mkdir2(path14.dirname(outputPath), { recursive: true });
6680
6707
  await writeFile2(outputPath, finalMarkdown, "utf-8");
6681
6708
  } catch (error) {
@@ -6845,7 +6872,7 @@ var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
6845
6872
  import { spawnSync } from "node:child_process";
6846
6873
  import { stat as stat3 } from "node:fs/promises";
6847
6874
  import { visit as visit4 } from "unist-util-visit";
6848
- import { parse as parse2, stringify as stringify3 } from "yaml";
6875
+ import { parse as parse2, stringify as stringify4 } from "yaml";
6849
6876
  var isGitAvailable;
6850
6877
  var hasWarnedShallowClone = false;
6851
6878
  var checkGitAvailable = () => {
@@ -6911,13 +6938,13 @@ var remarkLastModified = () => {
6911
6938
  const data = parse2(node.value) ?? {};
6912
6939
  if (!data.lastModifiedTime) {
6913
6940
  data.lastModifiedTime = lastModifiedISO;
6914
- node.value = stringify3(data).trim();
6941
+ node.value = stringify4(data).trim();
6915
6942
  }
6916
6943
  });
6917
6944
  if (!hasYaml) {
6918
6945
  tree.children.unshift({
6919
6946
  type: "yaml",
6920
- value: stringify3({ lastModifiedTime: lastModifiedISO }).trim()
6947
+ value: stringify4({ lastModifiedTime: lastModifiedISO }).trim()
6921
6948
  });
6922
6949
  }
6923
6950
  };
@@ -7844,7 +7871,7 @@ var prerender = async ({
7844
7871
  redirectUrls
7845
7872
  });
7846
7873
  if (config2.docs) {
7847
- const { DocsConfigSchema: DocsConfigSchema2 } = await Promise.resolve().then(() => (init_validate(), validate_exports));
7874
+ const { DocsConfigSchema: DocsConfigSchema2 } = await Promise.resolve().then(() => (init_ZudokuConfig(), ZudokuConfig_exports));
7848
7875
  const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
7849
7876
  const docsConfig = DocsConfigSchema2.parse(config2.docs);
7850
7877
  const llmsConfig = docsConfig.llms ?? {};
@@ -7871,8 +7898,14 @@ var prerender = async ({
7871
7898
  }
7872
7899
  if (!docsConfig.publishMarkdown) {
7873
7900
  await Promise.all(
7874
- markdownFileInfos.map((info) => rm(info.filePath).catch(() => {
7875
- }))
7901
+ markdownFileInfos.map((info) => {
7902
+ const outputPath = getMarkdownOutputPath(distDir, info.routePath);
7903
+ if (!path21.resolve(outputPath).startsWith(path21.resolve(distDir))) {
7904
+ return;
7905
+ }
7906
+ return rm(outputPath).catch(() => {
7907
+ });
7908
+ })
7876
7909
  );
7877
7910
  }
7878
7911
  }
@@ -17,14 +17,15 @@ var normalizeParts = (parts) => parts.filter(
17
17
  ).map((part) => `${part}`).filter((part) => part);
18
18
  var parseParts = (parts) => {
19
19
  const partsStr = parts.join("/");
20
- const [, prefix = "", pathname = ""] = partsStr.match(defaultUrlRegExp) ?? [];
20
+ const [, prefix = "", pathname = "", query = ""] = partsStr.match(defaultUrlRegExp) ?? [];
21
21
  return {
22
22
  prefix,
23
- pathname: pathname.split("/").filter((part) => part !== "")
23
+ pathname: pathname.split("/").filter((part) => part !== ""),
24
+ query
24
25
  };
25
26
  };
26
27
  var buildUrl = (parsedParts) => {
27
- const { prefix, pathname } = parsedParts;
28
+ const { prefix, pathname, query } = parsedParts;
28
29
  let url = prefix;
29
30
  if (pathname.length > 0) {
30
31
  if (url) {
@@ -36,7 +37,7 @@ var buildUrl = (parsedParts) => {
36
37
  } else if (!url) {
37
38
  url = "/";
38
39
  }
39
- return url;
40
+ return url + query;
40
41
  };
41
42
  var joinUrl = (...parts) => {
42
43
  const normalizedParts = normalizeParts(parts);
@@ -1,3 +1,3 @@
1
1
  import { type RouteObject } from "react-router";
2
- import type { ZudokuRedirect } from "../../config/validators/validate.js";
2
+ import type { ZudokuRedirect } from "../../config/validators/ZudokuConfig.js";
3
3
  export declare const createRedirectRoutes: (redirects?: ZudokuRedirect[]) => RouteObject[];
@@ -1,6 +1,6 @@
1
1
  import type { ConfigWithMeta } from "./loader.js";
2
2
  import type { BuildConfig } from "./validators/BuildSchema.js";
3
- import type { AuthenticationConfig, ZudokuConfig } from "./validators/validate.js";
3
+ import type { AuthenticationConfig, ZudokuConfig } from "./validators/ZudokuConfig.js";
4
4
  export type ZudokuBuildConfig = BuildConfig;
5
5
  export type LoadedConfig = ConfigWithMeta;
6
6
  export type { ZudokuConfig };
@@ -1,6 +1,6 @@
1
1
  import type { RollupOutput, RollupWatcher } from "rollup";
2
2
  import { type ConfigEnv } from "vite";
3
- import type { ZudokuConfig } from "./validators/validate.js";
3
+ import type { ZudokuConfig } from "./validators/ZudokuConfig.js";
4
4
  export type ConfigWithMeta = ZudokuConfig & {
5
5
  __meta: {
6
6
  rootDir: string;
@@ -15,6 +15,33 @@ import type { MdxComponentsType } from "../../lib/util/MdxComponents.js";
15
15
  import type { ExposedComponentProps } from "../../lib/util/useExposedProps.js";
16
16
  import { HeaderNavigationSchema } from "./HeaderNavigationSchema.js";
17
17
  import { InputNavigationSchema, NavigationRulesSchema } from "./InputNavigationSchema.js";
18
+ declare const AiAssistantCustomSchema: z.ZodObject<{
19
+ label: z.ZodString;
20
+ icon: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
21
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<(context: {
22
+ pageUrl: string;
23
+ type: "docs" | "openapi";
24
+ }) => string, (context: {
25
+ pageUrl: string;
26
+ type: "docs" | "openapi";
27
+ }) => string>]>;
28
+ }, z.core.$strip>;
29
+ export type AiAssistantCustom = z.infer<typeof AiAssistantCustomSchema>;
30
+ declare const AiAssistantsSchema: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
31
+ claude: "claude";
32
+ chatgpt: "chatgpt";
33
+ }>, z.ZodObject<{
34
+ label: z.ZodString;
35
+ icon: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
36
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<(context: {
37
+ pageUrl: string;
38
+ type: "docs" | "openapi";
39
+ }) => string, (context: {
40
+ pageUrl: string;
41
+ type: "docs" | "openapi";
42
+ }) => string>]>;
43
+ }, z.core.$strip>]>>]>>;
44
+ export type AiAssistantsConfig = z.infer<typeof AiAssistantsSchema>;
18
45
  declare const VersionConfigSchema: z.ZodObject<{
19
46
  path: z.ZodString;
20
47
  input: z.ZodString;
@@ -211,6 +238,7 @@ export declare const FooterSchema: z.ZodOptional<z.ZodObject<{
211
238
  alt: z.ZodOptional<z.ZodString>;
212
239
  width: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
213
240
  href: z.ZodOptional<z.ZodString>;
241
+ reloadDocument: z.ZodOptional<z.ZodBoolean>;
214
242
  }, z.core.$strip>>;
215
243
  position: z.ZodOptional<z.ZodEnum<{
216
244
  end: "end";
@@ -434,6 +462,7 @@ export declare const ZudokuConfig: z.ZodObject<{
434
462
  alt: z.ZodOptional<z.ZodString>;
435
463
  width: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
436
464
  href: z.ZodOptional<z.ZodString>;
465
+ reloadDocument: z.ZodOptional<z.ZodBoolean>;
437
466
  }, z.core.$strip>>;
438
467
  showPoweredBy: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
439
468
  banner: z.ZodOptional<z.ZodObject<{
@@ -483,6 +512,7 @@ export declare const ZudokuConfig: z.ZodObject<{
483
512
  alt: z.ZodOptional<z.ZodString>;
484
513
  width: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
485
514
  href: z.ZodOptional<z.ZodString>;
515
+ reloadDocument: z.ZodOptional<z.ZodBoolean>;
486
516
  }, z.core.$strip>>;
487
517
  position: z.ZodOptional<z.ZodEnum<{
488
518
  end: "end";
@@ -6982,6 +7012,20 @@ export declare const ZudokuConfig: z.ZodObject<{
6982
7012
  auth: UseAuthReturn;
6983
7013
  }) => Promise<void>>>;
6984
7014
  }, z.core.$strip>>;
7015
+ aiAssistants: z.ZodOptional<z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
7016
+ claude: "claude";
7017
+ chatgpt: "chatgpt";
7018
+ }>, z.ZodObject<{
7019
+ label: z.ZodString;
7020
+ icon: z.ZodOptional<z.ZodCustom<ReactNode, ReactNode>>;
7021
+ url: z.ZodUnion<readonly [z.ZodString, z.ZodCustom<(context: {
7022
+ pageUrl: string;
7023
+ type: "docs" | "openapi";
7024
+ }) => string, (context: {
7025
+ pageUrl: string;
7026
+ type: "docs" | "openapi";
7027
+ }) => string>]>;
7028
+ }, z.core.$strip>]>>]>>>;
6985
7029
  redirects: z.ZodOptional<z.ZodArray<z.ZodObject<{
6986
7030
  from: z.ZodString;
6987
7031
  to: z.ZodString;
@@ -5,11 +5,6 @@ export declare class CoreAuthenticationPlugin implements PluginInterface {
5
5
  path: string;
6
6
  element: import("react/jsx-runtime").JSX.Element;
7
7
  }[];
8
- getProfileMenuItems(): {
9
- readonly label: "Logout";
10
- readonly path: "/signout";
11
- readonly category: "bottom";
12
- readonly icon: import("react").ForwardRefExoticComponent<Omit<import("lucide-react").LucideProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
13
- }[];
8
+ getProfileMenuItems(): never[];
14
9
  }
15
10
  export {};
@@ -0,0 +1,6 @@
1
+ import type { AiAssistantsConfig } from "../../config/validators/ZudokuConfig.js";
2
+ export declare const AiAssistantMenuItems: ({ aiAssistants, getPageUrl, type, }: {
3
+ aiAssistants: AiAssistantsConfig;
4
+ getPageUrl: () => string;
5
+ type: "docs" | "openapi";
6
+ }) => (import("react/jsx-runtime").JSX.Element | null)[] | null;
@@ -6,7 +6,7 @@ import type { z } from "zod/mini";
6
6
  import type { HeaderNavigation } from "../../config/validators/HeaderNavigationSchema.js";
7
7
  import type { Navigation, ResolvedNavigationRule } from "../../config/validators/NavigationSchema.js";
8
8
  import type { CallbackContext, ProtectedRouteResult, ProtectedRoutesInput } from "../../config/validators/ProtectedRoutesSchema.js";
9
- import type { FooterSchema } from "../../config/validators/validate.js";
9
+ import type { AiAssistantsConfig, FooterSchema } from "../../config/validators/ZudokuConfig.js";
10
10
  import type { AuthenticationPlugin } from "../authentication/authentication.js";
11
11
  import { type AuthState } from "../authentication/state.js";
12
12
  import type { SlotType } from "../components/context/SlotProvider.js";
@@ -58,6 +58,7 @@ type Site = Partial<{
58
58
  width?: string | number;
59
59
  alt?: string;
60
60
  href?: string;
61
+ reloadDocument?: boolean;
61
62
  };
62
63
  banner?: {
63
64
  message: ReactNode;
@@ -80,6 +81,7 @@ export type ZudokuContextOptions = {
80
81
  metadata?: Metadata;
81
82
  site?: Site;
82
83
  header?: HeaderConfig;
84
+ aiAssistants?: AiAssistantsConfig;
83
85
  authentication?: AuthenticationPlugin;
84
86
  navigation?: Navigation;
85
87
  navigationRules?: ResolvedNavigationRule[];