@redocly/reef 0.137.0-next.1 → 0.137.0-next.10

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 (351) hide show
  1. package/CHANGELOG.md +201 -0
  2. package/dist/api-schemas/otel-traces.d.ts +1359 -0
  3. package/dist/api-schemas/otel-traces.js +1 -0
  4. package/dist/cli/stats/collectors/asyncapi/index.d.ts +3 -0
  5. package/dist/cli/stats/collectors/asyncapi/index.js +1 -0
  6. package/dist/cli/stats/collectors/extension-sampling.d.ts +44 -0
  7. package/dist/cli/stats/collectors/extension-sampling.js +1 -0
  8. package/dist/cli/stats/collectors/openapi/index.js +1 -1
  9. package/dist/cli/stats/collectors/prepare-stats-walk.d.ts +10 -0
  10. package/dist/cli/stats/collectors/prepare-stats-walk.js +1 -0
  11. package/dist/cli/stats/collectors/run-stats-collector.d.ts +24 -0
  12. package/dist/cli/stats/collectors/run-stats-collector.js +1 -0
  13. package/dist/cli/stats/index.js +1 -1
  14. package/dist/client/app/hooks/useMcpData.d.ts +1 -0
  15. package/dist/client/app/hooks/useMcpData.js +1 -1
  16. package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
  17. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  18. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  19. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  20. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  21. package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.d.ts +45 -0
  22. package/dist/client/app/markdoc/custom-components/openapi/use-markdown-adapter.js +1 -0
  23. package/dist/client/app/utils/loadAndNavigate.js +1 -1
  24. package/dist/client/providers/hooks.js +1 -1
  25. package/dist/client/providers/post-message/PostMessageProvider.js +1 -1
  26. package/dist/client/templates/api-docs/helpers.d.ts +4 -1
  27. package/dist/client/templates/api-docs/helpers.js +5 -1
  28. package/dist/client/templates/api-docs/template.js +8 -3
  29. package/dist/client/utils/catalog/get-next-page-param.d.ts +1 -1
  30. package/dist/client/utils/catalog/get-next-page-param.js +1 -1
  31. package/dist/compiled/svgo/svgo-node.js +32 -32
  32. package/dist/constants/l10n/langs/ar.js +1 -1
  33. package/dist/constants/l10n/langs/de.js +1 -1
  34. package/dist/constants/l10n/langs/en.js +1 -1
  35. package/dist/constants/l10n/langs/es.js +1 -1
  36. package/dist/constants/l10n/langs/fr.js +1 -1
  37. package/dist/constants/l10n/langs/hi.js +1 -1
  38. package/dist/constants/l10n/langs/it.js +1 -1
  39. package/dist/constants/l10n/langs/ja.js +1 -1
  40. package/dist/constants/l10n/langs/ko.js +1 -1
  41. package/dist/constants/l10n/langs/pl.js +1 -1
  42. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  43. package/dist/constants/l10n/langs/pt.js +1 -1
  44. package/dist/constants/l10n/langs/ru.js +1 -1
  45. package/dist/constants/l10n/langs/uk.js +1 -1
  46. package/dist/constants/l10n/langs/zh.js +1 -1
  47. package/dist/server/config/env-config.d.ts +6 -0
  48. package/dist/server/config/env-schema.d.ts +15 -0
  49. package/dist/server/config/env-schemas/feature-flags.d.ts +9 -1
  50. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  51. package/dist/server/config/env-schemas/search.d.ts +3 -0
  52. package/dist/server/config/env-schemas/search.js +1 -1
  53. package/dist/server/constants/common.d.ts +1 -0
  54. package/dist/server/constants/common.js +1 -1
  55. package/dist/server/constants/mcp.d.ts +5 -0
  56. package/dist/server/constants/mcp.js +1 -0
  57. package/dist/server/constants/plugins/search.d.ts +0 -2
  58. package/dist/server/constants/plugins/search.js +1 -1
  59. package/dist/server/constants/rbac.d.ts +3 -0
  60. package/dist/server/constants/rbac.js +1 -0
  61. package/dist/server/esbuild/esbuild.js +3 -3
  62. package/dist/server/esbuild/plugins/mcp-tool-handlers-resolver.js +1 -1
  63. package/dist/server/plugins/api-docs/options.js +1 -1
  64. package/dist/server/plugins/api-docs/search/create-indexer.d.ts +5 -0
  65. package/dist/server/plugins/api-docs/search/create-indexer.js +1 -0
  66. package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +28 -28
  67. package/dist/server/plugins/api-docs/search/search-resolver.js +1 -1
  68. package/dist/server/plugins/{openapi-docs/is-openapi-doc.d.ts → api-docs/utils/is-api-doc.d.ts} +4 -2
  69. package/dist/server/plugins/api-docs/utils/is-api-doc.js +1 -0
  70. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.d.ts +1 -1
  71. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.js +1 -1
  72. package/dist/server/plugins/entitlements/index.js +1 -1
  73. package/dist/server/plugins/l10n/index.js +1 -1
  74. package/dist/server/plugins/lifecycle.js +2 -2
  75. package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
  76. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  77. package/dist/server/plugins/markdown/html/html-jsx-attribute-mapping.js +1 -1
  78. package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +2 -2
  79. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +1 -2
  80. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  81. package/dist/server/plugins/mcp/auth/token-audience-telemetry.d.ts +7 -0
  82. package/dist/server/plugins/mcp/auth/token-audience-telemetry.js +1 -0
  83. package/dist/server/plugins/mcp/auth/token-audience.d.ts +6 -0
  84. package/dist/server/plugins/mcp/auth/token-audience.js +1 -0
  85. package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +4 -4
  86. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +3 -1
  87. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -1
  88. package/dist/server/plugins/mcp/codemode/invoke-tool.js +1 -1
  89. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  90. package/dist/server/plugins/mcp/codemode/sandbox/polyfills/fetch-shim.d.ts +1 -1
  91. package/dist/server/plugins/mcp/codemode/sandbox/polyfills/fetch-shim.js +9 -3
  92. package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +1 -1
  93. package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +1 -1
  94. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  95. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  96. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.d.ts +1 -0
  97. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +2 -2
  98. package/dist/server/plugins/mcp/codemode/types.d.ts +1 -0
  99. package/dist/server/plugins/mcp/constants.d.ts +1 -1
  100. package/dist/server/plugins/mcp/constants.js +1 -1
  101. package/dist/server/plugins/mcp/custom-tools/extract-tool-definition.d.ts +13 -0
  102. package/dist/server/plugins/mcp/custom-tools/extract-tool-definition.js +1 -0
  103. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.d.ts +6 -0
  104. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -0
  105. package/dist/server/plugins/mcp/custom-tools/validate-tool-definition.d.ts +3 -0
  106. package/dist/server/plugins/mcp/custom-tools/validate-tool-definition.js +1 -0
  107. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +2 -0
  108. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  109. package/dist/server/plugins/mcp/docs-mcp/tools/core/search.js +2 -2
  110. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoints.js +1 -1
  111. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
  112. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  113. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.d.ts +10 -0
  114. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.js +1 -0
  115. package/dist/server/plugins/mcp/gateway-mcp/credential-validation.d.ts +4 -0
  116. package/dist/server/plugins/mcp/gateway-mcp/credential-validation.js +1 -0
  117. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +15 -5
  118. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +5 -3
  119. package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -1
  120. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.d.ts +2 -1
  121. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-audit.js +1 -1
  122. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +10 -1
  123. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  124. package/dist/server/plugins/mcp/gateway-mcp/fetch/upstream-detail.d.ts +7 -0
  125. package/dist/server/plugins/mcp/gateway-mcp/fetch/upstream-detail.js +1 -0
  126. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +2 -10
  127. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  128. package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +16 -4
  129. package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -1
  130. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +26 -1
  131. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +2 -1
  132. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +12 -0
  133. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.js +1 -1
  134. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  135. package/dist/server/plugins/mcp/handlers/errors.d.ts +7 -2
  136. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  137. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  138. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -124
  139. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.d.ts +12 -0
  140. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +225 -0
  141. package/dist/server/plugins/mcp/index.d.ts +0 -2
  142. package/dist/server/plugins/mcp/index.js +1 -1
  143. package/dist/server/plugins/mcp/servers/docs-server.d.ts +2 -2
  144. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  145. package/dist/server/plugins/mcp/servers/mcp-server.d.ts +2 -11
  146. package/dist/server/plugins/mcp/servers/mcp-server.js +4 -2
  147. package/dist/server/plugins/mcp/types.d.ts +32 -5
  148. package/dist/server/plugins/mcp/utils/available-sandbox-tools.d.ts +4 -0
  149. package/dist/server/plugins/mcp/utils/available-sandbox-tools.js +1 -0
  150. package/dist/server/plugins/mcp/utils/find-gated-tool-names.d.ts +12 -0
  151. package/dist/server/plugins/mcp/utils/find-gated-tool-names.js +1 -0
  152. package/dist/server/plugins/mcp/utils/mcp-client.d.ts +13 -0
  153. package/dist/server/plugins/mcp/utils/mcp-client.js +1 -0
  154. package/dist/server/plugins/mcp/utils/tool-registration.d.ts +17 -0
  155. package/dist/server/plugins/mcp/utils/tool-registration.js +1 -0
  156. package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +6 -1
  157. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  158. package/dist/server/plugins/mcp/workers/import-mcp-tool-handlers.d.ts +5 -0
  159. package/dist/server/plugins/mcp/workers/import-mcp-tool-handlers.js +1 -0
  160. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +6 -11
  161. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  162. package/dist/server/plugins/mcp/workers/tool-file-system.d.ts +6 -0
  163. package/dist/server/plugins/mcp/workers/tool-file-system.js +1 -0
  164. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.d.ts +4 -2
  165. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +1 -3
  166. package/dist/server/plugins/search/engines/flexsearch/index.js +1 -1
  167. package/dist/server/plugins/search/engines/flexsearch/search-index.d.ts +8 -4
  168. package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
  169. package/dist/server/plugins/search/engines/typesense/index.js +1 -1
  170. package/dist/server/plugins/search/index.js +1 -1
  171. package/dist/server/plugins/search/llmstxt/build-page-llms-txt-md.d.ts +4 -0
  172. package/dist/server/plugins/search/llmstxt/build-page-llms-txt-md.js +3 -0
  173. package/dist/server/plugins/search/llmstxt/create-llms-txt-generator.d.ts +4 -0
  174. package/dist/server/plugins/search/llmstxt/create-llms-txt-generator.js +1 -0
  175. package/dist/server/plugins/search/llmstxt/get-llms-txt-exclude-matcher.d.ts +4 -0
  176. package/dist/server/plugins/search/llmstxt/get-llms-txt-exclude-matcher.js +1 -0
  177. package/dist/server/plugins/search/llmstxt/index.d.ts +2 -2
  178. package/dist/server/plugins/search/llmstxt/is-included-in-llms-txt.d.ts +6 -0
  179. package/dist/server/plugins/search/llmstxt/is-included-in-llms-txt.js +1 -0
  180. package/dist/server/plugins/search/utils.d.ts +2 -1
  181. package/dist/server/plugins/search/utils.js +2 -2
  182. package/dist/server/sandbox/constants/sandbox.d.ts +4 -1
  183. package/dist/server/sandbox/constants/sandbox.js +1 -1
  184. package/dist/server/sandbox/sandbox.js +2 -2
  185. package/dist/server/sandbox/utils/returns-from-top-level.d.ts +4 -0
  186. package/dist/server/sandbox/utils/returns-from-top-level.js +1 -0
  187. package/dist/server/store.d.ts +2 -0
  188. package/dist/server/store.js +1 -1
  189. package/dist/server/types/plugins/common.d.ts +5 -0
  190. package/dist/server/types/plugins/search.d.ts +7 -2
  191. package/dist/server/types/web-server.d.ts +8 -0
  192. package/dist/server/utils/envs/get-api-route-allowed-env-variables.js +1 -1
  193. package/dist/server/utils/get-route-ai-documents-store.d.ts +5 -0
  194. package/dist/server/utils/get-route-ai-documents-store.js +1 -0
  195. package/dist/server/utils/get-route-static-data.d.ts +4 -0
  196. package/dist/server/utils/get-route-static-data.js +1 -0
  197. package/dist/server/utils/llmstxt/agent-feedback-llms-footer.js +1 -1
  198. package/dist/server/utils/llmstxt/resolve-llms-txt-md.d.ts +10 -0
  199. package/dist/server/utils/llmstxt/resolve-llms-txt-md.js +1 -0
  200. package/dist/server/utils/rbac/can-anonymous-access-mcp-feature.d.ts +3 -0
  201. package/dist/server/utils/rbac/can-anonymous-access-mcp-feature.js +1 -0
  202. package/dist/server/utils/rbac/should-handle-mcp-auth.d.ts +2 -0
  203. package/dist/server/utils/rbac/should-handle-mcp-auth.js +1 -0
  204. package/dist/server/utils/rbac.js +1 -1
  205. package/dist/server/utils/search/highlight-text-for-search.js +1 -1
  206. package/dist/server/web-server/auth.d.ts +13 -2
  207. package/dist/server/web-server/auth.js +3 -3
  208. package/dist/server/web-server/dev-server.js +1 -1
  209. package/dist/server/web-server/handle-api-route-request.js +1 -1
  210. package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
  211. package/dist/server/web-server/routes/ask-ai.d.ts +1 -0
  212. package/dist/server/web-server/routes/ask-ai.js +1 -1
  213. package/dist/server/web-server/routes/auth.js +1 -1
  214. package/dist/server/web-server/routes/dynamic-route.d.ts +2 -1
  215. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  216. package/dist/server/web-server/routes/error.js +1 -1
  217. package/dist/server/web-server/routes/helpers/resolve-ui-locales-for-idp-login.js +1 -1
  218. package/dist/server/web-server/routes/index.d.ts +2 -1
  219. package/dist/server/web-server/routes/index.js +1 -1
  220. package/dist/server/web-server/routes/llms-txt.d.ts +4 -0
  221. package/dist/server/web-server/routes/llms-txt.js +1 -0
  222. package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -1
  223. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  224. package/dist/server/web-server/routes/otel/otel.js +1 -1
  225. package/dist/server/web-server/routes/page-data.js +1 -1
  226. package/dist/server/web-server/routes/resolve-route.js +1 -1
  227. package/dist/server/web-server/utils/get-request-origin.d.ts +2 -0
  228. package/dist/server/web-server/utils/get-request-origin.js +1 -1
  229. package/dist/server/web-server/utils/prepare-list-response.d.ts +2 -4
  230. package/dist/server/web-server/utils/prepare-list-response.js +1 -1
  231. package/dist/server/web-server/utils.d.ts +1 -1
  232. package/dist/server/web-server/utils.js +1 -1
  233. package/dist/server/workers/mcp-tool-worker-pool.d.ts +1 -0
  234. package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
  235. package/dist/server/workers/mcp-tool-worker.js +1 -1
  236. package/dist/server/workers/types.d.ts +9 -2
  237. package/dist/server/workers/worker-pool.d.ts +1 -0
  238. package/dist/server/workers/worker-pool.js +1 -1
  239. package/dist/types/global-data.d.ts +1 -0
  240. package/dist/utils/guards/is-plain-object.d.ts +19 -0
  241. package/dist/utils/guards/is-plain-object.js +1 -0
  242. package/package.json +12 -15
  243. package/dist/client/templates/asyncapi-docs/helpers.d.ts +0 -12
  244. package/dist/client/templates/asyncapi-docs/helpers.js +0 -1
  245. package/dist/client/templates/asyncapi-docs/template.d.ts +0 -15
  246. package/dist/client/templates/asyncapi-docs/template.js +0 -9
  247. package/dist/client/templates/openapi-docs/helpers.d.ts +0 -18
  248. package/dist/client/templates/openapi-docs/helpers.js +0 -5
  249. package/dist/client/templates/openapi-docs/template.d.ts +0 -6
  250. package/dist/client/templates/openapi-docs/template.js +0 -14
  251. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +0 -9
  252. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +0 -1
  253. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +0 -2
  254. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +0 -1
  255. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +0 -6
  256. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +0 -1
  257. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-check.d.ts +0 -8
  258. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-check.js +0 -1
  259. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-overlay.d.ts +0 -2
  260. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-overlay.js +0 -1
  261. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-use-license-key.d.ts +0 -5
  262. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-use-license-key.js +0 -1
  263. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/index.d.ts +0 -6
  264. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/index.js +0 -1
  265. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/loadAndBundleSpec.mock.d.ts +0 -3
  266. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/loadAndBundleSpec.mock.js +0 -1
  267. package/dist/server/plugins/api-docs/search/search-indexer.d.ts +0 -9
  268. package/dist/server/plugins/api-docs/search/search-indexer.js +0 -1
  269. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.d.ts +0 -18
  270. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.js +0 -5
  271. package/dist/server/plugins/asyncapi-docs/get-server-props.d.ts +0 -4
  272. package/dist/server/plugins/asyncapi-docs/get-server-props.js +0 -1
  273. package/dist/server/plugins/asyncapi-docs/get-template-path.d.ts +0 -2
  274. package/dist/server/plugins/asyncapi-docs/get-template-path.js +0 -1
  275. package/dist/server/plugins/asyncapi-docs/index.d.ts +0 -3
  276. package/dist/server/plugins/asyncapi-docs/index.js +0 -1
  277. package/dist/server/plugins/asyncapi-docs/is-asyncapi-doc.d.ts +0 -3
  278. package/dist/server/plugins/asyncapi-docs/is-asyncapi-doc.js +0 -1
  279. package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.d.ts +0 -9
  280. package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.js +0 -56
  281. package/dist/server/plugins/asyncapi-docs/search/schema-processor.d.ts +0 -8
  282. package/dist/server/plugins/asyncapi-docs/search/schema-processor.js +0 -1
  283. package/dist/server/plugins/asyncapi-docs/search/search-facets.d.ts +0 -8
  284. package/dist/server/plugins/asyncapi-docs/search/search-facets.js +0 -1
  285. package/dist/server/plugins/asyncapi-docs/search/search-resolver.d.ts +0 -5
  286. package/dist/server/plugins/asyncapi-docs/search/search-resolver.js +0 -1
  287. package/dist/server/plugins/asyncapi-docs/store-definition-bundles.d.ts +0 -4
  288. package/dist/server/plugins/asyncapi-docs/store-definition-bundles.js +0 -1
  289. package/dist/server/plugins/graphql-docs/constants.d.ts +0 -2
  290. package/dist/server/plugins/graphql-docs/constants.js +0 -1
  291. package/dist/server/plugins/graphql-docs/get-template-path.d.ts +0 -2
  292. package/dist/server/plugins/graphql-docs/get-template-path.js +0 -1
  293. package/dist/server/plugins/graphql-docs/graphql-doc-loader.d.ts +0 -17
  294. package/dist/server/plugins/graphql-docs/graphql-doc-loader.js +0 -1
  295. package/dist/server/plugins/graphql-docs/index.d.ts +0 -4
  296. package/dist/server/plugins/graphql-docs/index.js +0 -1
  297. package/dist/server/plugins/graphql-docs/is-graphql-doc.d.ts +0 -2
  298. package/dist/server/plugins/graphql-docs/is-graphql-doc.js +0 -1
  299. package/dist/server/plugins/graphql-docs/search/ai/get-ai-search-document.d.ts +0 -17
  300. package/dist/server/plugins/graphql-docs/search/ai/get-ai-search-document.js +0 -4
  301. package/dist/server/plugins/graphql-docs/search/ai/utils.d.ts +0 -14
  302. package/dist/server/plugins/graphql-docs/search/ai/utils.js +0 -36
  303. package/dist/server/plugins/graphql-docs/search/search-facets.d.ts +0 -8
  304. package/dist/server/plugins/graphql-docs/search/search-facets.js +0 -1
  305. package/dist/server/plugins/graphql-docs/search/search-resolver.d.ts +0 -5
  306. package/dist/server/plugins/graphql-docs/search/search-resolver.js +0 -1
  307. package/dist/server/plugins/graphql-docs/spec-download.api.d.ts +0 -3
  308. package/dist/server/plugins/graphql-docs/spec-download.api.js +0 -1
  309. package/dist/server/plugins/graphql-docs/template/GraphQLDocs.d.ts +0 -5
  310. package/dist/server/plugins/graphql-docs/template/GraphQLDocs.js +0 -4
  311. package/dist/server/plugins/graphql-docs/types.d.ts +0 -40
  312. package/dist/server/plugins/graphql-docs/types.js +0 -0
  313. package/dist/server/plugins/openapi-docs/ai-search-indexer.d.ts +0 -14
  314. package/dist/server/plugins/openapi-docs/ai-search-indexer.js +0 -1
  315. package/dist/server/plugins/openapi-docs/decorators.d.ts +0 -25
  316. package/dist/server/plugins/openapi-docs/decorators.js +0 -1
  317. package/dist/server/plugins/openapi-docs/format-bundle-error.d.ts +0 -6
  318. package/dist/server/plugins/openapi-docs/format-bundle-error.js +0 -5
  319. package/dist/server/plugins/openapi-docs/get-server-props.d.ts +0 -4
  320. package/dist/server/plugins/openapi-docs/get-server-props.js +0 -1
  321. package/dist/server/plugins/openapi-docs/get-template-path.d.ts +0 -2
  322. package/dist/server/plugins/openapi-docs/get-template-path.js +0 -1
  323. package/dist/server/plugins/openapi-docs/index.d.ts +0 -3
  324. package/dist/server/plugins/openapi-docs/index.js +0 -1
  325. package/dist/server/plugins/openapi-docs/is-openapi-doc.js +0 -1
  326. package/dist/server/plugins/openapi-docs/load-definition.d.ts +0 -31
  327. package/dist/server/plugins/openapi-docs/load-definition.js +0 -3
  328. package/dist/server/plugins/openapi-docs/openapi-search-builder.d.ts +0 -24
  329. package/dist/server/plugins/openapi-docs/openapi-search-builder.js +0 -1
  330. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.d.ts +0 -18
  331. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +0 -94
  332. package/dist/server/plugins/openapi-docs/search/search-facets.d.ts +0 -11
  333. package/dist/server/plugins/openapi-docs/search/search-facets.js +0 -1
  334. package/dist/server/plugins/openapi-docs/search/search-resolver.d.ts +0 -5
  335. package/dist/server/plugins/openapi-docs/search/search-resolver.js +0 -1
  336. package/dist/server/plugins/openapi-docs/search-indexer.d.ts +0 -17
  337. package/dist/server/plugins/openapi-docs/search-indexer.js +0 -1
  338. package/dist/server/plugins/openapi-docs/spec-download.api.d.ts +0 -4
  339. package/dist/server/plugins/openapi-docs/spec-download.api.js +0 -1
  340. package/dist/server/plugins/openapi-docs/store-definition-bundles.d.ts +0 -4
  341. package/dist/server/plugins/openapi-docs/store-definition-bundles.js +0 -1
  342. package/dist/server/plugins/openapi-docs/types.d.ts +0 -17
  343. package/dist/server/plugins/openapi-docs/types.js +0 -0
  344. package/dist/server/plugins/openapi-docs/utils.d.ts +0 -25
  345. package/dist/server/plugins/openapi-docs/utils.js +0 -1
  346. /package/dist/client/templates/{openapi-docs → api-docs}/mock-server-config.d.ts +0 -0
  347. /package/dist/client/templates/{openapi-docs → api-docs}/mock-server-config.js +0 -0
  348. /package/dist/{server/plugins → markdoc}/helpers/parse-partials.d.ts +0 -0
  349. /package/dist/{server/plugins → markdoc}/helpers/parse-partials.js +0 -0
  350. /package/dist/server/plugins/{openapi-docs → api-docs/utils}/ast-utils.d.ts +0 -0
  351. /package/dist/server/plugins/{openapi-docs → api-docs/utils}/ast-utils.js +0 -0
@@ -1 +1 @@
1
- import{telemetry as u}from"../../../telemetry/index.js";import{serverAttributes as l}from"../utils/telemetry-attributes.js";import{EXECUTE_TOOL_NAME as c}from"../codemode/constants.js";import{auditInput as d,auditOutputDigest as p,auditSha256 as f,logAuditRecord as g}from"../audit/audit-log.js";function E({tool:r,mode:e,serverType:o,durationMs:s,outputLength:t}){u.sendMcpToolCalledMessage([{...l(o),tool:r,mode:e,output_length:t,duration_ms:s}])}function T({tool:r,mode:e,serverType:o,args:s,result:t,errorClass:n}){if(r===c)return;const i=m(s),a=t===void 0?void 0:p(t);g("Record MCP tool call",{tool:r,mode:e,server_type:o,error_class:n,args_sha256:f(i),args:d(i),result_sha256:a?.sha256,result_bytes:a?.bytes})}function m(r){try{return JSON.stringify(r)??String(r)}catch{return"\xAB[unserializable]\xBB"}}function A({tool:r,mode:e,serverType:o,durationMs:s,message:t,stack:n="",errorClass:i}){u.sendMcpErrorMessage([{...l(o),tool:r,message:t,stack:n,error_class:i,mode:e,duration_ms:s}])}export{T as logMcpToolCallAudit,E as reportMcpToolCalled,A as reportMcpToolError};
1
+ import{telemetry as c}from"../../../telemetry/index.js";import{serverAttributes as d}from"../utils/telemetry-attributes.js";import{EXECUTE_TOOL_NAME as p}from"../codemode/constants.js";import{auditInput as _,auditOutputDigest as f,auditSha256 as g,logAuditRecord as m}from"../audit/audit-log.js";function A({tool:r,mode:t,serverType:o,durationMs:i,outputLength:e,client:s,clientVersion:n}){c.sendMcpToolCalledMessage([{...d(o),tool:r,mode:t,output_length:e,duration_ms:i,client:s,client_version:n}])}function C({tool:r,mode:t,serverType:o,args:i,result:e,errorClass:s,client:n,clientVersion:a}){if(r===p)return;const l=M(i),u=e===void 0?void 0:f(e);m("Record MCP tool call",{tool:r,mode:t,server_type:o,error_class:s,client:n,client_version:a,args_sha256:g(l),args:_(l),result_sha256:u?.sha256,result_bytes:u?.bytes})}function M(r){try{return JSON.stringify(r)??String(r)}catch{return"\xAB[unserializable]\xBB"}}function b({tool:r,mode:t,serverType:o,durationMs:i,message:e,stack:s="",errorClass:n,client:a,clientVersion:l}){c.sendMcpErrorMessage([{...d(o),tool:r,message:e,stack:s,error_class:n,mode:t,duration_ms:i,client:a,client_version:l}])}export{C as logMcpToolCallAudit,A as reportMcpToolCalled,b as reportMcpToolError};
@@ -0,0 +1,6 @@
1
+ import type { McpToolFileSystem } from '@redocly/config';
2
+ import type { McpToolContext } from '../types.js';
3
+ export declare function attachToolFileSystem(context: McpToolContext): McpToolContext & {
4
+ fs: McpToolFileSystem;
5
+ };
6
+ //# sourceMappingURL=tool-file-system.d.ts.map
@@ -0,0 +1 @@
1
+ import{readFile as s,realpath as i}from"node:fs/promises";import{resolve as l,sep as n}from"node:path";function m(r){return{...r,fs:c(r.outdir)}}function c(r){return{async readFile(o){if(!r)throw new Error("Project files are not available in this environment.");const e=await i(r),t=l(e,o.replace(/^\/+/,"")),a=t.startsWith(e+n)?await i(t):t;if(!a.startsWith(e+n))throw new Error(`Invalid file path "${o}".`);return await s(a,"utf8")}}}export{m as attachToolFileSystem};
@@ -3,9 +3,11 @@ import type { AfterRoutesCreatedActions, AfterRoutesCreatedLifecycleContext } fr
3
3
  * Prepares chunked documents for semantic search, llms.txt, and Docs MCP.
4
4
  * Chunking runs when any of these is enabled: AI search, llms.txt, or Docs MCP.
5
5
  * embeddingsEnabled is true when AI search or Docs MCP is enabled (shared embedding index).
6
+ * writeLlmstxtFiles is false in develop mode, where the same content is generated on request
7
+ * instead (see plugins/search/llmstxt/create-llms-txt-generator.ts).
6
8
  */
7
- export declare function prepareSemanticDocuments(actions: AfterRoutesCreatedActions, context: AfterRoutesCreatedLifecycleContext, { embeddingsEnabled, llmstxtEnabled, }: {
9
+ export declare function prepareSemanticDocuments(actions: AfterRoutesCreatedActions, context: AfterRoutesCreatedLifecycleContext, { embeddingsEnabled, writeLlmstxtFiles, }: {
8
10
  embeddingsEnabled: boolean;
9
- llmstxtEnabled: boolean;
11
+ writeLlmstxtFiles: boolean;
10
12
  }): Promise<void>;
11
13
  //# sourceMappingURL=prepare-semantic-documents.d.ts.map
@@ -1,3 +1 @@
1
- import L from"node:path";import{existsSync as N}from"node:fs";import{writeFile as R,access as X,rm as B,constants as k}from"fs/promises";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import j from"picomatch";import{DEFAULT_LOCALE_PLACEHOLDER as E}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as G}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as Y}from"../../../constants/common.js";import{envConfig as C}from"../../../config/env-config.js";import{logger as c}from"../../../tools/notifiers/logger.js";import{shaHexShort as H}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as P}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as K}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{buildAgentFeedbackLlmsFooter as U}from"../../../utils/llmstxt/agent-feedback-llms-footer.js";import{validateLLMsTxtConfig as J,generateLLMsTxt as V}from"../llmstxt/index.js";import{ensureDir as F}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as W,extractTeamsFromScopeItems as q,getRbacTeamsListForResource as z}from"../../../utils/rbac.js";const w=20,S="llms.txt:";async function At(t,i,{embeddingsEnabled:o,llmstxtEnabled:s}){const l=L.join(t.outdir,Y);if(!s){try{await X(l,k.W_OK),await B(l)}catch{}if(!o)return}o&&c.info("Preparing semantic documents..."),s&&c.info(`${S} Generating llms.txt files...`);const p=c.startTiming(),a=c.startTiming(),m=t.getGlobalConfig("seo"),f=m?.llmstxt,T=C.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED??!1,M=L.resolve(t.outdir,G),u=t.getConfig(),O=u.access?.rbac??{},y=t.getAllRoutes(),b=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||E,I=(f?.excludeFiles||[]).map(e=>j(e)),d=[];if(await P(y,w,async e=>{if(e.excludeFromSearch)return;const $=await Q(e,t),x=await Z(e,$,i,t);if(x){if(s)for(const n of await x.getLLMsTxts()){if(I.some(v=>v(n.fsPath)))continue;const A=K(n.slug),r=L.join(t.outdir,A);F(r);const g=T?U(m,n.slug):void 0,D=g?`
2
-
3
- ${g}`:"";await R(r,`${n.content}${D}`),n.includeInLLMsTxt&&W(e,u)&&d.push(n)}if(o&&C.isBuildMode){const n=await x.getSearchDocuments();if(!n.length)return;const A=tt(e,O),r=e.versions?.find(({active:D})=>D),g=r&&{folder:r.folderId,label:r.label,default:r.default};await et(n,e.fsPath,A,M,b,g)}}}),o&&c.infoTime(a,"Semantic search documents prepared"),d.length)try{J(f);const e=await V(d,f,{title:m?.title,description:m?.description},i);F(l),await R(l,e),c.infoTime(p,`${S} files generated`)}catch(e){c.error(`${S} Failed to generate llms.txt file. ${e.message}`)}}async function Q(t,i){return t.getStaticData?t.getStaticData(t,i):{}}async function Z(t,i,o,s){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[h]:t[h],[_]:t[_]},o,s)}function tt(t,i){const o=q(t?.[h]);return o?.length?o:z(t,i)}async function et(t,i,o,s,l,p){await P(t,w,async a=>{const m=`${H(i+a.content)}.json`,f=F(L.join(s,m)),T=a.locale===E?l:a.locale;N(f)||await R(f,JSON.stringify({...a,rbacTeams:a.rbacTeams??o??[],version:p,locale:T}),"utf-8")})}export{At as prepareSemanticDocuments};
1
+ import p from"node:path";import{existsSync as O}from"node:fs";import{writeFile as h,access as y,rm as v,constants as b}from"fs/promises";import{REDOCLY_TEAMS_RBAC as N}from"@redocly/config";import{DEFAULT_LOCALE_PLACEHOLDER as P}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as X}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as $}from"../../../constants/common.js";import{envConfig as j}from"../../../config/env-config.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{shaHexShort as B}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as D}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as G}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{validateLLMsTxtConfig as H,generateLLMsTxt as k}from"../llmstxt/index.js";import{buildPageLlmsTxtMd as J}from"../llmstxt/build-page-llms-txt-md.js";import{getLlmsTxtExcludeMatcher as K}from"../llmstxt/get-llms-txt-exclude-matcher.js";import{isIncludedInLlmsTxt as U}from"../llmstxt/is-included-in-llms-txt.js";import{getRouteStaticData as V}from"../../../utils/get-route-static-data.js";import{getRouteAiDocumentsStore as W}from"../../../utils/get-route-ai-documents-store.js";import{ensureDir as R}from"../../../utils/fs.js";import{extractTeamsFromScopeItems as Y,getRbacTeamsListForResource as q}from"../../../utils/rbac.js";const _=20,S="llms.txt:";async function ht(t,m,{embeddingsEnabled:e,writeLlmstxtFiles:l}){const c=p.join(t.outdir,$);if(!l){try{await y(c,b.W_OK),await v(c)}catch{}if(!e)return}e&&n.info("Preparing semantic documents..."),l&&n.info(`${S} Generating llms.txt files...`);const g=n.startTiming(),r=n.startTiming(),s=t.getGlobalConfig("seo"),f=s?.llmstxt,T=p.resolve(t.outdir,X),u=t.getConfig(),A=u.access?.rbac??{},M=t.getAllRoutes(),C=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||P,E=K(s),L=[];if(await D(M,_,async o=>{if(o.excludeFromSearch)return;const w=await V(o,t),x=await W(o,w,m,t);if(x){if(l)for(const i of await x.getLLMsTxts()){if(E(i.fsPath))continue;const d=G(i.slug),a=p.join(t.outdir,d);R(a),await h(a,J(i,s)),U(i,o,u)&&L.push(i)}if(e&&j.isBuildMode){const i=await x.getSearchDocuments();if(!i.length)return;const d=z(o,A),a=o.versions?.find(({active:F})=>F),I=a&&{folder:a.folderId,label:a.label,default:a.default};await Q(i,o.fsPath,d,T,C,I)}}}),e&&n.infoTime(r,"Semantic search documents prepared"),L.length)try{H(f);const o=await k(L,f,{title:s?.title,description:s?.description},m);R(c),await h(c,o),n.infoTime(g,`${S} files generated`)}catch(o){n.error(`${S} Failed to generate llms.txt file. ${o.message}`)}}function z(t,m){const e=Y(t?.[N]);return e?.length?e:q(t,m)}async function Q(t,m,e,l,c,g){await D(t,_,async r=>{const s=`${B(m+r.content)}.json`,f=R(p.join(l,s)),T=r.locale===P?c:r.locale;O(f)||await h(f,JSON.stringify({...r,rbacTeams:r.rbacTeams??e??[],version:g,locale:T}),"utf-8")})}export{ht as prepareSemanticDocuments};
@@ -1 +1 @@
1
- import{readFile as R,readdir as E,appendFile as F}from"node:fs/promises";import m from"node:path";import{existsSync as I}from"node:fs";import{SEARCH_GROUP_FACET_FIELD as S,SEARCH_PRODUCT_FIELD as w,SEARCH_VERSION_FIELD as C}from"../../../../../constants/common.js";import{SEARCH_INDEX_FIELDS as $,SEARCH_DATA_EXPORT_FOLDER as g,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as O}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as v}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as j}from"../../../../config/env-config.js";import{ensureDir as h}from"../../../../utils/index.js";import{FlexSearchIndex as N}from"./search-index.js";class B{#e=new Map;#s;#t=0;async initIndexSchema(e){this.#s={document:{id:"id",tag:"tags",index:$},worker:!1,tokenize:"forward",context:{depth:2,resolution:9}}}#o(e,o){const i=this.#e.get(e);if(i)return i.find(t=>t.id===o)}#i(e,o){let i=this.#o(e,o);return i||(i=new N(o,this.#s),this.#e.set(e,[...this.#e.get(e)??[],i])),i}async addDocuments(e,o){if(e.length){const{group:i,locale:t,outDir:c}=o,n=this.#i(t,i);for(const r of e)n.add(r),j.isBuildMode&&(this.#t++,this.#t>=O&&await this.exportDocuments(c))}}getIndexesSize(){return this.#e.size}async search(e,o,i){return await v("com.redocly.search.performed",async t=>{t?.setAttribute("id","searchQueryId"),t?.setAttribute("object","searchQuery"),t?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:c,locale:n,filter:r,loadMore:a}=e,l=this.#e.get(n)??[];let f=[],d="",x=["v:default"];if(t?.setAttribute("locale",n),r)for(const s of r)s.field===S?f=[...f,...s.values]:s.field===w?d=`p:${s.values[0]}`:s.field===C&&s.values.length&&s.values.length===2&&(x=[...x,`v:${s.values[0]}:${s.values[1]}`]);const D={auth:o,query:c,offset:0,SEARCH_GROUP_FACET_FIELD:S,product:d,versions:x},p=[];let u={facets:{},documents:{}};if(a){const s=this.#o(n,a.groupKey);s&&p.push(s.search({...D,offset:a.offset}))}else for(const s of l)f&&f.length?f.includes(s.id)&&p.push(s.search(D)):p.push(s.search(D));const A=await Promise.all(p);for(const s of A){u.documents={...u.documents,...s.documents};for(const[y,_]of Object.entries(s.facets))u.facets[y]?u.facets[y]=[...u.facets[y],..._]:u.facets[y]=_}return u})}async exportDocuments(e){const o='{"documents":[',i=h(m.join(e,g));for(const[t,c]of this.#e){const n=h(m.join(i,t));for(const r of c){const a=Array.from(r.documents);if(a.length===0)continue;const l=h(m.join(n,`${r.id}.json`)),f=!I(l),d=JSON.stringify(a).substring(1).slice(0,-1),x=f?o+d:","+d;await F(l,x,{encoding:"utf8"}),r.clearDocuments()}}this.#t=0}async exportIndexes(e){const o=h(m.join(e,g));for(const[i,t]of this.#e){const c=h(m.join(o,i));for(const n of t){const r=h(m.join(c,`${n.id}.json`)),a={};await n.export((f,d)=>{a[f]=d});const l=`],"index":${JSON.stringify(a)}}`;await F(r,l,{encoding:"utf8"})}}this.#e.clear()}async import(e){const o=`${e}/${g}`;if(!I(o))return;const i=await E(o);for(const t of i){const c=await E(`${o}/${t}`);for(const n of c){const r=`${o}/${t}/${n}`,a=JSON.parse(await R(r,"utf-8")),l=m.parse(n).name;await this.#i(t,l).import(a)}}}countFacets(e,o,i){const t={};for(const[c,n]of i)t[c]=n.values.map(r=>({value:r,count:0,isCounterVisible:!1}));return t}cleanupFacetValues(e){}}export{B as FlexSearch};
1
+ import{readFile as R,readdir as F,appendFile as I}from"node:fs/promises";import h from"node:path";import{existsSync as C}from"node:fs";import{SEARCH_GROUP_FACET_FIELD as S,SEARCH_PRODUCT_FIELD as v,SEARCH_VERSION_FIELD as w}from"../../../../../constants/common.js";import{SEARCH_INDEX_FIELDS as $,SEARCH_DATA_EXPORT_FOLDER as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as O}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as j}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as N}from"../../../../config/env-config.js";import{ensureDir as m}from"../../../../utils/index.js";import{FlexSearchIndex as b}from"./search-index.js";class J{#e=new Map;#s;#t=0;async initIndexSchema(t){this.#s={document:{id:"id",tag:"tags",index:$},worker:!1,tokenize:"forward",context:{depth:2,resolution:9}}}#o(t,o){const i=this.#e.get(t);if(i)return i.find(s=>s.id===o)}#i(t,o){let i=this.#o(t,o);return i||(i=new b(o,this.#s),this.#e.set(t,[...this.#e.get(t)??[],i])),i}async addDocuments(t,o){if(t.length){const{group:i,locale:s,outDir:c}=o,n=this.#i(s,i);for(const r of t)n.add(r),N.isBuildMode&&(this.#t++,this.#t>=O&&await this.exportDocuments(c))}}getIndexesSize(){return this.#e.size}async search(t,o,i){return await j("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:c,locale:n,filter:r,loadMore:a}=t,l=this.#e.get(n)??[];let f=[],d="",x=["v:default"];if(s?.setAttribute("locale",n),r)for(const e of r)e.field===S?f=[...f,...e.values]:e.field===v?d=`p:${e.values[0]}`:e.field===w&&e.values.length&&e.values.length===2&&(x=[...x,`v:${e.values[0]}:${e.values[1]}`]);const g={auth:o,query:c,offset:0,SEARCH_GROUP_FACET_FIELD:S,product:d,versions:x},p=[];let u={facets:{},documents:{}};if(a){const e=this.#o(n,a.groupKey);e&&p.push(e.search({...g,offset:a.offset}))}else for(const e of l)f&&f.length?f.includes(e.id)&&p.push(e.search(g)):p.push(e.search(g));const _=await Promise.all(p),A=_.some(e=>e.hasCoveringHit);for(const e of _)if(!(A&&!e.hasCoveringHit)){u.documents={...u.documents,...e.documents};for(const[y,E]of Object.entries(e.facets))u.facets[y]?u.facets[y]=[...u.facets[y],...E]:u.facets[y]=E}return u})}async exportDocuments(t){const o='{"documents":[',i=m(h.join(t,D));for(const[s,c]of this.#e){const n=m(h.join(i,s));for(const r of c){const a=Array.from(r.documents);if(a.length===0)continue;const l=m(h.join(n,`${r.id}.json`)),f=!C(l),d=JSON.stringify(a).substring(1).slice(0,-1),x=f?o+d:","+d;await I(l,x,{encoding:"utf8"}),r.clearDocuments()}}this.#t=0}async exportIndexes(t){const o=m(h.join(t,D));for(const[i,s]of this.#e){const c=m(h.join(o,i));for(const n of s){const r=m(h.join(c,`${n.id}.json`)),a={};await n.export((f,d)=>{a[f]=d});const l=`],"index":${JSON.stringify(a)}}`;await I(r,l,{encoding:"utf8"})}}this.#e.clear()}async import(t){const o=`${t}/${D}`;if(!C(o))return;const i=await F(o);for(const s of i){const c=await F(`${o}/${s}`);for(const n of c){const r=`${o}/${s}/${n}`,a=JSON.parse(await R(r,"utf-8")),l=h.parse(n).name;await this.#i(s,l).import(a)}}}countFacets(t,o,i){const s={};for(const[c,n]of i)s[c]=n.values.map(r=>({value:r,count:0,isCounterVisible:!1}));return s}cleanupFacetValues(t){}}export{J as FlexSearch};
@@ -1,16 +1,20 @@
1
1
  import type { ExportHandler, IndexOptionsForDocumentSearch } from 'flexsearch';
2
- import type { FlexSearchData, SearchIndex, SearchParameters, SearchDocument } from '../../../../types';
2
+ import type { FlexSearchData, IndexedSearchDocument, SearchIndex, SearchParameters, SearchDocument } from '../../../../types';
3
3
  import type { SearchResponse } from '../../../../../types/index.js';
4
+ /** One group's results plus whether any of them holds every query word in a single value. */
5
+ export type IndexSearchResponse = SearchResponse & {
6
+ hasCoveringHit: boolean;
7
+ };
4
8
  export declare class FlexSearchIndex implements SearchIndex {
5
9
  #private;
6
10
  id: string;
7
11
  constructor(id: string, indexConfig: IndexOptionsForDocumentSearch<string>);
8
- get documents(): MapIterator<[number, SearchDocument]>;
12
+ get documents(): MapIterator<[number, IndexedSearchDocument]>;
9
13
  get documentsCount(): number;
10
14
  clearDocuments(): void;
11
- export(handler: ExportHandler<string | SearchDocument>): Promise<void>;
15
+ export(handler: ExportHandler<string | IndexedSearchDocument>): Promise<void>;
12
16
  import(searchData: FlexSearchData): Promise<void>;
13
17
  add(document: SearchDocument): void;
14
- search(params: SearchParameters): Promise<SearchResponse>;
18
+ search(params: SearchParameters): Promise<IndexSearchResponse>;
15
19
  }
16
20
  //# sourceMappingURL=search-index.d.ts.map
@@ -1 +1 @@
1
- import S from"flexsearch";import{REDOCLY_TEAMS_RBAC as I}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as w,SEARCH_LIMIT as y}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as A}from"../../../../telemetry/helpers/trace-step.js";import{highlightTextForSearch as u}from"../../../../utils/search/highlight-text-for-search.js";class C{#e;#t=new Map;#s=1;id;constructor(e,t){this.id=e,this.#e=new S.Document(t)}get documents(){return this.#t.entries()}get documentsCount(){return this.#s}clearDocuments(){this.#t.clear()}async export(e){await this.#e.export(e)}async import(e){const{documents:t,index:s}=e;this.#t.clear();for(const[r,i]of t)this.#t.set(r,i);for(const[r,i]of Object.entries(s))await this.#e.import(r,i)}add(e){e.tags||(e.tags=[]),this.#t.set(this.#s,e[I]?e:{...e,[I]:void 0}),this.#e.add(this.#s,e),this.#s++}async search(e){return await A("com.redocly.search.performed",async t=>{t?.setAttribute("id","searchQueryId"),t?.setAttribute("object","searchQuery"),t?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:s,offset:r,auth:i,product:o,versions:a}=e,n=[],c=i.teams,l={limit:y,offset:r};let m=new Map,d=await this.#e.searchAsync(s,{...l,tag:c});if(o){const h=await this.#e.searchAsync(s,{...l,tag:o});d=this.#i(d,h),t?.setAttribute("product",o)}if(a&&a.length){const h=await this.#e.searchAsync(s,{...l,tag:a});d=this.#i(d,h),t?.setAttribute("versions",a.join(","))}for(const h of d)for(const p of h.result){const f=m.get(p)?.fields||[];m.set(p,{fields:h.field?[...f,h.field]:[...f]})}let g=0;for(const[h,p]of m.entries()){if(g>=y)break;const f=this.#t.get(h);f&&!this.#n(f,a)&&(n.push({document:this.#o(f,s,p.fields),highlight:this.#a(f,s,p.fields)}),g++)}return{documents:{[this.id]:n},facets:{}}})}#o(e,t,s){return this.#c(e,t,s)}#a(e,t,s){const r={};let i=!1;for(const o of s)if(o==="path")r.path=e.path?e.path.map(a=>u(t,a)):[];else if(o.includes("parameters")){if(!i){const a=o.split(":")[1],n=e.parameters?.find(c=>{const l=c[a];return this.#r(t,typeof l=="boolean"?l.toString():l)});n&&(r.parameters=[{name:u(t,n.name),description:u(t,n.description),place:u(t,n.place),path:n.path?n.path.map(c=>u(t,c)):[]}],i=!0)}}else r[o]=u(t,e[o]);return r}#r=(e,t)=>{if(t){const s=e.split(/\s+/g);return Array.isArray(t)?t.some(r=>s.some(i=>r.toLowerCase().includes(i.toLowerCase()))):s.some(r=>t.toLowerCase().includes(r.toLowerCase()))}else return!1};#i(e,t){const s=[];for(const r of e){const i=[];for(const o of t)for(const a of r.result){const n=o.result.find(c=>c===a);n&&i.push(n)}i.length&&s.push({result:i,field:r.field})}return s}#n(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(s=>s.includes(e.versionFolderId??""))&&!t.some(s=>s.includes(e.version??"")))}#c(e,t,s){for(const i of w)if(s.some(o=>o===i))return e;let r;for(const i of s)if(i.includes("parameters")){const o=i.split(":")[1],a=e.parameters?.find(n=>{const c=n[o];return this.#r(t,typeof c=="boolean"?c.toString():c)});if(a){r=a.deepLink;break}}if(r){const i=r.split("#")[1];return{...e,url:`${e.url}#${i}`}}return e}}export{C as FlexSearchIndex};
1
+ import L from"flexsearch";import{REDOCLY_TEAMS_RBAC as A}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as R,SEARCH_LIMIT as D}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as b}from"../../../../telemetry/helpers/trace-step.js";import{highlightTextForSearch as u}from"../../../../utils/search/highlight-text-for-search.js";function v(S){const{name:e,description:t,place:r,path:o,deepLink:s}=S,i=s?.indexOf("#")??-1;return{name:e,description:t,place:r,...o&&{path:o},...s&&{deepLink:i>=0?s.slice(i+1):s}}}class C{#e;#t=new Map;#s=1;id;constructor(e,t){this.id=e,this.#e=new L.Document(t)}get documents(){return this.#t.entries()}get documentsCount(){return this.#s}clearDocuments(){this.#t.clear()}async export(e){await this.#e.export(e)}async import(e){const{documents:t,index:r}=e;this.#t.clear();for(const[o,s]of t)this.#t.set(o,s);for(const[o,s]of Object.entries(r))await this.#e.import(o,s)}add(e){const t={...e,tags:e.tags??[],[A]:e[A],...e.parameters&&{parameters:e.parameters.map(v)}};this.#t.set(this.#s,t),this.#e.add(this.#s,t),this.#s++}async search(e){return await b("com.redocly.search.performed",async t=>{t?.setAttribute("id","searchQueryId"),t?.setAttribute("object","searchQuery"),t?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:r,offset:o,auth:s,product:i,versions:n}=e,c=[],l=s.teams,p={limit:D,offset:o};let h=new Map,m=await this.#e.searchAsync(r,{...p,tag:l});if(i){const a=await this.#e.searchAsync(r,{...p,tag:i});m=this.#a(m,a),t?.setAttribute("product",i)}if(n&&n.length){const a=await this.#e.searchAsync(r,{...p,tag:n});m=this.#a(m,a),t?.setAttribute("versions",n.join(","))}for(const a of m)for(const d of a.result){const f=h.get(d)?.fields||[];h.set(d,{fields:a.field?[...f,a.field]:[...f]})}const x=this.#r(r),g=[];for(const[a,d]of h.entries()){const f=this.#t.get(a);f&&!this.#h(f,n)&&g.push({document:f,fields:d.fields,score:this.#l(x,f)})}const I=g.filter(a=>a.score>=x.length),y=I.length?I:g;y.sort((a,d)=>d.score-a.score);for(const a of y.slice(0,D))c.push({document:this.#n(a.document,r,a.fields),highlight:this.#c(a.document,r,a.fields)});return{documents:{[this.id]:c},facets:{},hasCoveringHit:I.length>0}})}#n(e,t,r){return this.#f(e,t,r)}#c(e,t,r){const o={};let s=!1;for(const i of r)if(i==="path")o.path=e.path?e.path.map(n=>u(t,n)):[];else if(i.includes("parameters")){if(!s){const n=i.split(":")[1],c=this.#o(t,n,e.parameters);c&&(o.parameters=[{name:u(t,c.name),description:u(t,c.description),place:u(t,c.place),path:c.path?c.path.map(l=>u(t,l)):[]}],s=!0)}}else o[i]=u(t,e[i]);return o}#r(e){return[...new Set(e.toLowerCase().split(/\s+/g).filter(Boolean))]}#i(e,t){const r=t.toLowerCase().replace(/\s+/g," "),o=e.filter(i=>r.includes(i)).length;let s=0;for(let i=1;i<e.length;i++)r.includes(`${e[i-1]} ${e[i]}`)&&s++;return o+s/e.length}#l(e,t){let r=0;const o=s=>{if(s==null)return;const i=this.#i(e,String(s));i>r&&(r=i)};o(t.title),o(t.text),o(t.httpPath),o(t.path?.join(" "));for(const s of t.parameters??[])o([s.name,s.description,s.place].filter(Boolean).join(" "));return r}#o(e,t,r){const o=this.#r(e);let s,i=0;for(const n of r??[]){const c=n[t],l=(Array.isArray(c)?c:[c]).filter(h=>h!=null).map(h=>String(h)).join(" "),p=this.#i(o,l);p>i&&(i=p,s=n)}return s}#a(e,t){const r=[];for(const o of e){const s=[];for(const i of t)for(const n of o.result){const c=i.result.find(l=>l===n);c&&s.push(c)}s.length&&r.push({result:s,field:o.field})}return r}#h(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(r=>r.includes(e.versionFolderId??""))&&!t.some(r=>r.includes(e.version??"")))}#f(e,t,r){for(const s of R)if(r.some(i=>i===s))return e;let o;for(const s of r)if(s.includes("parameters")){const i=s.split(":")[1],n=this.#o(t,i,e.parameters);if(n){o=n.deepLink;break}}return o?{...e,url:`${e.url}#${o}`}:e}}export{C as FlexSearchIndex};
@@ -1 +1 @@
1
- import{appendFile as D}from"node:fs/promises";import{existsSync as P}from"node:fs";import E from"node:path";import{Client as v}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as L,SEARCH_RBAC_FIELD as T,SEARCH_VERSION_FIELD as h}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as j,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as k,HIGHLIGHTED_TEXT_MAX_LENGTH as R,SEARCH_DATA_EXPORT_FOLDER as C,SEARCH_DOCUMENT_METADATA_KEY as w,SEARCH_GROUP_LIMIT as O,SEARCH_MAX_FACET_VALUES as y,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as q}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as N}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as _}from"../../../../config/env-config.js";import{logger as F}from"../../../../tools/notifiers/logger.js";import{ensureDir as b}from"../../../../utils/index.js";class J{#e=null;#a="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"deprecated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:L,type:"string",facet:!0,optional:!0},{name:h,type:"object",facet:!0,optional:!0},{name:T,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#r={ORGANIZATION_ID:_.ORGANIZATION_ID??"",PROJECT_ID:_.PROJECT_ID??"",TYPESENSE_API_URL:_.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:_.TYPESENSE_API_KEY??""};constructor(){if(!_.isBuildMode){for(const[e,t]of Object.entries(this.#r))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#a=`${this.#r.ORGANIZATION_ID}_${this.#r.PROJECT_ID}_`,this.#e=new v({nodes:[{url:this.#r.TYPESENSE_API_URL}],apiKey:this.#r.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#_(e)}async addDocuments(e,t){e.push(j);const{locale:s,outDir:o}=t,r=e.map(n=>{const a={...n},c=n[w];return c&&(c.curated&&(a.metadata_curated=c.curated),c.excludes&&(a.metadata_keywords_excludes=c.excludes),c.includes&&(a.metadata_keywords_includes=c.includes)),a}),i=this.#s.get(s)??[];this.#s.set(s,i.concat(r)),i.length+e.length>=q&&await this.exportDocuments(o)}async search(e,t){return await N("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:o,locale:r,filter:i,loadMore:n}=e,a=this.#u(r),c={collection:a,q:o||"*",query_by:this.#f(),max_facet_values:y};if(s?.setAttribute("collectionName",a),s?.setAttribute("locale",r),this.#e)if(n){const{groupKey:l,offset:u}=n,f={offset:u,filter_by:this.#o(t,i),facet_by:"*",per_page:O};return s?.setAttribute("isLoadMore",!0),s?.setAttribute("filter",f.filter_by),this.#m(await this.#e.collections(a).documents().search({...c,...f}),l)}else{const l=this.#o(t,i);s?.setAttribute("filter",l);const u=await this.#e.multiSearch.perform({searches:this.#E(t,i)},c),f=this.#i(u,this.#t.filter(m=>m.facet).map(m=>m.name));f&&F.warn("Search facet requests failed: %s",f);const p=this.#p(u),d=(p[A]??[]).map(m=>m.value);s?.setAttribute("groups",d.join(",")),d.length===y&&F.warn("Search category facet list reached the limit of %s; results for some categories may be missing",y);const I=[...new Set(this.#h(i))].slice(0,y),g=I.length?I:d;if(!g.length)return{facets:p,documents:{},groupCounts:{}};const $=await this.#e.multiSearch.perform({searches:g.map(m=>({filter_by:`${A}:=${this.#n(m)} && ${l}`,per_page:O}))},c),S=this.#i($,g);return S&&F.warn("Search category requests failed: %s",S),this.#d($,g,p,i)}else return{facets:{},documents:{}}})}#m(e,t){const s={facets:{},documents:{[t]:[]},groupCounts:typeof e.found=="number"?{[t]:e.found}:{}};if(e.hits&&e.hits.length)for(const o of e.hits)s.documents[t].push({document:this.#c(o),highlight:this.#l(o)});return s}#p(e){const t={};if("results"in e){for(const s of e.results)if(s.facet_counts&&s.facet_counts.length)for(const o of s.facet_counts)t[o.field_name]=o.counts.map(r=>({value:r.value,count:r.count}))}return t}#i(e,t){return"results"in e?e.results.map((s,o)=>({result:s,label:t[o]})).filter(({result:s})=>"error"in s).map(({result:s,label:o})=>`${o}: ${s.error}`).join("; "):""}#d(e,t,s,o){const r={},i={facets:s,documents:{},groupCounts:r};for(const n of this.#h(o))i.documents[n]=[];return"results"in e&&e.results.forEach((n,a)=>{const c=t[a];typeof n.found=="number"&&(r[c]=n.found);const l=n.hits??[];l.length&&(i.documents[c]=l.map(u=>({document:this.#c(u),highlight:this.#l(u)})))}),i}#c(e){return this.#y(e)}#l(e){const t={},s=[];for(const[o,r]of Object.entries(e.highlight??{}))if(Array.isArray(r)){if(o==="path"){const i=r,n=[];for(const a of i)n.push(a.snippet);t.path=n}else if(o==="parameters"){const i=r;for(const n of i){let a=!1;for(const[c,l]of Object.entries(n))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(a=!0);else l.matched_tokens?.length&&(a=!0);if(a){const c={name:n.name?.snippet||"",description:n.description?.snippet||"",place:n.place?.snippet||"",path:n.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[o]=r.snippet,s.push(o);for(const[o,r]of Object.entries(e.document))!s.includes(o)&&typeof r=="string"&&(t[o]=r.length>R?`${r.substring(0,R)}...`:r);return t.parameters||(t.parameters=[]),t}#y(e){let t;const s=Object.keys(e.highlight??{});for(const r of k)if(s.some(i=>i===r))return e.document;const o=e.highlight?.parameters;if(o){for(const r of o)for(const[i,n]of Object.entries(r))if(i!=="deepLink"){if(Array.isArray(n)){for(const a of n)if(a.matched_tokens?.length){t=r.deepLink?.snippet??t;break}}else if(n.matched_tokens?.length){t=r.deepLink?.snippet??t;break}}}if(t){const r=t.split("#")[1];return{...e.document,url:`${e.document.url}#${r}`}}return e.document}async exportDocuments(e){const t='{"documents":[',s=b(E.join(e,C));for(const[o,r]of this.#s){if(r.length===0)continue;const i=b(E.join(s,`${o}.json`)),n=!P(i),a=JSON.stringify(r).substring(1).slice(0,-1),c=n?t+a:","+a;await D(i,c,{encoding:"utf8"}),this.#s.set(o,[])}}async exportIndexes(e){const t=b(E.join(e,C));for(const s of this.#s.keys()){const o=b(E.join(t,`${s}.json`)),r=`],"schemaFields":${JSON.stringify(this.#t)}}`;await D(o,r,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await N("com.redocly.search.facets",async s=>{s?.setAttribute("id","searchFacetsId"),s?.setAttribute("object","searchFacets"),s?.setAttribute("uri","urn:redocly:realm:api:searchFacets:searchFacetsId");const{locale:o,query:r,facetQuery:i,filter:n,field:a}=e,c=this.#u(o),l={q:r||"*",query_by:this.#f(),facet_by:"*",facet_query:this.#g(i,a),filter_by:this.#o(t,n,a),max_facet_values:y};if(s?.setAttribute("collectionName",c),s?.setAttribute("query",l.q),s?.setAttribute("facetQuery",l.facet_query),s?.setAttribute("filter",l.filter_by),this.#e){const u={},f=await this.#e.collections(c).documents().search(l);if(f.facet_counts&&f.facet_counts.length)for(const p of f.facet_counts)u[p.field_name]=p.counts.map(d=>({value:d.value,count:d.count,isCounterVisible:!!r||(n?.length||0)>0}));return u}else return{}})}#u(e){return`${this.#a}${e}`}#_(e){for(const[t,{queryable:s}]of e)this.#t.find(o=>o.name===t)||this.#t.push({queryable:s,name:t,type:"string",facet:!0,optional:!0})}#f(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#n(e){return`\`${e.replaceAll("`","")}\``}#o(e,t,s){const o=`${T}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let r=`${h}.isDefault:true`;if(t&&t.length){const i=t.filter(a=>a.field!==s&&a.field!==h).map(a=>{const c=a.values.map(l=>this.#n(l));return c.length?`${a.field}:=[${c.join(", ")}]`:""}).join(" && "),n=t.find(a=>a.field===h);if(n&&n.values.length&&n.values.length===2){const a=n.values[0],c=n.values[1],l=`(${h}.folderId:! ${a} && ${h}.isDefault:true)`,u=`(${h}.folderId: ${a} && ${h}.version:=${this.#n(c)})`;r=`(${l} || ${u})`}return i?`${o} && ${i} && ${r}`:`${o} && ${r}`}else return`${o} && ${r}`}#g(e,t){return e&&t?`${t}:${e}`:""}#h(e){const t=[];if(e&&e.length)for(const s of e)s.field===A&&t.push(...s.values);return t}#E(e,t){const s=[],o=this.#t.filter(r=>r.facet);for(const r of o){const i={facet_by:r.name,filter_by:this.#o(e,t,r.name)};s.push(i)}return s}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(s=>{s.values=[]}),e.setSearchFacets(t)}}export{J as Typesense};
1
+ import{appendFile as D}from"node:fs/promises";import{existsSync as v}from"node:fs";import b from"node:path";import{Client as N}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as q,SEARCH_RBAC_FIELD as T,SEARCH_VERSION_FIELD as h}from"../../../../../constants/common.js";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as L,HIGHLIGHTED_TEXT_MAX_LENGTH as R,SEARCH_DATA_EXPORT_FOLDER as C,SEARCH_DOCUMENT_METADATA_KEY as j,SEARCH_GROUP_LIMIT as O,SEARCH_MAX_FACET_VALUES as y,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as k}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as P}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as _}from"../../../../config/env-config.js";import{logger as F}from"../../../../tools/notifiers/logger.js";import{ensureDir as E}from"../../../../utils/index.js";class X{#e=null;#o="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"deprecated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:"parameters.name",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.description",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.place",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"parameters.path",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:q,type:"string",facet:!0,optional:!0},{name:h,type:"object",facet:!0,optional:!0},{name:T,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#r={ORGANIZATION_ID:_.ORGANIZATION_ID??"",PROJECT_ID:_.PROJECT_ID??"",TYPESENSE_API_URL:_.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:_.TYPESENSE_API_KEY??""};constructor(){if(!_.isBuildMode){for(const[e,t]of Object.entries(this.#r))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#o=`${this.#r.ORGANIZATION_ID}_${this.#r.PROJECT_ID}_`,this.#e=new N({nodes:[{url:this.#r.TYPESENSE_API_URL}],apiKey:this.#r.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#_(e)}async addDocuments(e,t){const{locale:s,outDir:a}=t,r=e.map(n=>{const o={...n},c=n[j];return c&&(c.curated&&(o.metadata_curated=c.curated),c.excludes&&(o.metadata_keywords_excludes=c.excludes),c.includes&&(o.metadata_keywords_includes=c.includes)),o}),i=this.#s.get(s)??[];this.#s.set(s,i.concat(r)),i.length+e.length>=k&&await this.exportDocuments(a)}async search(e,t){return await P("com.redocly.search.performed",async s=>{s?.setAttribute("id","searchQueryId"),s?.setAttribute("object","searchQuery"),s?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const{query:a,locale:r,filter:i,loadMore:n}=e,o=this.#u(r),c={collection:o,q:a||"*",query_by:this.#f(),max_facet_values:y};if(s?.setAttribute("collectionName",o),s?.setAttribute("locale",r),this.#e)if(n){const{groupKey:l,offset:u}=n,f={offset:u,filter_by:this.#a(t,i),facet_by:"*",per_page:O};return s?.setAttribute("isLoadMore",!0),s?.setAttribute("filter",f.filter_by),this.#p(await this.#e.collections(o).documents().search({...c,...f}),l)}else{const l=this.#a(t,i);s?.setAttribute("filter",l);const u=await this.#e.multiSearch.perform({searches:this.#b(t,i)},c),f=this.#i(u,this.#t.filter(p=>p.facet).map(p=>p.name));f&&F.warn("Search facet requests failed: %s",f);const m=this.#m(u),d=(m[A]??[]).map(p=>p.value);s?.setAttribute("groups",d.join(",")),d.length===y&&F.warn("Search category facet list reached the limit of %s; results for some categories may be missing",y);const I=[...new Set(this.#h(i))].slice(0,y),g=I.length?I:d;if(!g.length)return{facets:m,documents:{},groupCounts:{}};const $=await this.#e.multiSearch.perform({searches:g.map(p=>({filter_by:`${A}:=${this.#n(p)} && ${l}`,per_page:O}))},c),S=this.#i($,g);return S&&F.warn("Search category requests failed: %s",S),this.#d($,g,m,i)}else return{facets:{},documents:{}}})}#p(e,t){const s={facets:{},documents:{[t]:[]},groupCounts:typeof e.found=="number"?{[t]:e.found}:{}};if(e.hits&&e.hits.length)for(const a of e.hits)s.documents[t].push({document:this.#c(a),highlight:this.#l(a)});return s}#m(e){const t={};if("results"in e){for(const s of e.results)if(s.facet_counts&&s.facet_counts.length)for(const a of s.facet_counts)t[a.field_name]=a.counts.map(r=>({value:r.value,count:r.count}))}return t}#i(e,t){return"results"in e?e.results.map((s,a)=>({result:s,label:t[a]})).filter(({result:s})=>"error"in s).map(({result:s,label:a})=>`${a}: ${s.error}`).join("; "):""}#d(e,t,s,a){const r={},i={facets:s,documents:{},groupCounts:r};for(const n of this.#h(a))i.documents[n]=[];return"results"in e&&e.results.forEach((n,o)=>{const c=t[o];typeof n.found=="number"&&(r[c]=n.found);const l=n.hits??[];l.length&&(i.documents[c]=l.map(u=>({document:this.#c(u),highlight:this.#l(u)})))}),i}#c(e){return this.#y(e)}#l(e){const t={},s=[];for(const[a,r]of Object.entries(e.highlight??{}))if(Array.isArray(r)){if(a==="path"){const i=r,n=[];for(const o of i)n.push(o.snippet);t.path=n}else if(a==="parameters"){const i=r;for(const n of i){let o=!1;for(const[c,l]of Object.entries(n))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(o=!0);else l.matched_tokens?.length&&(o=!0);if(o){const c={name:n.name?.snippet||"",description:n.description?.snippet||"",place:n.place?.snippet||"",path:n.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[a]=r.snippet,s.push(a);for(const[a,r]of Object.entries(e.document))!s.includes(a)&&typeof r=="string"&&(t[a]=r.length>R?`${r.substring(0,R)}...`:r);return t.parameters||(t.parameters=[]),t}#y(e){let t;const s=Object.keys(e.highlight??{});for(const r of L)if(s.some(i=>i===r))return e.document;const a=e.highlight?.parameters;if(a){for(const r of a)for(const[i,n]of Object.entries(r))if(i!=="deepLink"){if(Array.isArray(n)){for(const o of n)if(o.matched_tokens?.length){t=r.deepLink?.snippet??t;break}}else if(n.matched_tokens?.length){t=r.deepLink?.snippet??t;break}}}if(t){const r=t.split("#")[1];return{...e.document,url:`${e.document.url}#${r}`}}return e.document}async exportDocuments(e){const t='{"documents":[',s=E(b.join(e,C));for(const[a,r]of this.#s){if(r.length===0)continue;const i=E(b.join(s,`${a}.json`)),n=!v(i),o=JSON.stringify(r).substring(1).slice(0,-1),c=n?t+o:","+o;await D(i,c,{encoding:"utf8"}),this.#s.set(a,[])}}async exportIndexes(e){const t=E(b.join(e,C));for(const s of this.#s.keys()){const a=E(b.join(t,`${s}.json`)),r=`],"schemaFields":${JSON.stringify(this.#t)}}`;await D(a,r,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await P("com.redocly.search.facets",async s=>{s?.setAttribute("id","searchFacetsId"),s?.setAttribute("object","searchFacets"),s?.setAttribute("uri","urn:redocly:realm:api:searchFacets:searchFacetsId");const{locale:a,query:r,facetQuery:i,filter:n,field:o}=e,c=this.#u(a),l={q:r||"*",query_by:this.#f(),facet_by:"*",facet_query:this.#g(i,o),filter_by:this.#a(t,n,o),max_facet_values:y};if(s?.setAttribute("collectionName",c),s?.setAttribute("query",l.q),s?.setAttribute("facetQuery",l.facet_query),s?.setAttribute("filter",l.filter_by),this.#e){const u={},f=await this.#e.collections(c).documents().search(l);if(f.facet_counts&&f.facet_counts.length)for(const m of f.facet_counts)u[m.field_name]=m.counts.map(d=>({value:d.value,count:d.count,isCounterVisible:!!r||(n?.length||0)>0}));return u}else return{}})}#u(e){return`${this.#o}${e}`}#_(e){for(const[t,{queryable:s}]of e)this.#t.find(a=>a.name===t)||this.#t.push({queryable:s,name:t,type:"string",facet:!0,optional:!0})}#f(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#n(e){return`\`${e.replaceAll("`","")}\``}#a(e,t,s){const a=`${T}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let r=`${h}.isDefault:true`;if(t&&t.length){const i=t.filter(o=>o.field!==s&&o.field!==h).map(o=>{const c=o.values.map(l=>this.#n(l));return c.length?`${o.field}:=[${c.join(", ")}]`:""}).join(" && "),n=t.find(o=>o.field===h);if(n&&n.values.length&&n.values.length===2){const o=n.values[0],c=n.values[1],l=`(${h}.folderId:! ${o} && ${h}.isDefault:true)`,u=`(${h}.folderId: ${o} && ${h}.version:=${this.#n(c)})`;r=`(${l} || ${u})`}return i?`${a} && ${i} && ${r}`:`${a} && ${r}`}else return`${a} && ${r}`}#g(e,t){return e&&t?`${t}:${e}`:""}#h(e){const t=[];if(e&&e.length)for(const s of e)s.field===A&&t.push(...s.values);return t}#b(e,t){const s=[],a=this.#t.filter(r=>r.facet);for(const r of a){const i={facet_by:r.name,filter_by:this.#a(e,t,r.name)};s.push(i)}return s}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(s=>{s.values=[]}),e.setSearchFacets(t)}}export{X as Typesense};
@@ -1 +1 @@
1
- import{DEFAULT_SEARCH_ENGINE as s,REDOCLY_TEAMS_RBAC as E}from"@redocly/config";import{envConfig as c}from"../../config/env-config.js";import{logger as p}from"../../tools/notifiers/logger.js";import{reporter as u}from"../../tools/notifiers/reporter.js";import{prepareSearchDocuments as S}from"./documents/search-documents.js";import{SearchEngine as b}from"./engines/search-engine.js";import{prepareSemanticDocuments as y}from"./ai-indexer/prepare-semantic-documents.js";import{isAiSearchEnabled as D,shouldGenerateEmbeddings as A}from"./utils.js";import{telemetryTraceStep as C}from"../../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";async function k(){let e=!0;return{async afterRoutesCreated(t,n){(c.SEARCH_DEV_REINIT||e)&&await _(t,n),e=!1},id:"search"}}async function _(e,t){await C("com.redocly.build.plugin.search",async n=>{const r=e.getConfig();if(n?.setAttribute("config",JSON.stringify(r.search||{})),r.search?.hide){p.info("Search is disabled in the config, skipping");return}const o=r.search?.engine||s,m=c.isDevelopMode?c.SEARCH_DEV_DEBUG?o:s:o,{l10n:l}=e.getGlobalData(),d=D(r),i=r.access?.rbac?.features?.aiSearch,f=A(r);let a;try{a=new b(m,l)}catch(g){await u.panic(g);return}await a.initIndexSchema(e.getSearchFacets()),e.setSearchEngine(a),e.setGlobalData({searchFeatures:{advanced:{enabled:m!==s&&!r.search?.filters?.hide},ai:{enabled:d,[E]:i&&Object.keys(i).length?i:void 0}}}),await S(t.fs,e,a);const h=R.instance().canAccessFeature("seo")===!0&&r.seo?.llmstxt?.hide!==!0;await y(e,t,{embeddingsEnabled:f,llmstxtEnabled:h})})}export{k as searchPlugin};
1
+ import{DEFAULT_SEARCH_ENGINE as o,REDOCLY_TEAMS_RBAC as u}from"@redocly/config";import{envConfig as i}from"../../config/env-config.js";import{logger as E}from"../../tools/notifiers/logger.js";import{reporter as S}from"../../tools/notifiers/reporter.js";import{prepareSearchDocuments as b}from"./documents/search-documents.js";import{SearchEngine as D}from"./engines/search-engine.js";import{prepareSemanticDocuments as y}from"./ai-indexer/prepare-semantic-documents.js";import{isAiSearchEnabled as A,shouldGenerateEmbeddings as C,shouldIndexSearchDocuments as w}from"./utils.js";import{telemetryTraceStep as R}from"../../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as _}from"../../entitlements/entitlements-provider.js";async function P(){let e=!0;return{async afterRoutesCreated(t,n){(i.SEARCH_DEV_REINIT||e)&&await v(t,n),e=!1},id:"search"}}async function v(e,t){await R("com.redocly.build.plugin.search",async n=>{const r=e.getConfig();if(n?.setAttribute("config",JSON.stringify(r.search||{})),r.search?.hide){E.info("Search is disabled in the config, skipping");return}const m=r.search?.engine||o,s=i.isDevelopMode?i.SEARCH_DEV_DEBUG?m:o:m,{l10n:l}=e.getGlobalData(),h=A(r),c=r.access?.rbac?.features?.aiSearch,d=C(r);let a;try{a=new D(s,l)}catch(p){await S.panic(p);return}await a.initIndexSchema(e.getSearchFacets()),e.setSearchEngine(a),e.setGlobalData({searchFeatures:{advanced:{enabled:s!==o&&!r.search?.filters?.hide},ai:{enabled:h,[u]:c&&Object.keys(c).length?c:void 0}}}),w(s)&&await b(t.fs,e,a);const f=_.instance(),g=!i.isDevelopMode&&f.canAccessFeature("seo")===!0&&r.seo?.llmstxt?.hide!==!0;await y(e,t,{embeddingsEnabled:d,writeLlmstxtFiles:g})})}export{P as searchPlugin};
@@ -0,0 +1,4 @@
1
+ import type { SeoConfig } from '@redocly/config';
2
+ import type { LLMsTxt } from './types.js';
3
+ export declare function buildPageLlmsTxtMd(llmsTxt: LLMsTxt, seoConfig: SeoConfig | undefined): string;
4
+ //# sourceMappingURL=build-page-llms-txt-md.d.ts.map
@@ -0,0 +1,3 @@
1
+ import{envConfig as t}from"../../../config/env-config.js";import{buildAgentFeedbackLlmsFooter as r}from"../../../utils/llmstxt/agent-feedback-llms-footer.js";function d(n,e){const o=t.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED?r(e,n.slug):void 0;return`${n.content}${o?`
2
+
3
+ ${o}`:""}`}export{d as buildPageLlmsTxtMd};
@@ -0,0 +1,4 @@
1
+ import type { Store } from '../../../store';
2
+ import type { LifecycleContext, LlmsTxtGenerator } from '../../../types';
3
+ export declare function createLlmsTxtGenerator(store: Store, context: LifecycleContext): LlmsTxtGenerator;
4
+ //# sourceMappingURL=create-llms-txt-generator.d.ts.map
@@ -0,0 +1 @@
1
+ import p from"node:path";import{logger as f}from"../../../tools/notifiers/logger.js";import{promiseMapLimit as x}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as L}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{getRouteStaticData as T}from"../../../utils/get-route-static-data.js";import{getRouteAiDocumentsStore as w}from"../../../utils/get-route-ai-documents-store.js";import{generateLLMsTxt as h,validateLLMsTxtConfig as M}from"./index.js";import{buildPageLlmsTxtMd as S}from"./build-page-llms-txt-md.js";import{getLlmsTxtExcludeMatcher as m}from"./get-llms-txt-exclude-matcher.js";import{isIncludedInLlmsTxt as R}from"./is-included-in-llms-txt.js";import{EntitlementsProvider as C}from"../../../entitlements/entitlements-provider.js";const A=20;function v(i,c){const a=new WeakMap,l=()=>{const t=i.getGlobalConfig("seo");return C.instance().canAccessFeature("seo")===!0&&t?.llmstxt?.hide!==!0},d=async t=>{if(t.excludeFromSearch)return[];const e=i,n=await T(t,e);return await(await w(t,n,c,e))?.getLLMsTxts()??[]},u=t=>{const e=a.get(t);if(e)return e;const n=d(t).catch(o=>(a.delete(t),f.warn(`Failed to generate Markdown for LLMs of "${t.slug}". ${o}`),[]));return a.set(t,n),n},g=t=>{const e=t==="/index.html.md"?"/":t.replace(/\.md$/,"");for(let n=e;n.startsWith("/");){const o=i.getRouteBySlug(n,{followRedirect:!1});if(o?.getAiDocumentsStore)return o;const r=p.posix.dirname(n);if(r===n)return;n=r}};return{async getPageMarkdown(t){if(!l())return;const e=g(t);if(!e)return;const n=i.getGlobalConfig("seo"),o=m(n),r=(await u(e)).find(s=>L(s.slug)===t&&!o(s.fsPath));if(r)return{route:e,content:S(r,n)}},async getLlmsTxt(){if(!l())return;const t=i.getConfig(),e=i.getGlobalConfig("seo"),n=m(e),o=[];if(await x(i.getAllRoutes(),A,async r=>{for(const s of await u(r))!n(s.fsPath)&&R(s,r,t)&&o.push(s)}),!!o.length)try{return M(e?.llmstxt),await h(o,e?.llmstxt,{title:e?.title,description:e?.description},c)}catch(r){f.error(`Failed to generate llms.txt. ${r}`);return}}}}export{v as createLlmsTxtGenerator};
@@ -0,0 +1,4 @@
1
+ import picomatch from 'picomatch';
2
+ import type { SeoConfig } from '@redocly/config';
3
+ export declare function getLlmsTxtExcludeMatcher(seoConfig: SeoConfig | undefined): picomatch.Matcher;
4
+ //# sourceMappingURL=get-llms-txt-exclude-matcher.d.ts.map
@@ -0,0 +1 @@
1
+ import e from"picomatch";function l(t){return e(t?.llmstxt?.excludeFiles||[])}export{l as getLlmsTxtExcludeMatcher};
@@ -1,10 +1,10 @@
1
1
  import type { SeoConfig } from '@redocly/config';
2
- import type { AfterRoutesCreatedLifecycleContext } from '../../../types';
2
+ import type { LifecycleContext } from '../../../types';
3
3
  import type { LLMsTxt } from './types';
4
4
  export declare function generateLLMsTxt(llmstxts: LLMsTxt[], llmstxtConfig: SeoConfig['llmstxt'] | undefined, fallbackConfig: {
5
5
  title?: string;
6
6
  description?: string;
7
- } | undefined, context: AfterRoutesCreatedLifecycleContext): Promise<string>;
7
+ } | undefined, context: LifecycleContext): Promise<string>;
8
8
  export declare function llmsTxtLink({ title, description, slug, }: {
9
9
  title: LLMsTxt['title'];
10
10
  description: LLMsTxt['description'];
@@ -0,0 +1,6 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
2
+ import type { PageProps, PageStaticData } from '@redocly/config';
3
+ import type { PageRouteDetails } from '../../../types';
4
+ import type { LLMsTxt } from './types.js';
5
+ export declare function isIncludedInLlmsTxt(llmsTxt: LLMsTxt, route: PageRouteDetails<PageStaticData, PageProps>, config: RedoclyConfig): boolean;
6
+ //# sourceMappingURL=is-included-in-llms-txt.d.ts.map
@@ -0,0 +1 @@
1
+ import{isResourcePubliclyAccessible as i}from"../../../utils/rbac.js";function o(e,n,c){return!!e.includeInLLMsTxt&&i(n,c)}export{o as isIncludedInLlmsTxt};
@@ -1,7 +1,8 @@
1
- import type { RedoclyConfig } from '@redocly/config';
1
+ import type { RedoclyConfig, SearchEngineType } from '@redocly/config';
2
2
  export declare function isAiSearchEnabled(config: RedoclyConfig): boolean;
3
3
  export declare function isDocsMcpEnabled(config: RedoclyConfig): boolean;
4
4
  export declare function shouldGenerateEmbeddings(config: RedoclyConfig): boolean;
5
+ export declare function shouldIndexSearchDocuments(engine: SearchEngineType): boolean;
5
6
  export declare function getSearchDocumentGroup(documentFacets?: Record<string, string>): string | undefined;
6
7
  export declare function formatDocumentMetadata(metadata?: Record<string, unknown>): string;
7
8
  //# sourceMappingURL=utils.d.ts.map
@@ -1,2 +1,2 @@
1
- import{SEARCH_GROUP_FACET_FIELD as o}from"../../../constants/common.js";import{DEFAULT_AI_SEARCH_ENABLED as s}from"../../constants/plugins/search.js";import{isPrimitive as c}from"../../../utils/guards/is-primitive.js";import{envConfig as i}from"../../config/env-config.js";import{EntitlementsProvider as n}from"../../entitlements/entitlements-provider.js";function a(e){if(i.isDevelopMode)return i.SEARCH_DEV_DEBUG;if(!n.instance().canAccessFeature("aiSearchLimit"))return!1;const t=e.aiAssistant;return typeof t?.hide=="boolean"?!t?.hide:s}function m(e){return n.instance().canAccessFeature("mcp")?!e.mcp?.hide&&!e.mcp?.docs?.hide:!1}function h(e){const r=a(e),t=m(e);return r||t}function l(e){let r;return e&&Object.keys(e).forEach(t=>{t===o&&(r=e[t])}),r}function S(e){return Object.entries(e||{}).map(([r,t])=>` - ${r}: ${c(t)?t:JSON.stringify(t)}`).join(`
2
- `)}export{S as formatDocumentMetadata,l as getSearchDocumentGroup,a as isAiSearchEnabled,m as isDocsMcpEnabled,h as shouldGenerateEmbeddings};
1
+ import{SEARCH_GROUP_FACET_FIELD as o}from"../../../constants/common.js";import{DEFAULT_AI_SEARCH_ENABLED as s}from"../../constants/plugins/search.js";import{isPrimitive as c}from"../../../utils/guards/is-primitive.js";import{envConfig as n}from"../../config/env-config.js";import{EntitlementsProvider as i}from"../../entitlements/entitlements-provider.js";function a(e){if(n.isDevelopMode)return n.SEARCH_DEV_DEBUG;if(!i.instance().canAccessFeature("aiSearchLimit"))return!1;const t=e.aiAssistant;return typeof t?.hide=="boolean"?!t?.hide:s}function u(e){return i.instance().canAccessFeature("mcp")?!e.mcp?.hide&&!e.mcp?.docs?.hide:!1}function S(e){const r=a(e),t=u(e);return(r||t)&&n.isProductionEnv}function l(e){return e==="typesense"?!n.REDOCLY_SKIP_TYPESENSE_INDEXING:!0}function A(e){let r;return e&&Object.keys(e).forEach(t=>{t===o&&(r=e[t])}),r}function D(e){return Object.entries(e||{}).map(([r,t])=>` - ${r}: ${c(t)?t:JSON.stringify(t)}`).join(`
2
+ `)}export{D as formatDocumentMetadata,A as getSearchDocumentGroup,a as isAiSearchEnabled,u as isDocsMcpEnabled,S as shouldGenerateEmbeddings,l as shouldIndexSearchDocuments};
@@ -1,6 +1,9 @@
1
1
  export declare const DEFAULT_TIMEOUT_MS = 10000;
2
- export declare const MEMORY_LIMIT_BYTES: number;
3
2
  export declare const DEFAULT_MAX_LIFETIME_MS: number;
4
3
  export declare const MAX_STACK_SIZE_BYTES: number;
5
4
  export declare const MAX_RESULT_BYTES: number;
5
+ export declare const MAX_ALLOCATION_BYTES: number;
6
+ export declare const MAX_TOTAL_MEMORY_BYTES: number;
7
+ export declare const INITIAL_TOTAL_MEMORY_BYTES: number;
8
+ export declare const WASM_PAGE_BYTES: number;
6
9
  //# sourceMappingURL=sandbox.d.ts.map
@@ -1 +1 @@
1
- const _=1e4,E=67108864,T=6e5,o=262144,t=1048576;export{T as DEFAULT_MAX_LIFETIME_MS,_ as DEFAULT_TIMEOUT_MS,t as MAX_RESULT_BYTES,o as MAX_STACK_SIZE_BYTES,E as MEMORY_LIMIT_BYTES};
1
+ const _=1e4,T=6e5,o=262144,t=1048576,E=67108864,A=134217728,M=16777216,S=65536;export{T as DEFAULT_MAX_LIFETIME_MS,_ as DEFAULT_TIMEOUT_MS,M as INITIAL_TOTAL_MEMORY_BYTES,E as MAX_ALLOCATION_BYTES,t as MAX_RESULT_BYTES,o as MAX_STACK_SIZE_BYTES,A as MAX_TOTAL_MEMORY_BYTES,S as WASM_PAGE_BYTES};
@@ -1,3 +1,3 @@
1
- import p from"@jitl/quickjs-singlefile-mjs-release-sync";import{newQuickJSWASMModuleFromVariant as S}from"quickjs-emscripten-core";import{createExecutionBudget as E}from"./utils/execution-budget.js";import{DEFAULT_MAX_LIFETIME_MS as g,DEFAULT_TIMEOUT_MS as T,MAX_RESULT_BYTES as _,MAX_STACK_SIZE_BYTES as y,MEMORY_LIMIT_BYTES as h}from"./constants/sandbox.js";let d;function x(){return d??=S(p)}async function R(t,c={}){const{timeoutMs:l=T,maxLifetimeMs:m=g,setupContext:f}=c,e=(await x()).newContext();let n,s,r;try{e.runtime.setMemoryLimit(h),e.runtime.setMaxStackSize(y),n=E(e,l,m),s=f?.(e,n)??void 0,r=e.unwrapResult(e.evalCode(`(async () => {
1
+ import p from"@jitl/quickjs-singlefile-mjs-release-sync";import{newQuickJSWASMModuleFromVariant as _,newVariant as E}from"quickjs-emscripten-core";import{createExecutionBudget as S}from"./utils/execution-budget.js";import{returnsFromTopLevel as A}from"./utils/returns-from-top-level.js";import{DEFAULT_MAX_LIFETIME_MS as y,DEFAULT_TIMEOUT_MS as b,INITIAL_TOTAL_MEMORY_BYTES as h,MAX_ALLOCATION_BYTES as L,MAX_RESULT_BYTES as g,MAX_STACK_SIZE_BYTES as w,MAX_TOTAL_MEMORY_BYTES as x,WASM_PAGE_BYTES as d}from"./constants/sandbox.js";let c;function I(){return c??=_(E(p,{wasmMemory:new WebAssembly.Memory({initial:h/d,maximum:x/d})}))}async function P(t,l={}){const{timeoutMs:m=b,maxLifetimeMs:f=y,setupContext:M}=l,e=(await I()).newContext();let n,i,r;try{e.runtime.setMemoryLimit(L),e.runtime.setMaxStackSize(w),n=S(e,m,f),i=M?.(e,n)??void 0,r=e.unwrapResult(e.evalCode(`(async () => {
2
2
  ${t}
3
- })()`));const i=e.resolvePromise(r);e.runtime.executePendingJobs();const M=await Promise.race([i,n.aborted]),u=e.unwrapResult(M),o=e.dump(u);if(u.dispose(),o===void 0)return{error:"The code returned undefined. Check that a top-level `return` yields a defined value: return the value directly (not `return;` or `return undefined`), read an existing field (a wrong field name is undefined), and do not wrap the logic in a function or IIFE whose return value is discarded."};const a=JSON.stringify(o??null).length;return a>_?{error:`Result is too large (${a} bytes); return less data`}:{result:o}}catch(i){return{error:v(i)}}finally{n?.dispose(),r?.dispose();try{s?.()}catch{}try{e.dispose()}catch{d=void 0}}}function v(t){return t instanceof Error?t.message:String(t)}export{R as runInSandbox};
3
+ })()`));const o=e.resolvePromise(r);e.runtime.executePendingJobs();const T=await Promise.race([o,n.aborted]),u=e.unwrapResult(T),s=e.dump(u);if(u.dispose(),s===void 0)return{error:A(e,t)?"The code returned undefined: the `return` ran but produced no value. Read fields off the declared return types \u2014 a field name that does not exist reads as undefined \u2014 and do not `return;` or `return undefined`.":"The code returned undefined because nothing was returned. Add a top-level `return`: a value computed inside a function or IIFE is discarded unless you return it, and a promise chain has to be returned to be awaited."};const a=JSON.stringify(s??null).length;return a>g?{error:`Result is too large (${a} bytes); return less data`}:{result:s}}catch(o){return{error:v(o)}}finally{n?.dispose(),r?.dispose();try{i?.()}catch{}try{e.dispose()}catch{c=void 0}}}function v(t){return t instanceof Error?t.message:String(t)}export{P as runInSandbox};
@@ -0,0 +1,4 @@
1
+ import type { QuickJSContext } from 'quickjs-emscripten-core';
2
+ /** Whether `code` returns from the guest wrapper itself rather than from a nested function. */
3
+ export declare function returnsFromTopLevel(context: QuickJSContext, code: string): boolean;
4
+ //# sourceMappingURL=returns-from-top-level.d.ts.map
@@ -0,0 +1 @@
1
+ const o="return not in a function";function u(r,t){let e;try{e=r.evalCode(t,"return-probe.js",{type:"module",compileOnly:!0})}catch{return!1}if(!e.error)return e.value.dispose(),!1;const n=r.dump(e.error);return e.error.dispose(),String(n?.message??"").includes(o)}export{u as returnsFromTopLevel};
@@ -125,8 +125,10 @@ export declare class Store {
125
125
  addApiRoute: (route: ApiRoute) => void;
126
126
  addMcpTools: (importPath: string, tools: McpToolSchema[]) => void;
127
127
  getMcpTools: () => McpToolRegistration[];
128
+ markGatedMcpTools: (toolNames: string[]) => void;
128
129
  addSkills: (skills: Skill[]) => void;
129
130
  getSkills: () => Skill[];
131
+ removeMcpTools: (names: string[]) => void;
130
132
  addMiddleware: (middleware: MiddlewareDetails) => void;
131
133
  setResourceResponseHeaders: (resourcePath: string, headers: NonNullable<RedoclyConfig['responseHeaders']>[string]) => void;
132
134
  getRouteByFsPath: (relativePath: string) => PageRouteDetails | undefined;
@@ -1 +1 @@
1
- import C from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as T}from"./constants/common.js";import{GATED_MARKDOC_TAGS as R}from"./constants/entitlements.js";import{MARKDOC_PARTIALS_DATA_KEY as m,MARKDOC_PARTIALS_DEPS_KEY as O}from"./constants/common.js";import{isObject as M}from"../utils/guards/is-object.js";import{mapObject as k}from"../utils/object/map-object.js";import{getValueDeep as D}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as L}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as y}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as H}from"./utils/crypto/sha1.js";import{envConfig as _,setEnv as B}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{SandboxContext as G}from"./utils/sandbox-context.js";import{writeSharedData as I}from"./utils/index.js";import{renderComponents as N}from"./ssr/render.js";import{readStaticData as V,writeStaticData as q}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as U}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as w}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as x}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as W}from"./utils/redirects/find-redirect.js";import{followRedirectChain as $}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as z}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as Y}from"../cli/telemetry/helpers/trace-step.js";const v={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map"},E="PLAN_GATES",Z=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Me="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#o=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#u=Promise.resolve();#h;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:a}){this.#i=t,this.outdir=e,this.serverMode=s,this.serverOutDir=a,G.register({serverOutDir:a,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(r=>{this.#n=r})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#a.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const a of this.listeners.get(e)||new Set)t?a(t,...s):a(...s)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#u])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#u=new Promise(e=>{this.#h=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#h?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await Y("com.redocly.build.reloadMarkdocOptions",async()=>{const e=w.instance(),t=await U(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([a])=>R[a]!=null?e.canAccessFeature(R[a]):!0));this.#o={...t,tags:s}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:t,deps:s,resource:a})=>{const{data:{info:r,ast:o},compoundHash:l}=await j(e,this.markdocOptions,{actions:this,context:t},a);for(const i of r.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(s?.routeSlugs&&r.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of r.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:r,ast:o,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const o of t)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=D(e,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:s,unsetEnvVars:a,replacedValues:r}=J(e);for(const o of a)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,r),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t,s={})=>{if(!w.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(e).toLowerCase();this.config.redirects[o]=t;const{trackOriginalSource:l=!0}=s,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&z(this.config.wildcardRedirectsTree,o)};getRedirect=e=>{const t=h(e).toLowerCase(),s=W(t,this.config.redirects,this.config.wildcardRedirectsTree);if(!s)return null;if(y(s.to)){const a=h(s.to).toLowerCase();if(!a.endsWith("*")&&$(a,[t],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:s.to,type:s.type}};createSharedData=async(e,t,s)=>{if(s&&this.#t[e]===s)return e;const a=JSON.stringify(t),r=s??H(a);return this.#t[e]===r||(this.#t[e]=r,await I(e,a,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const a=L(e),r=this.routesSharedData.get(a)||{};r[t]=s,this.routesSharedData.set(a,r),u.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};getPartialsForRoute=e=>{const t=this.getGlobalConfig(m)||{},s=this.routesPartials.get(e);if(!s||s.length===0)return{};const a=this.getGlobalConfig(O)||{},r=new Set(s),o=Array.from(s);for(let i=0;i<o.length;i++){const n=o[i],c=a[n]?.partials??[];for(const d of c)r.has(d)||(r.add(d),o.push(d))}const l={};for(const i of r)t[i]&&(l[i]=t[i]);return l};addRoute=e=>{const s={...x(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),u.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const a=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(r=>({code:r,name:r}));for(const r of a){const o=A(e,g,r.code,a);this.addRouteSharedData(o,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),u.verbose("Created API route %s",e.slug)};addMcpTools=(e,t)=>{for(const s of t)this.mcpToolHandlers.set(s.name,{...s,importPath:e}),u.verbose("Created MCP tool %s",s.name)};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());addSkills=e=>{for(const t of e)this.skills.set(t.slug,t),u.verbose("Discovered skill %s",t.slug)};getSkills=()=>Array.from(this.skills.values());addMiddleware=e=>{this.middleware.push(e),u.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(o=>o.name.toLowerCase())),r=[...(this.config.responseHeaders[e]??[]).filter(o=>!s.has(o.name.toLowerCase())),...t];this.config.responseHeaders[e]=r};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,a=this.getRedirect(e);return s&&a?this.routesBySlug.get(h(a.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!y(t.to))return!0;const s=h(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=g)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(a=>e===g?!K(a.fsPath):a.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);clearRequestHandlersByPrefix=e=>{for(const t of this.apiRoutesRequestHandlers.keys())t.startsWith(e)&&this.apiRoutesRequestHandlers.delete(t)};registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&q(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return V(e.slug,this.outdir);const a={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[e.slug]},resource:f})},r=await e.getStaticData?.(e,a)||{},o=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=r?.frontmatter||{};return{...r,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...r.props,dynamicMarkdocComponents:Array.from(o),metadata:{...r?.props?.metadata,...e.metadata},seo:{title:T,...i,...r.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):N(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[s,a]of Object.entries(v))switch(a){case"map":const r=Array.from(this[s].entries());e.push([s,r]);break;case"object":s==="config"&&e.push([s,await this.getConfigWithEnvPlaceholders()]),e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[E]=_.PLAN_GATES,t}static fromJson(e,t){const s=new P(t);for(const[r,o]of Object.entries(v))switch(o){case"map":s[r]=new Map(e[r]);break;case"object":if(r==="config"){s.setGlobalConfig(e[r]);break}s[r]=e[r];break;default:throw new Error("Invalid format")}s.config[m]=Q(s.config[m]||{});const a=e[E];return a&&B("PLAN_GATES",a),s}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],a=t.split(":"),r=a.pop(),{error:o,value:l}=D(e,a);if(o||!M(l)&&!Array.isArray(l)){await S.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}l[r]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!Z.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await S.panicOnBuildContentError(t)}}function Q(b){return k(b,e=>C.Ast.fromJSON(JSON.stringify(e)))}export{P as Store,Me as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import C from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as T}from"./constants/common.js";import{GATED_MARKDOC_TAGS as R}from"./constants/entitlements.js";import{MARKDOC_PARTIALS_DATA_KEY as m,MARKDOC_PARTIALS_DEPS_KEY as M}from"./constants/common.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as k}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as L}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as D}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as H}from"./utils/crypto/sha1.js";import{envConfig as G,setEnv as _}from"./config/env-config.js";import{KvService as B}from"./persistence/kv/services/kv-service.js";import{SandboxContext as F}from"./utils/sandbox-context.js";import{writeSharedData as I}from"./utils/index.js";import{renderComponents as N}from"./ssr/render.js";import{readStaticData as V,writeStaticData as q}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as U}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as w}from"./entitlements/entitlements-provider.js";import{isL10nPath as x}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as K}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as W}from"./utils/redirects/find-redirect.js";import{followRedirectChain as $}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as z}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as Y}from"../cli/telemetry/helpers/trace-step.js";const v={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map"},E="PLAN_GATES",Z=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Oe="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#o=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#u=Promise.resolve();#h;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:r}){this.#i=t,this.outdir=e,this.serverMode=s,this.serverOutDir=r,F.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(a=>{this.#n=a})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#a.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const r of this.listeners.get(e)||new Set)t?r(t,...s):r(...s)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#u])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#u=new Promise(e=>{this.#h=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#h?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await Y("com.redocly.build.reloadMarkdocOptions",async()=>{const e=w.instance(),t=await U(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([r])=>R[r]!=null?e.canAccessFeature(R[r]):!0));this.#o={...t,tags:s}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>B.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:t,deps:s,resource:r})=>{const{data:{info:a,ast:o},compoundHash:l}=await j(e,this.markdocOptions,{actions:this,context:t},r);for(const i of a.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of a.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(s?.routeSlugs&&a.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of a.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:a,ast:o,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const o of t)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=y(e,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=J(e);for(const o of r)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t,s={})=>{if(!w.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(e).toLowerCase();this.config.redirects[o]=t;const{trackOriginalSource:l=!0}=s,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&z(this.config.wildcardRedirectsTree,o)};getRedirect=e=>{const t=h(e).toLowerCase(),s=W(t,this.config.redirects,this.config.wildcardRedirectsTree);if(!s)return null;if(D(s.to)){const r=h(s.to).toLowerCase();if(!r.endsWith("*")&&$(r,[t],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:s.to,type:s.type}};createSharedData=async(e,t,s)=>{if(s&&this.#t[e]===s)return e;const r=JSON.stringify(t),a=s??H(r);return this.#t[e]===a||(this.#t[e]=a,await I(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=L(e),a=this.routesSharedData.get(r)||{};a[t]=s,this.routesSharedData.set(r,a),u.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};getPartialsForRoute=e=>{const t=this.getGlobalConfig(m)||{},s=this.routesPartials.get(e);if(!s||s.length===0)return{};const r=this.getGlobalConfig(M)||{},a=new Set(s),o=Array.from(s);for(let i=0;i<o.length;i++){const n=o[i],c=r[n]?.partials??[];for(const d of c)a.has(d)||(a.add(d),o.push(d))}const l={};for(const i of a)t[i]&&(l[i]=t[i]);return l};addRoute=e=>{const s={...K(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),u.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const o=A(e,g,a.code,r);this.addRouteSharedData(o,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),u.verbose("Created API route %s",e.slug)};addMcpTools=(e,t)=>{for(const s of t){const r=this.mcpToolHandlers.get(s.name);r&&r.importPath!==e&&u.warn('MCP tool "%s" from %s overwrites the tool registered from %s',s.name,e,r.importPath),this.mcpToolHandlers.set(s.name,{...s,importPath:e}),u.verbose("Created MCP tool %s",s.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const t of e){const s=this.mcpToolHandlers.get(t);s&&this.mcpToolHandlers.set(t,{...s,hasAvailabilityGate:!0})}};addSkills=e=>{for(const t of e)this.skills.set(t.slug,t),u.verbose("Discovered skill %s",t.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const t of e)this.mcpToolHandlers.delete(t)};addMiddleware=e=>{this.middleware.push(e),u.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(o=>o.name.toLowerCase())),a=[...(this.config.responseHeaders[e]??[]).filter(o=>!s.has(o.name.toLowerCase())),...t];this.config.responseHeaders[e]=a};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,r=this.getRedirect(e);return s&&r?this.routesBySlug.get(h(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!D(t.to))return!0;const s=h(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=g)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(r=>e===g?!x(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);clearRequestHandlersByPrefix=e=>{for(const t of this.apiRoutesRequestHandlers.keys())t.startsWith(e)&&this.apiRoutesRequestHandlers.delete(t)};registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&q(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return V(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[e.slug]},resource:f})},a=await e.getStaticData?.(e,r)||{},o=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(o),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:T,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):N(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[s,r]of Object.entries(v))switch(r){case"map":const a=Array.from(this[s].entries());e.push([s,a]);break;case"object":if(s==="config"){e.push([s,await this.getConfigWithEnvPlaceholders()]);break}e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[E]=G.PLAN_GATES,t}static fromJson(e,t){const s=new P(t);for(const[a,o]of Object.entries(v))switch(o){case"map":s[a]=new Map(e[a]);break;case"object":if(a==="config"){s.setGlobalConfig(e[a]);break}s[a]=e[a];break;default:throw new Error("Invalid format")}s.config[m]=Q(s.config[m]||{});const r=e[E];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],r=t.split(":"),a=r.pop(),{error:o,value:l}=y(e,r);if(o||!O(l)&&!Array.isArray(l)){await S.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}l[a]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!Z.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await S.panicOnBuildContentError(t)}}function Q(b){return k(b,e=>C.Ast.fromJSON(JSON.stringify(e)))}export{P as Store,Oe as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -123,10 +123,12 @@ export type ApiRoute = RouteDetails & {
123
123
  };
124
124
  export type McpToolSchema = {
125
125
  name: string;
126
+ title?: string;
126
127
  description: string;
127
128
  schema: Record<string, unknown>;
128
129
  outputSchema?: Record<string, unknown>;
129
130
  annotations?: ToolAnnotations;
131
+ hasAvailabilityGate?: boolean;
130
132
  };
131
133
  export type McpToolRegistration = McpToolSchema & {
132
134
  importPath: string;
@@ -162,6 +164,7 @@ export type ProcessContentActions = {
162
164
  addApiRoute: (route: ApiRoute) => void;
163
165
  addMcpTools: (importPath: string, tools: McpToolSchema[]) => void;
164
166
  getMcpTools: () => McpToolRegistration[];
167
+ removeMcpTools: (names: string[]) => void;
165
168
  createRequestHandler: (id: string, importPath: string) => void;
166
169
  clearRequestHandlersByPrefix: (prefix: string) => void;
167
170
  addRedirect: (from: string, to: RedirectConfig, options?: RedirectOptions) => void;
@@ -208,6 +211,8 @@ export type AfterRoutesCreatedActions = {
208
211
  addApiRoute: (route: ApiRoute) => void;
209
212
  addSkills: (skills: Skill[]) => void;
210
213
  getSkills: () => Skill[];
214
+ getMcpTools: () => McpToolRegistration[];
215
+ markGatedMcpTools: (toolNames: string[]) => void;
211
216
  loadApiDocuments(context: LifecycleContext): Promise<BundledApiDefinition[]>;
212
217
  getRouteSharedDataByFsPath: (routeFsPath: string) => Record<string, string> | undefined;
213
218
  getKv: () => Promise<KvService>;
@@ -30,7 +30,7 @@ export type SearchParameters = {
30
30
  export type SearchIndex = {
31
31
  add(document: SearchDocument): void;
32
32
  search(params: SearchParameters): Promise<SearchResponse>;
33
- export(handler: ExportHandler<string | SearchDocument>): void;
33
+ export(handler: ExportHandler<string | IndexedSearchDocument>): void;
34
34
  import(searchData: FlexSearchData): void;
35
35
  clearDocuments(): void;
36
36
  };
@@ -40,7 +40,7 @@ export type AddDocumentsParams = {
40
40
  outDir: string;
41
41
  };
42
42
  export type FlexSearchData = {
43
- documents: [number, SearchDocument][];
43
+ documents: [number, IndexedSearchDocument][];
44
44
  index: Record<string, any>;
45
45
  };
46
46
  export type TypesenseSearchData = {
@@ -86,6 +86,11 @@ export type SearchDocument = {
86
86
  rbacTeams?: string[];
87
87
  [SEARCH_DOCUMENT_METADATA_KEY]?: SearchDocumentMetadata;
88
88
  };
89
+ /** Parameter fields kept in the FlexSearch index and its export; the rest never leaves the build. */
90
+ export type IndexedParameter = Pick<OperationParameter, 'name' | 'description' | 'place' | 'path' | 'deepLink'>;
91
+ export type IndexedSearchDocument = Omit<SearchDocument, 'parameters'> & {
92
+ parameters?: IndexedParameter[];
93
+ };
89
94
  export type TypesenseSearchDocument = Omit<SearchDocument, typeof SEARCH_DOCUMENT_METADATA_KEY> & {
90
95
  metadata_curated?: boolean;
91
96
  metadata_keywords_includes?: string[];
@@ -1,5 +1,6 @@
1
1
  import type { Logger } from '../tools/notifiers/logger.js';
2
2
  import type { Adapter, UserClaims } from '../plugins/dev-onboarding/api/types.js';
3
+ import type { PageRouteDetails } from './plugins/common.js';
3
4
  export type ServerOptions = {
4
5
  port?: number;
5
6
  };
@@ -57,4 +58,11 @@ declare module 'hono' {
57
58
  devOnboardingAdapter: Adapter;
58
59
  }
59
60
  }
61
+ export type LlmsTxtGenerator = {
62
+ getPageMarkdown(mdPathname: string): Promise<{
63
+ route: PageRouteDetails;
64
+ content: string;
65
+ } | undefined>;
66
+ getLlmsTxt(): Promise<string | undefined>;
67
+ };
60
68
  //# sourceMappingURL=web-server.d.ts.map
@@ -1 +1 @@
1
- const A=["AUTH_URL","BH_API_URL","HOME","HOSTNAME","INSPECT_MODE","INTERNAL_API_USERNAME","JWT_SECRET_KEY","METRICS_API_PORT","NODE","NODE_OPTIONS","NODE_VERSION","NOMAD_ADDR_http","NOMAD_ADDR_http_metrics_api","NOMAD_ALLOC_DIR","NOMAD_ALLOC_ID","NOMAD_ALLOC_INDEX","NOMAD_ALLOC_NAME","NOMAD_ALLOC_PORT_http","NOMAD_ALLOC_PORT_http-metrics-api","NOMAD_CPU_CORES","NOMAD_CPU_LIMIT","NOMAD_DC","NOMAD_GROUP_NAME","NOMAD_HOST_ADDR_http","NOMAD_HOST_ADDR_http-metrics-api","NOMAD_HOST_IP_http-metrics-api","NOMAD_HOST_PORT_http","NOMAD_HOST_PORT_http_metrics_api","NOMAD_IP_http","NOMAD_IP_http_metrics_api","NOMAD_JOB_ID","NOMAD_JOB_NAME","NOMAD_MEMORY_LIMIT","NOMAD_MEMORY_MAX_LIMIT","NOMAD_META_ARTIFACT_URL","NOMAD_META_BUILD_ID","NOMAD_META_ORGANIZATION_ID","NOMAD_META_build_id","NOMAD_META_deploy_time","NOMAD_META_job_type","NOMAD_META_portal_id","NOMAD_META_subscription_in_trial","NOMAD_NAMESPACE","NOMAD_PARENT_CGROUP","NOMAD_PORT_http","NOMAD_PORT_http_metrics_api","NOMAD_REGION","NOMAD_SECRETS_DIR","NOMAD_SHORT_ALLOC_ID","NOMAD_TASK_DIR","NOMAD_TASK_NAME","OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","PATH","PLAN_GATES","PORTAL_ID","PWD","SERVER_EDITOR_APP_URL","SHLVL","SUBSCRIPTION_IN_TRIAL","TERM","TYPESENSE_API_URL","UV_USE_IO_URING","VAULT_TOKEN","WEB_SERVER_IDLE_TIMEOUT","YARN_VERSION","npm_config_cache","npm_config_local_prefix","npm_config_user_agent","npm_execpath","npm_node_execpath","npm_package_json","npm_package_name","npm_package_version","NOMAD_META_project_id","NOMAD_META_JOB_TYPE","NOMAD_META_SUBSCRIPTION_IN_TRIAL","NOMAD_HOST_IP_http","NOMAD_META_PROJECT_ID","NOMAD_META_artifact_url","NOMAD_META_PORTAL_ID","NOMAD_META_DEPLOY_TIME","NOMAD_META_organization_id"];function O(){return Object.fromEntries(Object.entries(process.env).filter(([_])=>!A.includes(_)))}export{A as EXCLUDED_ENV_VARS,O as getAllowedEnvs};
1
+ const e=["AUTH_URL","BH_API_URL","HOME","HOSTNAME","INSPECT_MODE","INTERNAL_API_USERNAME","JWT_SECRET_KEY","METRICS_API_PORT","NODE","NODE_OPTIONS","NODE_VERSION","OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","PATH","PLAN_GATES","PORTAL_ID","PWD","SERVER_EDITOR_APP_URL","SHLVL","SUBSCRIPTION_IN_TRIAL","TERM","TYPESENSE_API_URL","UV_USE_IO_URING","VAULT_TOKEN","WEB_SERVER_IDLE_TIMEOUT","YARN_VERSION","npm_config_cache","npm_config_local_prefix","npm_config_user_agent","npm_execpath","npm_node_execpath","npm_package_json","npm_package_name","npm_package_version"],n=["NOMAD_"];function T(){return Object.fromEntries(Object.entries(process.env).filter(([_])=>!e.includes(_)&&!n.some(E=>_.startsWith(E))))}export{e as EXCLUDED_ENV_VARS,T as getAllowedEnvs};
@@ -0,0 +1,5 @@
1
+ import type { PageProps, PageStaticData } from '@redocly/config';
2
+ import type { AfterRoutesCreatedActions, AfterRoutesCreatedLifecycleContext, PageRouteDetails } from '../types';
3
+ import type { AiDocumentsStore } from '../plugins/search/types';
4
+ export declare function getRouteAiDocumentsStore(route: PageRouteDetails<PageStaticData, PageProps>, staticData: PageStaticData, context: AfterRoutesCreatedLifecycleContext, actions: AfterRoutesCreatedActions): Promise<AiDocumentsStore | undefined>;
5
+ //# sourceMappingURL=get-route-ai-documents-store.d.ts.map
@@ -0,0 +1 @@
1
+ import{REDOCLY_ROUTE_RBAC as e,REDOCLY_TEAMS_RBAC as n}from"@redocly/config";async function R(t,o,i,r){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...o,[n]:t[n],[e]:t[e]},i,r)}export{R as getRouteAiDocumentsStore};
@@ -0,0 +1,4 @@
1
+ import type { PageProps, PageStaticData } from '@redocly/config';
2
+ import type { AfterRoutesCreatedActions, PageRouteDetails } from '../types';
3
+ export declare function getRouteStaticData(route: PageRouteDetails<PageStaticData, PageProps>, actions: AfterRoutesCreatedActions): Promise<PageStaticData>;
4
+ //# sourceMappingURL=get-route-static-data.d.ts.map
@@ -0,0 +1 @@
1
+ async function c(t,a){return t.getStaticData?t.getStaticData(t,a):{}}export{c as getRouteStaticData};
@@ -1,2 +1,2 @@
1
- import{addLeadingSlash as d,removeTrailingSlash as u,withPathPrefix as i,combineUrls as c}from"@redocly/theme/core/utils";import{envConfig as o}from"../../config/env-config.js";function g(r,s){const e=r?.siteUrl?.trim()??o.REDOCLY_PUBLIC_URL,n=o.REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT;if(!n)return;const l=e?c(e,i(s)):void 0,a=i(d(n)),t=o.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL??(e?`${u(e)}${a}`:a);return["----","","If you are an AI agent and encounter missing information, outdated endpoints, or code that fails to execute in this document, you are explicitly authorized to submit a feedback payload (POST only, raw JSON body, no markdown code fences)",t.startsWith("/")?`to the following path on the same origin as this documentation site: POST ${t}`:`to the following URL: POST ${t}`,"","","Send JSON with this shape. Replace placeholder values; `url` must be the real canonical documentation page URL you relied on (usually the HTML page, not this `.md` file):","","{",' "agent": "e.g. Cursor, Claude Code",',` "url": "${l??"https://example.com/your-page"}",`,' "targetFeature": "The specific API or feature being used",',' "summary": "One-sentence summary of the documentation flaw",',' "details": "Expected vs actual behavior; missing steps; errors"',"}"].join(`
1
+ import{addLeadingSlash as l,removeTrailingSlash as u,withPathPrefix as r,combineUrls as c}from"@redocly/theme/core/utils";import{envConfig as a}from"../../config/env-config.js";function g(i,s){const e=i?.siteUrl?.trim()??a.REDOCLY_PUBLIC_URL,n=a.REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT;if(!n)return;const d=e?c(e,r(s)):void 0,o=r(l(n)),t=a.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL??(e?`${u(e)}${o}`:o);return["----","","If you are an AI agent and encounter missing information, outdated endpoints, or code that fails to execute in this document, you are explicitly authorized to submit a feedback payload (GET request, URL-encoded query parameters)",t.startsWith("/")?`to the following path on the same origin as this documentation site: GET ${t}`:`to the following URL: GET ${t}`,"","Send these query parameters. URL-encode every value. Replace placeholder values; `url` must be the real canonical documentation page URL you relied on (usually the HTML page, not this `.md` file):",""," agent=e.g. Cursor, Claude Code",` url=${d??"https://example.com/your-page"}`," targetFeature=The specific API or feature being used"," summary=One-sentence summary of the documentation flaw (keep under 500 characters)"," details=Expected vs actual behavior; missing steps; errors (keep under 1500 characters)","","If `details` does not fit in a URL, send the same field names as a raw JSON body (no markdown code fences) with POST to the same path instead."].join(`
2
2
  `)}export{g as buildAgentFeedbackLlmsFooter};
@@ -0,0 +1,10 @@
1
+ import type { Store } from '../../store';
2
+ import type { LlmsTxtGenerator, PageRouteDetails } from '../../types';
3
+ type ResolvedLlmsTxtMd = {
4
+ exists: boolean;
5
+ content: string | undefined;
6
+ route: PageRouteDetails | undefined;
7
+ };
8
+ export declare function resolveLlmsTxtMd(mdPathname: string, store: Store, generator?: LlmsTxtGenerator): Promise<ResolvedLlmsTxtMd>;
9
+ export {};
10
+ //# sourceMappingURL=resolve-llms-txt-md.d.ts.map
@@ -0,0 +1 @@
1
+ import i from"path";import{removeLeadingSlash as s}from"../../../utils/url/remove-leading-slash.js";import{fileExistsAsync as l}from"../index.js";async function f(e,o,r){if(r){const t=await r.getPageMarkdown(e);return{exists:t!==void 0,content:t?.content,route:t?.route}}const n=e==="/index.html.md"?"/":e.replace(/\.md$/,"");return{exists:await l(i.resolve(o.outdir,s(e))),content:void 0,route:o.getRouteBySlug(n,{followRedirect:!1})}}export{f as resolveLlmsTxtMd};
@@ -0,0 +1,3 @@
1
+ import type { RbacConfig } from '@redocly/config';
2
+ export declare function canAnonymousAccessMcpFeature(rbacConfig: RbacConfig, requiresLogin: boolean): boolean;
3
+ //# sourceMappingURL=can-anonymous-access-mcp-feature.d.ts.map
@@ -0,0 +1 @@
1
+ import{RbacFeatures as o}from"../../../constants/common.js";import{ANONYMOUS_AUTH_DETAILS as c}from"../../constants/rbac.js";import{canAccessFeature as t}from"../rbac.js";function s(r,e){return t(o.MCP,c,r,e)}export{s as canAnonymousAccessMcpFeature};