@redocly/redoc 0.137.0-next.6 → 0.137.0-next.7

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 (211) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  3. package/dist/client/templates/api-docs/helpers.d.ts +4 -1
  4. package/dist/client/templates/api-docs/helpers.js +5 -1
  5. package/dist/client/templates/api-docs/template.js +1 -1
  6. package/dist/constants/l10n/langs/ar.js +1 -1
  7. package/dist/constants/l10n/langs/de.js +1 -1
  8. package/dist/constants/l10n/langs/en.js +1 -1
  9. package/dist/constants/l10n/langs/es.js +1 -1
  10. package/dist/constants/l10n/langs/fr.js +1 -1
  11. package/dist/constants/l10n/langs/hi.js +1 -1
  12. package/dist/constants/l10n/langs/it.js +1 -1
  13. package/dist/constants/l10n/langs/ja.js +1 -1
  14. package/dist/constants/l10n/langs/ko.js +1 -1
  15. package/dist/constants/l10n/langs/pl.js +1 -1
  16. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  17. package/dist/constants/l10n/langs/pt.js +1 -1
  18. package/dist/constants/l10n/langs/ru.js +1 -1
  19. package/dist/constants/l10n/langs/uk.js +1 -1
  20. package/dist/constants/l10n/langs/zh.js +1 -1
  21. package/dist/server/config/env-config.d.ts +2 -0
  22. package/dist/server/config/env-schema.d.ts +5 -0
  23. package/dist/server/config/env-schemas/feature-flags.d.ts +4 -0
  24. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  25. package/dist/server/esbuild/esbuild.js +3 -3
  26. package/dist/server/esbuild/plugins/mcp-tool-handlers-resolver.js +1 -1
  27. package/dist/server/plugins/api-docs/options.js +1 -1
  28. package/dist/server/plugins/{openapi-docs/is-openapi-doc.d.ts → api-docs/utils/is-api-doc.d.ts} +4 -2
  29. package/dist/server/plugins/api-docs/utils/is-api-doc.js +1 -0
  30. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.d.ts +1 -1
  31. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.js +1 -1
  32. package/dist/server/plugins/entitlements/index.js +1 -1
  33. package/dist/server/plugins/l10n/index.js +1 -1
  34. package/dist/server/plugins/lifecycle.js +2 -2
  35. package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
  36. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  37. package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +4 -4
  38. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +3 -1
  39. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -1
  40. package/dist/server/plugins/mcp/codemode/invoke-tool.js +1 -1
  41. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  42. package/dist/server/plugins/mcp/codemode/sandbox/polyfills/fetch-shim.d.ts +1 -1
  43. package/dist/server/plugins/mcp/codemode/sandbox/polyfills/fetch-shim.js +9 -3
  44. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  45. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +1 -1
  46. package/dist/server/plugins/mcp/codemode/types.d.ts +1 -0
  47. package/dist/server/plugins/mcp/constants.d.ts +1 -0
  48. package/dist/server/plugins/mcp/constants.js +1 -1
  49. package/dist/server/plugins/mcp/custom-tools/extract-tool-definition.d.ts +13 -0
  50. package/dist/server/plugins/mcp/custom-tools/extract-tool-definition.js +1 -0
  51. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.d.ts +6 -0
  52. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -0
  53. package/dist/server/plugins/mcp/custom-tools/validate-tool-definition.d.ts +3 -0
  54. package/dist/server/plugins/mcp/custom-tools/validate-tool-definition.js +1 -0
  55. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +2 -0
  56. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  57. package/dist/server/plugins/mcp/docs-mcp/tools/core/search.js +2 -2
  58. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoints.js +1 -1
  59. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
  60. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  61. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.d.ts +10 -0
  62. package/dist/server/plugins/mcp/gateway-mcp/callable-apis.js +1 -0
  63. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  64. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +1 -9
  65. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  66. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  67. package/dist/server/plugins/mcp/handlers/errors.d.ts +6 -1
  68. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  69. package/dist/server/plugins/mcp/index.js +1 -1
  70. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  71. package/dist/server/plugins/mcp/servers/mcp-server.js +3 -3
  72. package/dist/server/plugins/mcp/types.d.ts +29 -3
  73. package/dist/server/plugins/mcp/utils/available-sandbox-tools.d.ts +4 -0
  74. package/dist/server/plugins/mcp/utils/available-sandbox-tools.js +1 -0
  75. package/dist/server/plugins/mcp/utils/find-gated-tool-names.d.ts +2 -3
  76. package/dist/server/plugins/mcp/utils/find-gated-tool-names.js +1 -1
  77. package/dist/server/plugins/mcp/utils/mcp-client.d.ts +13 -0
  78. package/dist/server/plugins/mcp/utils/mcp-client.js +1 -0
  79. package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +6 -1
  80. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  81. package/dist/server/plugins/mcp/workers/import-mcp-tool-handlers.d.ts +5 -0
  82. package/dist/server/plugins/mcp/workers/import-mcp-tool-handlers.js +1 -0
  83. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +6 -11
  84. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  85. package/dist/server/plugins/mcp/workers/tool-file-system.d.ts +6 -0
  86. package/dist/server/plugins/mcp/workers/tool-file-system.js +1 -0
  87. package/dist/server/sandbox/sandbox.js +2 -2
  88. package/dist/server/sandbox/utils/returns-from-top-level.d.ts +4 -0
  89. package/dist/server/sandbox/utils/returns-from-top-level.js +1 -0
  90. package/dist/server/store.d.ts +1 -0
  91. package/dist/server/store.js +1 -1
  92. package/dist/server/types/plugins/common.d.ts +2 -1
  93. package/dist/server/web-server/routes/resolve-route.js +1 -1
  94. package/dist/server/web-server/utils/get-request-origin.d.ts +2 -0
  95. package/dist/server/web-server/utils/get-request-origin.js +1 -1
  96. package/dist/server/workers/mcp-tool-worker-pool.d.ts +1 -0
  97. package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
  98. package/dist/server/workers/mcp-tool-worker.js +1 -1
  99. package/dist/server/workers/types.d.ts +9 -2
  100. package/dist/server/workers/worker-pool.d.ts +1 -0
  101. package/dist/server/workers/worker-pool.js +1 -1
  102. package/dist/utils/guards/is-plain-object.d.ts +19 -0
  103. package/dist/utils/guards/is-plain-object.js +1 -0
  104. package/package.json +3 -6
  105. package/dist/client/templates/asyncapi-docs/helpers.d.ts +0 -12
  106. package/dist/client/templates/asyncapi-docs/helpers.js +0 -1
  107. package/dist/client/templates/asyncapi-docs/template.d.ts +0 -15
  108. package/dist/client/templates/asyncapi-docs/template.js +0 -9
  109. package/dist/client/templates/openapi-docs/helpers.d.ts +0 -18
  110. package/dist/client/templates/openapi-docs/helpers.js +0 -5
  111. package/dist/client/templates/openapi-docs/template.d.ts +0 -6
  112. package/dist/client/templates/openapi-docs/template.js +0 -14
  113. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +0 -9
  114. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +0 -1
  115. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +0 -2
  116. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +0 -1
  117. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +0 -6
  118. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +0 -1
  119. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-check.d.ts +0 -8
  120. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-check.js +0 -1
  121. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-overlay.d.ts +0 -2
  122. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-overlay.js +0 -1
  123. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-use-license-key.d.ts +0 -5
  124. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/empty-use-license-key.js +0 -1
  125. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/index.d.ts +0 -6
  126. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/index.js +0 -1
  127. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/loadAndBundleSpec.mock.d.ts +0 -3
  128. package/dist/server/esbuild/plugins/openapi-docs-module-replacer/loadAndBundleSpec.mock.js +0 -1
  129. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.d.ts +0 -18
  130. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.js +0 -5
  131. package/dist/server/plugins/asyncapi-docs/get-server-props.d.ts +0 -4
  132. package/dist/server/plugins/asyncapi-docs/get-server-props.js +0 -1
  133. package/dist/server/plugins/asyncapi-docs/get-template-path.d.ts +0 -2
  134. package/dist/server/plugins/asyncapi-docs/get-template-path.js +0 -1
  135. package/dist/server/plugins/asyncapi-docs/index.d.ts +0 -3
  136. package/dist/server/plugins/asyncapi-docs/index.js +0 -1
  137. package/dist/server/plugins/asyncapi-docs/is-asyncapi-doc.d.ts +0 -3
  138. package/dist/server/plugins/asyncapi-docs/is-asyncapi-doc.js +0 -1
  139. package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.d.ts +0 -9
  140. package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.js +0 -56
  141. package/dist/server/plugins/asyncapi-docs/search/schema-processor.d.ts +0 -8
  142. package/dist/server/plugins/asyncapi-docs/search/schema-processor.js +0 -1
  143. package/dist/server/plugins/asyncapi-docs/search/search-facets.d.ts +0 -8
  144. package/dist/server/plugins/asyncapi-docs/search/search-facets.js +0 -1
  145. package/dist/server/plugins/asyncapi-docs/search/search-resolver.d.ts +0 -5
  146. package/dist/server/plugins/asyncapi-docs/search/search-resolver.js +0 -1
  147. package/dist/server/plugins/asyncapi-docs/store-definition-bundles.d.ts +0 -4
  148. package/dist/server/plugins/asyncapi-docs/store-definition-bundles.js +0 -1
  149. package/dist/server/plugins/graphql-docs/constants.d.ts +0 -2
  150. package/dist/server/plugins/graphql-docs/constants.js +0 -1
  151. package/dist/server/plugins/graphql-docs/get-template-path.d.ts +0 -2
  152. package/dist/server/plugins/graphql-docs/get-template-path.js +0 -1
  153. package/dist/server/plugins/graphql-docs/graphql-doc-loader.d.ts +0 -17
  154. package/dist/server/plugins/graphql-docs/graphql-doc-loader.js +0 -1
  155. package/dist/server/plugins/graphql-docs/index.d.ts +0 -4
  156. package/dist/server/plugins/graphql-docs/index.js +0 -1
  157. package/dist/server/plugins/graphql-docs/is-graphql-doc.d.ts +0 -2
  158. package/dist/server/plugins/graphql-docs/is-graphql-doc.js +0 -1
  159. package/dist/server/plugins/graphql-docs/search/ai/get-ai-search-document.d.ts +0 -17
  160. package/dist/server/plugins/graphql-docs/search/ai/get-ai-search-document.js +0 -4
  161. package/dist/server/plugins/graphql-docs/search/ai/utils.d.ts +0 -14
  162. package/dist/server/plugins/graphql-docs/search/ai/utils.js +0 -36
  163. package/dist/server/plugins/graphql-docs/search/search-facets.d.ts +0 -8
  164. package/dist/server/plugins/graphql-docs/search/search-facets.js +0 -1
  165. package/dist/server/plugins/graphql-docs/search/search-resolver.d.ts +0 -5
  166. package/dist/server/plugins/graphql-docs/search/search-resolver.js +0 -1
  167. package/dist/server/plugins/graphql-docs/spec-download.api.d.ts +0 -3
  168. package/dist/server/plugins/graphql-docs/spec-download.api.js +0 -1
  169. package/dist/server/plugins/graphql-docs/template/GraphQLDocs.d.ts +0 -5
  170. package/dist/server/plugins/graphql-docs/template/GraphQLDocs.js +0 -4
  171. package/dist/server/plugins/graphql-docs/types.d.ts +0 -40
  172. package/dist/server/plugins/graphql-docs/types.js +0 -0
  173. package/dist/server/plugins/openapi-docs/ai-search-indexer.d.ts +0 -14
  174. package/dist/server/plugins/openapi-docs/ai-search-indexer.js +0 -1
  175. package/dist/server/plugins/openapi-docs/decorators.d.ts +0 -25
  176. package/dist/server/plugins/openapi-docs/decorators.js +0 -1
  177. package/dist/server/plugins/openapi-docs/format-bundle-error.d.ts +0 -6
  178. package/dist/server/plugins/openapi-docs/format-bundle-error.js +0 -5
  179. package/dist/server/plugins/openapi-docs/get-server-props.d.ts +0 -4
  180. package/dist/server/plugins/openapi-docs/get-server-props.js +0 -1
  181. package/dist/server/plugins/openapi-docs/get-template-path.d.ts +0 -2
  182. package/dist/server/plugins/openapi-docs/get-template-path.js +0 -1
  183. package/dist/server/plugins/openapi-docs/index.d.ts +0 -3
  184. package/dist/server/plugins/openapi-docs/index.js +0 -1
  185. package/dist/server/plugins/openapi-docs/is-openapi-doc.js +0 -1
  186. package/dist/server/plugins/openapi-docs/load-definition.d.ts +0 -31
  187. package/dist/server/plugins/openapi-docs/load-definition.js +0 -3
  188. package/dist/server/plugins/openapi-docs/openapi-search-builder.d.ts +0 -24
  189. package/dist/server/plugins/openapi-docs/openapi-search-builder.js +0 -1
  190. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.d.ts +0 -18
  191. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +0 -94
  192. package/dist/server/plugins/openapi-docs/search/search-facets.d.ts +0 -11
  193. package/dist/server/plugins/openapi-docs/search/search-facets.js +0 -1
  194. package/dist/server/plugins/openapi-docs/search/search-resolver.d.ts +0 -5
  195. package/dist/server/plugins/openapi-docs/search/search-resolver.js +0 -1
  196. package/dist/server/plugins/openapi-docs/search-indexer.d.ts +0 -17
  197. package/dist/server/plugins/openapi-docs/search-indexer.js +0 -1
  198. package/dist/server/plugins/openapi-docs/spec-download.api.d.ts +0 -4
  199. package/dist/server/plugins/openapi-docs/spec-download.api.js +0 -1
  200. package/dist/server/plugins/openapi-docs/store-definition-bundles.d.ts +0 -4
  201. package/dist/server/plugins/openapi-docs/store-definition-bundles.js +0 -1
  202. package/dist/server/plugins/openapi-docs/types.d.ts +0 -17
  203. package/dist/server/plugins/openapi-docs/types.js +0 -0
  204. package/dist/server/plugins/openapi-docs/utils.d.ts +0 -25
  205. package/dist/server/plugins/openapi-docs/utils.js +0 -1
  206. /package/dist/client/templates/{openapi-docs → api-docs}/mock-server-config.d.ts +0 -0
  207. /package/dist/client/templates/{openapi-docs → api-docs}/mock-server-config.js +0 -0
  208. /package/dist/{server/plugins → markdoc}/helpers/parse-partials.d.ts +0 -0
  209. /package/dist/{server/plugins → markdoc}/helpers/parse-partials.js +0 -0
  210. /package/dist/server/plugins/{openapi-docs → api-docs/utils}/ast-utils.d.ts +0 -0
  211. /package/dist/server/plugins/{openapi-docs → api-docs/utils}/ast-utils.js +0 -0
@@ -1,3 +1,3 @@
1
- import{context as m}from"esbuild";import{mkdirSync as M,writeFileSync as Y,existsSync as k}from"node:fs";import*as a from"node:path";import{RUNTIME_RESOURCES_DIR as V,TELEMETRY_ENABLED as $}from"../constants/common.js";import{fromCurrentDir as r}from"../utils/paths.js";import{NodeBrowserPlugin as P}from"./plugins/node-browser.js";import{PortalImport as l}from"./plugins/portal-import.js";import{ThemesResolver as u}from"./plugins/themes-resolver.js";import{AssetsResolver as E}from"./plugins/assets-resolver.js";import{EsbuildErrorCollector as d}from"./plugins/esbuild-compile-resolver.js";import{OpenapiDocsModuleReplacer as R}from"./plugins/openapi-docs-module-replacer/index.js";import{ApiDocsModuleReplacer as _}from"./plugins/api-docs-module-replacer/index.js";import{ServerPropsResolver as f}from"./plugins/server-props-resolver.js";import{StyledComponentsSSR as v}from"./plugins/styled-components-ssr.js";import{DependencyResolver as D}from"./plugins/dependency-resolver.js";import{YamlLoader as N}from"./plugins/yaml-loader.js";import{ApiRequestHandlersResolver as S}from"./plugins/api-request-handlers-resolver.js";import{McpToolHandlersResolver as T}from"./plugins/mcp-tool-handlers-resolver.js";import{MiddlewareResolver as I}from"./plugins/middleware-resolver.js";import{OnRebuild as L}from"./plugins/on-rebuild.js";import{getPublicEnvVariables as q}from"../utils/envs/get-public-env-variables.js";import{PORTAL_VERSION as w}from"../version.js";import{AsyncApiPatch as y}from"./plugins/async-api-patch.js";import{telemetryTraceStep as g}from"../../cli/telemetry/helpers/trace-step.js";import{initServerRebuildTrigger as x}from"./generate.js";const O={bundle:!0,format:"esm",chunkNames:"chunks/[name]-[hash]"};function C(e){const o=a.join(e,"tsconfig.json");return k(o)?o:void 0}const c=new Set;async function ue(){await Promise.all([...c].map(e=>e.dispose())),c.clear()}async function Ee(e,o,t="production",n){return await g("com.redocly.build.createClientCompiler",async()=>{const p=q(),i={};Object.entries(p).map(([j,b])=>i[`process.env.${j}`]=JSON.stringify(b));const s=[...n?[L(n)]:[],P({path:"path-browserify",fs:"{}",tty:"tty-browserify",os:"os-browserify",http:"stream-http",https:"stream-http",readline:"{}",crypto:"{}",stream:"{}",zlib:"{}","https-proxy-agent":"{}"}),u(e,e.contentDir),E(e,e.contentDir),d(e,e.contentDir),f(e),D(),l(),N(),y(),v(),R(),_()],h=[r(import.meta.url,"../../client/browser-entry.js"),r(import.meta.url,"../../client/user-tags-entry.js")],A=await m({...O,entryPoints:h,outdir:a.join(o,V),sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",plugins:s,tsconfig:C(e.contentDir),mainFields:["browser","module","main"],metafile:t!=="production",minify:t==="production",splitting:!0,external:["constants","zlib","stream","https","vm","module","worker_threads","child_process","@swc/core"],inject:[process.env.INSPECT_MODE==="true"?r(import.meta.url,"../../client/inspect-mode-hooks.js"):"",r(import.meta.url,"./web-shim.js")].filter(Boolean),define:{...i,"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.SERVER_EDITOR_APP_URL":`"${process.env.SERVER_EDITOR_APP_URL}"`,"process.env.ENABLE_COMMENTS":`"${process.env.ENABLE_COMMENTS}"`,"process.env.REDOCLY_TELEMETRY":$?'"on"':'"off"',"process.env.REDOCLY_PORTAL_VERSION":`"${w}"`,"process.env":`{"NODE_ENV": "${t}"}`,"process.platform":'"browser"',"process.browser":"true","module.hot":"false",global:"{}",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`},...process.env.INSPECT_MODE==="true"&&{"process.env.INSPECT_MODE":`${process.env.INSPECT_MODE}`},...process.env.MAIN_API_URL&&{"process.env.MAIN_API_URL":`"${process.env.MAIN_API_URL}"`}},logLevel:"silent"});return c.add(A),A})}async function de(e,o,t="development",n){M(o,{recursive:!0}),x(o),Y(a.join(o,"package.json"),JSON.stringify({name:"@redocly/portal/server-cache",type:"module"}));const p=[...n?[L(n)]:[],u(e,e.contentDir),E(e,e.contentDir),d(e,e.contentDir),f(e),S(e),T(e),I(e),D(),l(),N(),y(),v(),R(),_()],i=[{in:r(import.meta.url,"../../client/server-entry.js"),out:"server-entry"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../../client/server-props-entry.js"),out:"server-props-entry"},{in:r(import.meta.url,"../../client/api-request-handlers-entry.js"),out:"api-request-handlers-entry"},{in:r(import.meta.url,"../../client/api-docs-builder-entry.js"),out:"api-docs-builder-entry"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"},{in:r(import.meta.url,"../../client/middleware-entry.js"),out:"middleware-entry"}],s=await m({...O,entryPoints:i,outdir:o,plugins:p,sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",minify:t==="production",tsconfig:C(e.contentDir),mainFields:["module","main"],splitting:!0,external:["react","react-router","@dr.pogodin/react-helmet","@swc/core","pnpapi","canvas"],banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
2
- const require = topLevelCreateRequire(import.meta.url);`},platform:"node",define:{"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"module.hot":"false"},logLevel:"silent"});return c.add(s),s}async function Re(e,o,t="production",n){return await g("com.redocly.build.createServerCompiler",async()=>{const p=[...n?[L(n)]:[],P({"node-fetch":"{}",webpack:"{}",swagger2openapi:"{}"}),u(e,e.contentDir),E(e,e.contentDir),d(e,e.contentDir),f(e),S(e),T(e),I(e),D(),l(),N(),y(),v(),R(),_()],i=[{in:r(import.meta.url,"../node-bundle-entry.js"),out:"index"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../../client/api-docs-builder-entry.js"),out:"api-docs-builder-entry"},{in:r(import.meta.url,"../workers/api-routes-worker.js"),out:"api-routes-worker"},{in:r(import.meta.url,"../workers/scorecards-worker.js"),out:"scorecards-worker"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"}],s=await m({...O,entryPoints:i,outExtension:{".js":".mjs"},outdir:o,platform:"node",plugins:p,tsconfig:C(e.contentDir),mainFields:["module","main"],metafile:t!=="production",minify:t==="production",splitting:!1,define:{"process.env.NODE_ENV":`"${t}"`,...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.REDOCLY_EXECUTION_MODE":'"runtime"',"process.env.REDOCLY_PORTAL_VERSION":`"${w}"`,"module.hot":"false",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`}},banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
3
- const require = topLevelCreateRequire(import.meta.url);`},logLevel:"silent"});return c.add(s),s})}export{Ee as createClientCompiler,Re as createNodeBundleCompiler,de as createServerCompiler,ue as stopAllCompilers};
1
+ import{context as m}from"esbuild";import{mkdirSync as j,writeFileSync as Y,existsSync as b}from"node:fs";import*as l from"node:path";import{RUNTIME_RESOURCES_DIR as M,TELEMETRY_ENABLED as k}from"../constants/common.js";import{fromCurrentDir as r}from"../utils/paths.js";import{NodeBrowserPlugin as C}from"./plugins/node-browser.js";import{PortalImport as a}from"./plugins/portal-import.js";import{ThemesResolver as u}from"./plugins/themes-resolver.js";import{AssetsResolver as E}from"./plugins/assets-resolver.js";import{EsbuildErrorCollector as R}from"./plugins/esbuild-compile-resolver.js";import{ServerPropsResolver as _}from"./plugins/server-props-resolver.js";import{StyledComponentsSSR as d}from"./plugins/styled-components-ssr.js";import{DependencyResolver as v}from"./plugins/dependency-resolver.js";import{YamlLoader as f}from"./plugins/yaml-loader.js";import{ApiRequestHandlersResolver as T}from"./plugins/api-request-handlers-resolver.js";import{McpToolHandlersResolver as P}from"./plugins/mcp-tool-handlers-resolver.js";import{MiddlewareResolver as S}from"./plugins/middleware-resolver.js";import{OnRebuild as D}from"./plugins/on-rebuild.js";import{getPublicEnvVariables as V}from"../utils/envs/get-public-env-variables.js";import{PORTAL_VERSION as A}from"../version.js";import{AsyncApiPatch as L}from"./plugins/async-api-patch.js";import{telemetryTraceStep as I}from"../../cli/telemetry/helpers/trace-step.js";import{initServerRebuildTrigger as $}from"./generate.js";const y={bundle:!0,format:"esm",chunkNames:"chunks/[name]-[hash]"};function N(e){const o=l.join(e,"tsconfig.json");return b(o)?o:void 0}const c=new Set;async function ce(){await Promise.all([...c].map(e=>e.dispose())),c.clear()}async function me(e,o,t="production",n){return await I("com.redocly.build.createClientCompiler",async()=>{const p=V(),i={};Object.entries(p).map(([g,h])=>i[`process.env.${g}`]=JSON.stringify(h));const s=[...n?[D(n)]:[],C({path:"path-browserify",fs:"{}",tty:"tty-browserify",os:"os-browserify",http:"stream-http",https:"stream-http",readline:"{}",crypto:"{}",stream:"{}",zlib:"{}","https-proxy-agent":"{}"}),u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),_(e),v(),a(),f(),L(),d()],w=[r(import.meta.url,"../../client/browser-entry.js"),r(import.meta.url,"../../client/user-tags-entry.js")],O=await m({...y,entryPoints:w,outdir:l.join(o,M),sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",plugins:s,tsconfig:N(e.contentDir),mainFields:["browser","module","main"],metafile:t!=="production",minify:t==="production",splitting:!0,external:["constants","zlib","stream","https","vm","module","worker_threads","child_process","@swc/core"],inject:[process.env.INSPECT_MODE==="true"?r(import.meta.url,"../../client/inspect-mode-hooks.js"):"",r(import.meta.url,"./web-shim.js")].filter(Boolean),define:{...i,"process.env.NODE_ENV":`"${t}"`,"process.env.REDOCLY_FIRST_PARTY":'"true"',...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.SERVER_EDITOR_APP_URL":`"${process.env.SERVER_EDITOR_APP_URL}"`,"process.env.ENABLE_COMMENTS":`"${process.env.ENABLE_COMMENTS}"`,"process.env.REDOCLY_TELEMETRY":k?'"on"':'"off"',"process.env.REDOCLY_PORTAL_VERSION":`"${A}"`,"process.env":`{"NODE_ENV": "${t}"}`,"process.platform":'"browser"',"process.browser":"true","module.hot":"false",global:"{}",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`},...process.env.INSPECT_MODE==="true"&&{"process.env.INSPECT_MODE":`${process.env.INSPECT_MODE}`},...process.env.MAIN_API_URL&&{"process.env.MAIN_API_URL":`"${process.env.MAIN_API_URL}"`}},logLevel:"silent"});return c.add(O),O})}async function le(e,o,t="development",n){j(o,{recursive:!0}),$(o),Y(l.join(o,"package.json"),JSON.stringify({name:"@redocly/portal/server-cache",type:"module"}));const p=[...n?[D(n)]:[],u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),_(e),T(e),P(e),S(e),v(),a(),f(),L(),d()],i=[{in:r(import.meta.url,"../../client/server-entry.js"),out:"server-entry"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../../client/server-props-entry.js"),out:"server-props-entry"},{in:r(import.meta.url,"../../client/api-request-handlers-entry.js"),out:"api-request-handlers-entry"},{in:r(import.meta.url,"../../client/api-docs-builder-entry.js"),out:"api-docs-builder-entry"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"},{in:r(import.meta.url,"../../client/mcp-tool-handlers-entry.js"),out:"mcp-tool-handlers-entry"},{in:r(import.meta.url,"../../client/middleware-entry.js"),out:"middleware-entry"}],s=await m({...y,entryPoints:i,outdir:o,plugins:p,sourcemap:t!=="production"&&process.env.ENABLE_SOURCE_MAPS==="true",minify:t==="production",tsconfig:N(e.contentDir),mainFields:["module","main"],splitting:!0,external:["react","react-router","@dr.pogodin/react-helmet","@swc/core","pnpapi","canvas"],banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
2
+ const require = topLevelCreateRequire(import.meta.url);`},platform:"node",define:{"process.env.NODE_ENV":`"${t}"`,"process.env.REDOCLY_FIRST_PARTY":'"true"',...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"module.hot":"false"},logLevel:"silent"});return c.add(s),s}async function ae(e,o,t="production",n){return await I("com.redocly.build.createServerCompiler",async()=>{const p=[...n?[D(n)]:[],C({"node-fetch":"{}",webpack:"{}",swagger2openapi:"{}"}),u(e,e.contentDir),E(e,e.contentDir),R(e,e.contentDir),_(e),T(e),P(e),S(e),v(),a(),f(),L(),d()],i=[{in:r(import.meta.url,"../node-bundle-entry.js"),out:"index"},{in:r(import.meta.url,"../../client/user-tags-entry.js"),out:"user-tags-entry"},{in:r(import.meta.url,"../../client/api-docs-builder-entry.js"),out:"api-docs-builder-entry"},{in:r(import.meta.url,"../workers/api-routes-worker.js"),out:"api-routes-worker"},{in:r(import.meta.url,"../workers/scorecards-worker.js"),out:"scorecards-worker"},{in:r(import.meta.url,"../workers/mcp-tool-worker.js"),out:"mcp-tool-worker"}],s=await m({...y,entryPoints:i,outExtension:{".js":".mjs"},outdir:o,platform:"node",plugins:p,tsconfig:N(e.contentDir),mainFields:["module","main"],metafile:t!=="production",minify:t==="production",splitting:!1,define:{"process.env.NODE_ENV":`"${t}"`,"process.env.REDOCLY_FIRST_PARTY":'"true"',...process.env.REDOCLY_INTERNAL_DEV!==void 0&&{"process.env.REDOCLY_INTERNAL_DEV":`"${process.env.REDOCLY_INTERNAL_DEV}"`},"process.env.REDOCLY_EXECUTION_MODE":'"runtime"',"process.env.REDOCLY_PORTAL_VERSION":`"${A}"`,"module.hot":"false",...process.env.REDOCLY_PREFIX_PATHS&&{"process.env.REDOCLY_PREFIX_PATHS":`"${process.env.REDOCLY_PREFIX_PATHS}"`}},banner:{js:`import { createRequire as topLevelCreateRequire } from 'module';
3
+ const require = topLevelCreateRequire(import.meta.url);`},logLevel:"silent"});return c.add(s),s})}export{me as createClientCompiler,ae as createNodeBundleCompiler,le as createServerCompiler,ce as stopAllCompilers};
@@ -1 +1 @@
1
- import{generateMcpToolHandlersEntry as n}from"./codegen/index.js";const a="mcp-tool-handlers-ns",p=r=>({name:"esbuild-redocly-mcp-tool-handlers-resolver",setup:t=>{t.onResolve({filter:/@portal\/mcp-tool-handlers/},l=>{const o=Array.from(r.mcpToolHandlers.values()).map(e=>e.importPath);return{namespace:a,path:l.path,watchFiles:o}}),t.onLoad({filter:/@portal\/mcp-tool-handlers/,namespace:a},()=>({contents:n(Array.from(r.mcpToolHandlers.entries()).map(([o,e])=>[o,e.importPath])),resolveDir:"/",loader:"ts"}))}});export{p as McpToolHandlersResolver};
1
+ import{generateMcpToolHandlersEntry as s}from"./codegen/index.js";import{getServerRebuildTriggerPath as i}from"../generate.js";const n="mcp-tool-handlers-ns",m=e=>({name:"esbuild-redocly-mcp-tool-handlers-resolver",setup:a=>{a.onResolve({filter:/@portal\/mcp-tool-handlers/},async t=>{e.buildRevision>0&&await e.waitForPluginsRun();const r=Array.from(e.mcpToolHandlers.values()).map(l=>l.importPath),o=i(e.serverOutDir);return{namespace:n,path:t.path,watchFiles:[...r,o]}}),a.onLoad({filter:/@portal\/mcp-tool-handlers/,namespace:n},async()=>(e.buildRevision>0&&await e.waitForPluginsRun(),{contents:s(Array.from(e.mcpToolHandlers.entries()).map(([r,o])=>[r,o.importPath])),resolveDir:"/",loader:"ts"}))}});export{m as McpToolHandlersResolver};
@@ -1 +1 @@
1
- import*as w from"node:path";import{findFirstBinding as M,markdocParser as P}from"@redocly/api-docs";import{combineUrls as i}from"@redocly/theme/core/openapi";import{withPathPrefix as p}from"@redocly/theme/core/utils";import{GRAPHQL_SPEC_SLUG as _}from"../../../constants/common.js";import{PUBLIC_API_DEFINITIONS_FOLDER as f}from"../../constants/common.js";import{deepMerge as B}from"../../../utils/object/deep-merge.js";import{normalizeFeedbackOptions as E}from"./utils/normalize-feedback-options.js";import{replaceFileExtension as u}from"./utils/replace-file-extension.js";import{relativePathToBaseSlug as I}from"./utils/relative-path-to-base-slug.js";const U={tags:{},nodes:{},components:{}};function A(o,r){if(!(o?.off!==!0))return o;const t=I(r);return{url:p(`/_mock${t}`),position:"first",description:"Mock server",...o}}function L(o,r){return(r==="graphql"?[i(_,`${u(o,w.posix.extname(o))}?download`)]:[i(f,`${u(o,".json")}?download`),i(f,`${u(o,".yaml")}?download`)]).map(t=>({url:p(t)}))}function H(o,r,m){const{rootConfig:t,config:c,apiConfig:d,mergedConfig:e,relativePath:s}=m,a=B(t?.[o]||{},c[o]||{},d[o]||d.theme?.[o]||{}),b=r["x-feedback"]||a.feedback||c.feedback,S=!!e[o]?.excludeFromSearch||!!e.theme?.[o]?.excludeFromSearch||!!t?.[o]?.excludeFromSearch||!!t?.theme?.[o]?.excludeFromSearch,x=e.rbac||d.rbac,g=E(b),h=c.metadata,O={...g&&{feedback:g},hideSidebar:!0,mockServer:A(e?.mockServer||t?.mockServer,s),disableRouter:!0,downloadUrls:a.downloadUrls||L(s,o),excludeFromSearch:S,rbac:x,markdownParser:P};let l;if(o==="graphql"){const n=a;l={title:n.info?.title,...h,...n.metadata??{}}}else{const n=r.info,F=n?.["x-metadata"];l={title:n?.title,description:n?.description,...o==="openapi"&&{summary:n?.summary},...h,...F}}o==="openapi"&&a.showSchemaCatalogLinks&&(r["x-schema-catalog-link"]=i(f,s));const C=a.markdocOptions??U,k={...a,...O,specType:o,markdocOptions:C,metadata:l};return o==="asyncapi"&&(k.protocol=M(r)??void 0),k}export{L as buildDownloadUrls,H as createOptions};
1
+ import*as w from"node:path";import{findFirstBinding as M,markdocParser as P}from"@redocly/api-docs";import{combineUrls as i}from"@redocly/theme/core/openapi";import{withPathPrefix as h}from"@redocly/theme/core/utils";import{GRAPHQL_SPEC_SLUG as _}from"../../../constants/common.js";import{PUBLIC_API_DEFINITIONS_FOLDER as f}from"../../constants/common.js";import{deepMerge as B}from"../../../utils/object/deep-merge.js";import{normalizeFeedbackOptions as E}from"./utils/normalize-feedback-options.js";import{replaceFileExtension as u}from"./utils/replace-file-extension.js";import{relativePathToBaseSlug as I}from"./utils/relative-path-to-base-slug.js";const U={tags:{},nodes:{},components:{}};function A(o,r){if(!(o?.off!==!0))return o;const t=I(r);return{url:h(`/_mock${t}`),position:"first",description:"Mock server",...o}}function L(o,r){return(r==="graphql"?[i(_,`${u(o,w.posix.extname(o))}?download`)]:[i(f,`${u(o,".json")}?download`),i(f,`${u(o,".yaml")}?download`)]).map(t=>({url:h(t)}))}function H(o,r,m){const{rootConfig:t,config:c,apiConfig:s,mergedConfig:e,relativePath:d}=m,a=B(t?.[o]||{},c[o]||{},s[o]||s.theme?.[o]||{}),b=r["x-feedback"]||a.feedback||c.feedback,S=!!e[o]?.excludeFromSearch||!!e.theme?.[o]?.excludeFromSearch||!!t?.[o]?.excludeFromSearch||!!t?.theme?.[o]?.excludeFromSearch,x=e.rbac||s.rbac,g=E(b),k=c.metadata,O={...g&&{feedback:g},mockServer:A(e?.mockServer||t?.mockServer,d),disableRouter:!0,downloadUrls:a.downloadUrls||L(d,o),excludeFromSearch:S,rbac:x,markdownParser:P};let l;if(o==="graphql"){const n=a;l={title:n.info?.title,...k,...n.metadata??{}}}else{const n=r.info,F=n?.["x-metadata"];l={title:n?.title,description:n?.description,...o==="openapi"&&{summary:n?.summary},...k,...F}}o==="openapi"&&a.showSchemaCatalogLinks&&(r["x-schema-catalog-link"]=i(f,d));const C=a.markdocOptions??U,p={...a,...O,specType:o,markdocOptions:C,metadata:l};return o==="asyncapi"&&(p.protocol=M(r)??void 0),p}export{L as buildDownloadUrls,H as createOptions};
@@ -1,7 +1,9 @@
1
- import type { LifecycleContext, PluginDefaultOptions, RoutesInfoActions } from '../../types';
1
+ import type { LifecycleContext, PluginDefaultOptions, RoutesInfoActions } from '../../../types';
2
2
  export declare const isOpenapiDoc: (relativePath: string, context: LifecycleContext) => Promise<boolean>;
3
+ export declare const isAsyncapiDoc: (relativePath: string, context: LifecycleContext) => Promise<boolean>;
4
+ export declare const isGraphqlDoc: (relativePath: string) => boolean;
3
5
  export declare const isOpenApiURL: (url: string, pageRelativePath: string, actions: PluginDefaultOptions & RoutesInfoActions, context: LifecycleContext) => Promise<{
4
6
  isOpenapiDetected: boolean;
5
7
  isOpenapiValid: boolean;
6
8
  }>;
7
- //# sourceMappingURL=is-openapi-doc.d.ts.map
9
+ //# sourceMappingURL=is-api-doc.d.ts.map
@@ -0,0 +1 @@
1
+ import c from"node:path";import{CONFIG_FILE_NAME as O}from"../../../../constants/common.js";import{normalizeRouteSlug as l}from"../../../../utils/path/normalize-route-slug.js";import{removeLeadingSlash as x}from"../../../../utils/url/remove-leading-slash.js";import{parseBaseName as w}from"../../utils.js";const m=async(t,e)=>{if(!t.match(/(\.ya?ml|\.json)$/)||c.posix.basename(t)===O||await e.isPathIgnored(t))return null;const s=e.fs.getFileInfo(t);if(!s)return null;try{const{data:o}=await e.cache.load(s.realRelativePath,"yaml");return o??null}catch{return null}},L=async(t,e)=>{const s=await m(t,e);return!!(s?.openapi||s?.swagger)},j=async(t,e)=>!!(await m(t,e))?.asyncapi,F=t=>!!t.match(/(\.gql|\.graphql)$/),U=async(t,e,s,o)=>{const{getRouteBySlug:d,getRouteByFsPath:f}=s,i={isOpenapiDetected:!1,isOpenapiValid:!1},g={isOpenapiDetected:!0,isOpenapiValid:!1},h={isOpenapiDetected:!0,isOpenapiValid:!0};let r=t.toLowerCase();if(t.startsWith("/"))r=l(t);else if(t.startsWith("./")||t.startsWith("../")){const n=f(e)?.slug;if(!n)return i;const{isIndexFile:a}=w(e);r=a?l(c.posix.join(n,t)):l(c.posix.join(n,"../",t))}else return i;const p=r.toLowerCase().split("/");for(let n=p.length;n>=0;n--){const a=p.slice(0,n).join("/"),y=p.slice(n).join("/"),u=d(a)||f(x(a));if(u)return await L(u.fsPath,o)?y?g:h:i}return i};export{j as isAsyncapiDoc,F as isGraphqlDoc,U as isOpenApiURL,L as isOpenapiDoc};
@@ -1,5 +1,5 @@
1
1
  import type { ArazzoDefinition } from '@redocly/openapi-core';
2
- import type { MarkdocChunk } from '../openapi-docs/load-definition.js';
2
+ import type { MarkdocChunk } from '../api-docs/loader.js';
3
3
  import type { RedoclyConfig } from '@redocly/config';
4
4
  import type { LifecycleContext } from '../../types';
5
5
  export type BundledDefinition = {
@@ -1,4 +1,4 @@
1
- import s from"node:path";import{bundle as R,createConfig as I,getTotals as B}from"@redocly/openapi-core";import{CONFIG_FILE_NAME as J}from"../../../constants/common.js";import{deepMerge as L}from"../../../utils/object/deep-merge.js";import{pluralize as $}from"../../../utils/string/pluralize.js";import{getAllApiConfigsByPath as M}from"../get-api-config.js";import{injectDecoratorIntoConfig as W}from"../openapi-docs/decorators.js";import{ExternalResolver as _}from"../../fs/utils/external-ref-resolver.js";async function Y(o,{fs:n,logger:d,cache:u,getConfig:l,isPathIgnored:f}){let i;try{i=(await u.load(o,"yaml")).data}catch{return[]}if(!i?.arazzo)return d.verbose(`${o} file is not Arazzo document. Skipping`),[];const p=[],r=n.getFileInfo(o),t=await l(s.posix.dirname(o)),x=M(t?.apis,o,t.configPath),D=await f(o);for(const c of x){if(!c.output&&D)continue;const k=t.configPath?s.posix.dirname(t.configPath):".",a=c.output?s.posix.join(k,c.output):o;r&&c.output&&!await n.exists(a)&&n.addVirtualFile(a,r);const m=L(t,{rbac:void 0},c),v=s.resolve(n.cwd,t.realConfigPath||J),w=new _(n),O=await I(W(m,a,n.cwd),{configPath:v,externalRefResolver:w}),h=s.resolve(n.cwd,o),g={config:O,base:s.dirname(h),doc:{source:{absoluteRef:h},parsed:JSON.parse(JSON.stringify(i))}},{bundle:{parsed:N},problems:z,visitorsData:P}=await R({...g,dereference:!0,externalRefResolver:w}),{bundle:{parsed:S}}=await R({...g,doc:{...g.doc,parsed:JSON.parse(JSON.stringify(i))}}),V=P["markdown/markdown"]?.markdocChunks??[],e=B(z);let b=[e.errors&&`${e.errors} ${$(e.errors,"error","errors")}`,e.warnings&&`${e.warnings} ${$(e.warnings,"warning","warnings")}`,e.ignored&&`${e.ignored} ignored`].filter(Boolean).join(", ");if(e.errors){const C=z.find(F=>F.severity==="error");throw new Error(`${b} while bundling ${a} definition.
1
+ import s from"node:path";import{bundle as R,createConfig as I,getTotals as B}from"@redocly/openapi-core";import{CONFIG_FILE_NAME as J}from"../../../constants/common.js";import{deepMerge as L}from"../../../utils/object/deep-merge.js";import{pluralize as $}from"../../../utils/string/pluralize.js";import{getAllApiConfigsByPath as M}from"../get-api-config.js";import{injectDecoratorIntoConfig as W}from"../api-docs/utils/decorators.js";import{ExternalResolver as _}from"../../fs/utils/external-ref-resolver.js";async function Y(o,{fs:n,logger:d,cache:u,getConfig:l,isPathIgnored:f}){let i;try{i=(await u.load(o,"yaml")).data}catch{return[]}if(!i?.arazzo)return d.verbose(`${o} file is not Arazzo document. Skipping`),[];const p=[],r=n.getFileInfo(o),t=await l(s.posix.dirname(o)),x=M(t?.apis,o,t.configPath),D=await f(o);for(const c of x){if(!c.output&&D)continue;const k=t.configPath?s.posix.dirname(t.configPath):".",a=c.output?s.posix.join(k,c.output):o;r&&c.output&&!await n.exists(a)&&n.addVirtualFile(a,r);const m=L(t,{rbac:void 0},c),v=s.resolve(n.cwd,t.realConfigPath||J),w=new _(n),O=await I(W(m,a,n.cwd),{configPath:v,externalRefResolver:w}),h=s.resolve(n.cwd,o),g={config:O,base:s.dirname(h),doc:{source:{absoluteRef:h},parsed:JSON.parse(JSON.stringify(i))}},{bundle:{parsed:N},problems:z,visitorsData:P}=await R({...g,dereference:!0,externalRefResolver:w}),{bundle:{parsed:S}}=await R({...g,doc:{...g.doc,parsed:JSON.parse(JSON.stringify(i))}}),V=P["markdown/markdown"]?.markdocChunks??[],e=B(z);let b=[e.errors&&`${e.errors} ${$(e.errors,"error","errors")}`,e.warnings&&`${e.warnings} ${$(e.warnings,"warning","warnings")}`,e.ignored&&`${e.ignored} ignored`].filter(Boolean).join(", ");if(e.errors){const C=z.find(F=>F.severity==="error");throw new Error(`${b} while bundling ${a} definition.
2
2
 
3
3
  ${C?.message} at ${C?.location?.[0]?.pointer}
4
4
 
@@ -1 +1 @@
1
- import{writeFileSync as F}from"node:fs";import S from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as b}from"../../constants/common.js";import{envConfig as O}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as C}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as $,isPathIgnored as M}from"../../utils/index.js";import{isGraphqlDoc as k}from"../graphql-docs/is-graphql-doc.js";import{isMarkdownPage as D}from"../markdown/is-markdown-page.js";import{isOpenapiDoc as E}from"../openapi-docs/is-openapi-doc.js";import{PRODUCT_NAME as p}from"../../../config/product-gates.js";import{isAsyncapiDoc as _}from"../asyncapi-docs/is-asyncapi-doc.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{getBilledCatalogBuildPagesCount as j}from"./utils/get-billed-catalog-build-pages-count.js";async function X(){return{id:"entitlements",async afterRoutesCreated(g,u){await I("com.redocly.build.plugin.entitlements",async t=>{const i=R.instance(),s=[],n=[],r=[],a=[],l=[];for(const{relativePath:e}of u.fs.scan())M(e)||(D(e)?s.push(e):k(e)?r.push(e):C(e)?a.push(e):await E(e,u)?n.push(e):await _(e,u)&&l.push(e));const c=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",s.length.toString()),t?.setAttribute("isMarkdownSupported",(!!c).toString()),s.length>0&&!c&&o.warn(`The product you are using ("${p}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const d=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",n.length.toString()),t?.setAttribute("isOpenApiSupported",(!!d).toString()),n.length>0&&!d&&o.warn(`The product you are using ("${p}") does not support OpenAPI documents. The following files are ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const m=i.canAccessFeature("asyncapi");t?.setAttribute("totalAsyncApiFiles",l.length.toString()),t?.setAttribute("isAsyncApiSupported",(!!m).toString()),l.length>0&&!m&&o.warn(`The product you are using ("${p}") does not support AsyncAPI documents. The following files are ignored: ${l.map(()=>"%rp").join(", ")}`,...l);const f=i.canAccessFeature("graphql");t?.setAttribute("totalGraphqlFiles",r.length.toString()),t?.setAttribute("isGraphqlSupported",(!!f).toString()),r.length>0&&!f&&o.warn(`The product you are using ("${p}") does not support GraphQL documents. The following files are ignored: ${r.map(()=>"%rp").join(", ")}`,...r);const A=i.canAccessFeature("reactPages");t?.setAttribute("totalReactFiles",a.length.toString()),t?.setAttribute("isReactPagesSupported",(!!A).toString()),a.length>0&&!A&&o.warn(`The product you are using ("${p}") does not support React pages. The following files are ignored: ${a.map(()=>"%rp").join(", ")}`,...a);const P=(await u.getConfig()).entitiesCatalog,y=$(g.getAllRoutes()),{total:T}=await j(g.serverOutDir,P),h=y+T;t?.setAttribute("totalBilledPages",h.toString());const w=O.REDOCLY_METADATA_OUTPUT_FOLDER;w&&(o.info("Save total pages..."),F(S.join(w,b),JSON.stringify({totalPages:h},null)))})}}}export{X as entitlementsPlugin};
1
+ import{writeFileSync as F}from"node:fs";import S from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as b}from"../../constants/common.js";import{envConfig as O}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as C}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as $,isPathIgnored as M}from"../../utils/index.js";import{isAsyncapiDoc as k,isGraphqlDoc as D,isOpenapiDoc as E}from"../api-docs/utils/is-api-doc.js";import{isMarkdownPage as _}from"../markdown/is-markdown-page.js";import{PRODUCT_NAME as p}from"../../../config/product-gates.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{getBilledCatalogBuildPagesCount as j}from"./utils/get-billed-catalog-build-pages-count.js";async function V(){return{id:"entitlements",async afterRoutesCreated(g,u){await I("com.redocly.build.plugin.entitlements",async t=>{const i=R.instance(),s=[],n=[],r=[],a=[],l=[];for(const{relativePath:e}of u.fs.scan())M(e)||(_(e)?s.push(e):D(e)?r.push(e):C(e)?a.push(e):await E(e,u)?n.push(e):await k(e,u)&&l.push(e));const c=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",s.length.toString()),t?.setAttribute("isMarkdownSupported",(!!c).toString()),s.length>0&&!c&&o.warn(`The product you are using ("${p}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const d=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",n.length.toString()),t?.setAttribute("isOpenApiSupported",(!!d).toString()),n.length>0&&!d&&o.warn(`The product you are using ("${p}") does not support OpenAPI documents. The following files are ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const f=i.canAccessFeature("asyncapi");t?.setAttribute("totalAsyncApiFiles",l.length.toString()),t?.setAttribute("isAsyncApiSupported",(!!f).toString()),l.length>0&&!f&&o.warn(`The product you are using ("${p}") does not support AsyncAPI documents. The following files are ignored: ${l.map(()=>"%rp").join(", ")}`,...l);const m=i.canAccessFeature("graphql");t?.setAttribute("totalGraphqlFiles",r.length.toString()),t?.setAttribute("isGraphqlSupported",(!!m).toString()),r.length>0&&!m&&o.warn(`The product you are using ("${p}") does not support GraphQL documents. The following files are ignored: ${r.map(()=>"%rp").join(", ")}`,...r);const A=i.canAccessFeature("reactPages");t?.setAttribute("totalReactFiles",a.length.toString()),t?.setAttribute("isReactPagesSupported",(!!A).toString()),a.length>0&&!A&&o.warn(`The product you are using ("${p}") does not support React pages. The following files are ignored: ${a.map(()=>"%rp").join(", ")}`,...a);const P=(await u.getConfig()).entitiesCatalog,y=$(g.getAllRoutes()),{total:T}=await j(g.serverOutDir,P),h=y+T;t?.setAttribute("totalBilledPages",h.toString());const w=O.REDOCLY_METADATA_OUTPUT_FOLDER;w&&(o.info("Save total pages..."),F(S.join(w,b),JSON.stringify({totalPages:h},null)))})}}}export{V as entitlementsPlugin};
@@ -1 +1 @@
1
- import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as A}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{reporter as w}from"../../tools/notifiers/reporter.js";import{EntitlementsProvider as O}from"../../entitlements/entitlements-provider.js";import{isL10nPath as E}from"../../fs/utils/is-l10n-path.js";import{isOpenapiDoc as I}from"../openapi-docs/is-openapi-doc.js";import{telemetryTraceStep as N}from"../../../cli/telemetry/helpers/trace-step.js";async function $(){return{id:"l10n",async processContent(n,i){await N("com.redocly.build.plugin.l10n",async a=>{const{fs:t,cache:c,getConfig:r}=i,e={},p=O.instance(),l=await r();a?.setAttribute("config",JSON.stringify(l.l10n||{}));const s=l.l10n?.defaultLocale||d;if(p.canAccessFeature("l10n")){await F(i);for(const{relativePath:o}of t.scan(/(^|.*[\/\\])translations\.yaml$/)){const u=await c.load(o,"yaml"),L=P(o)||s;e[L]={translation:u.data||{}}}}e[s]={translation:{...e[s]?.translation||{}}};const f=l.l10n?.locales||[d,...t.localeFolders].map(o=>({code:o.toLowerCase(),name:o}));a?.setAttribute("locales",JSON.stringify(f)),n.setGlobalData({l10n:{translations:e,defaultLocale:s,locales:f.map(o=>({code:o.code,name:o.name||o.code}))}})})}}}function P(n){return n.indexOf("/")>0?n.split("/")[1]:void 0}async function F(n){const i=n.fs.scan();for(const{isVirtual:a,realRelativePath:t}of i){if(a)continue;if(E(t)&&t.endsWith(".page.tsx")&&await w.panicOnBuild(`The file %rp is not allowed in ${A} or ${y} folders`,t),g.posix.basename(t)===h){const r=/^(?:@(i18n|l10n)[\/\\][^\/\\]+[\/\\])?translations\.yaml$/.test(t),e=await I(t,n);!r&&!e&&m.warn("The file %rp is in the wrong location. Make sure it is located in the root directory or in the locale root directory.",t),r&&e&&m.warn("It looks like the file %rp might be an OpenAPI definition and is located in a location reserved for translation files. Please rename it or move to another directory if it is not a translations file",t)}}}export{$ as l10nPlugin};
1
+ import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as A}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{reporter as w}from"../../tools/notifiers/reporter.js";import{EntitlementsProvider as O}from"../../entitlements/entitlements-provider.js";import{isL10nPath as E}from"../../fs/utils/is-l10n-path.js";import{isOpenapiDoc as I}from"../api-docs/utils/is-api-doc.js";import{telemetryTraceStep as N}from"../../../cli/telemetry/helpers/trace-step.js";async function $(){return{id:"l10n",async processContent(n,i){await N("com.redocly.build.plugin.l10n",async a=>{const{fs:t,cache:c,getConfig:r}=i,e={},p=O.instance(),l=await r();a?.setAttribute("config",JSON.stringify(l.l10n||{}));const s=l.l10n?.defaultLocale||d;if(p.canAccessFeature("l10n")){await F(i);for(const{relativePath:o}of t.scan(/(^|.*[\/\\])translations\.yaml$/)){const u=await c.load(o,"yaml"),L=P(o)||s;e[L]={translation:u.data||{}}}}e[s]={translation:{...e[s]?.translation||{}}};const f=l.l10n?.locales||[d,...t.localeFolders].map(o=>({code:o.toLowerCase(),name:o}));a?.setAttribute("locales",JSON.stringify(f)),n.setGlobalData({l10n:{translations:e,defaultLocale:s,locales:f.map(o=>({code:o.code,name:o.name||o.code}))}})})}}}function P(n){return n.indexOf("/")>0?n.split("/")[1]:void 0}async function F(n){const i=n.fs.scan();for(const{isVirtual:a,realRelativePath:t}of i){if(a)continue;if(E(t)&&t.endsWith(".page.tsx")&&await w.panicOnBuild(`The file %rp is not allowed in ${A} or ${y} folders`,t),g.posix.basename(t)===h){const r=/^(?:@(i18n|l10n)[\/\\][^\/\\]+[\/\\])?translations\.yaml$/.test(t),e=await I(t,n);!r&&!e&&m.warn("The file %rp is in the wrong location. Make sure it is located in the root directory or in the locale root directory.",t),r&&e&&m.warn("It looks like the file %rp might be an OpenAPI definition and is located in a location reserved for translation files. Please rename it or move to another directory if it is not a translations file",t)}}}export{$ as l10nPlugin};
@@ -1,2 +1,2 @@
1
- import F from"@redocly/portal-plugin-mock-server";import{REDOCLY_ROUTE_RBAC as B}from"@redocly/config";import{combineUrls as E,withPathPrefix as k}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as x}from"../constants/common.js";import{removeTrailingSlash as L}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as N}from"../../utils/url/remove-leading-slash.js";import{isTruthy as j}from"../../utils/guards/is-truthy.js";import{normalizeRouteSlug as D}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as q}from"../../utils/path/parse-path-versions.js";import{reporter as w}from"../tools/notifiers/reporter.js";import{logger as P}from"../tools/notifiers/logger.js";import{envConfig as S}from"../config/env-config.js";import{shaDirPathShort as V}from"../utils/crypto/sha-dir-path-short.js";import{writeServerRebuildTrigger as _}from"../esbuild/generate.js";import{customPagesPlugin as $}from"../../server/plugins/pages/index.js";import{apiDocsPlugin as M}from"../../server/plugins/api-docs/index.js";import{configParserPlugin as z}from"./config-parser/index.js";import{createSlugify as H}from"./create-slugify.js";import{markdownPlugin as U}from"./markdown/index.js";import{generateBrowserPluginsModule as G,generateClientRoutes as I,generateTemplatesModule as W}from"../esbuild/generate.js";import{searchPlugin as K}from"./search/index.js";import{skillsPlugin as Y}from"./skills/index.js";import{defaultThemePlugin as J}from"./default-theme/index.js";import{apiKeyMgmtPlugin as Q}from"./dev-onboarding/index.js";import{apiFunctionsPlugin as X}from"./api-functions/index.js";import{scorecardClassicPlugin as Z}from"./scorecard-classic/index.js";import{lintPlugin as ee}from"./lint/index.js";import{resolveExternalPlugins as te}from"../external-plugins/resolve-external-plugins.js";import{sidebarsPlugin as oe}from"./sidebars/index.js";import{l10nPlugin as ie}from"./l10n/index.js";import{validateRedirects as re}from"../utils/redirects/validate-redirects.js";import{analyticsPlugins as ne}from"./analytics/index.js";import{sitemapPlugin as se}from"./sitemap/index.js";import{entitlementsPlugin as ae}from"./entitlements/index.js";import{getBilledPagesCount as le}from"../utils/index.js";import{telemetry as ce}from"../../cli/telemetry/index.js";import{telemetryTraceStep as b}from"../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as T}from"../entitlements/entitlements-provider.js";import{enforceLoginPlugin as ue}from"./enforce-login/index.js";import{ssoPlugin as fe}from"./sso/index.js";import{Cache as me}from"../fs/cache.js";import{ContentFs as de}from"../fs/content-fs.js";import{findProductBySlug as ge}from"../utils/product.js";import{isRouteReserved as pe}from"./get-reserved-routes.js";import{catalogClassicPlugin as Pe}from"./catalog-classic/index.js";import{arazzoDocsPlugin as ye}from"./arazzo-docs/index.js";const he=[z,ue,fe,J,ie,U,M,ye,Z,ee,X,$,Q,Pe,{importPath:"./catalog-entities/plugin.js",loadCondition:()=>S.NEW_CATALOG_ENABLED??!1},{importPath:"./scorecards/plugin.js",loadCondition:()=>S.NEW_SCORECARDS_ENABLED??!1},{importPath:"./mcp/index.js",loadCondition:()=>T.instance().canAccessFeature("mcp")},oe,se,ae,K,Y,F,...ne];async function gt(t,e=he){return await b("com.redocly.build.pluginsInit",async()=>{const r=[],R=T.instance(),y={};for(const s of e){let u;if("loadCondition"in s){if(!s.loadCondition())continue;const o=await import(s.importPath);if(!o.default||typeof o.default!="function"){await w.panicOnBuild(`Dynamic plugin ${s.importPath} does not export a default export or it is not a function`);continue}u=o.default}else u=s;const h=await u(t);for(const[o,f]of Object.entries(h.loaders||{}))y[o]&&await w.panicOnBuild(`Duplicate loader with name ${o}`),y[o]=f;(!h.requiredEntitlements||h.requiredEntitlements?.every(o=>R.canAccessFeature(o)))&&r.push(h)}const l=new de(t.contentDir);await l.ready;const c=new me(l);return c.setLoaders(y),P.verbose("All plugins instantiated"),{pluginInstances:r,lifecycleContext:we(l,c)}})}function O(t){P.verbose("Generating templates"),b("com.redocly.build.writeClientEntries",()=>{W(t),G(t),I(t)})}async function Re(t){const e=t.getAllRoutes();le(e)||await w.panicOnBuild("No routes created by plugins. Please check your project configuration.")}async function pt(t,e,r,R={}){const y=T.instance();try{await b("com.redocly.build.pluginsRun",async()=>{e.startPluginsRun();const l=S.isDevelopMode&&e.buildRevision>0,c=l?Array.from(e.apiRoutesRequestHandlers.keys()).sort().join(","):"";let s=[];await b("com.redocly.build.pluginsProcessContent",async o=>{for(const i of t){const a=P.startTiming();await i.processContent?.(e,r),P.verboseTime(a,`processContent for ${i.id}`)}s=(await te(e.contentDir,e.config.plugins)).map(i=>i.lifecyclePlugin).filter(i=>j(i)&&(!i.requiredEntitlements||i.requiredEntitlements?.every(a=>y.canAccessFeature(a)))),r.cache.setLoaders(Object.fromEntries(s.flatMap(i=>Object.entries(i.loaders||{}))));for(const i of s){const a=P.startTiming();await i.processContent?.(e,r),P.verboseTime(a,`processContent for ${i.id}`)}o?.setAttribute("externalPluginsProcessed",s.length.toString())});const u=await Ce(e,r),h=[...t,...s];if(O(e),S.isDevelopMode?await e.userCodeReady:e.buildRevision++,await b("com.redocly.build.pluginsAfterRoutesCreated",async()=>{for(const o of h){const f=P.startTiming();await o.afterRoutesCreated?.(e,u),P.verboseTime(f,`afterRoutesCreated for ${o.id}`)}}),re(e),await e.reportUnsetEnvVars(),await Re(e),O(e),l){const o=Array.from(e.apiRoutesRequestHandlers.keys()).sort().join(",");c!==o&&(e.markRequestHandlersEntryOutdated(),_(e.serverOutDir))}})}catch(l){const c="Unhandled error in plugin. "+l.message+`
2
- `+l.stack;ce.sendCliErrorCaughtMessage([{id:"cli",object:"error",uri:"urn:redocly:realm:cli:error:cli",message:c}]),R.failFast?await w.panic(c):await w.panicOnBuild(c)}finally{e.finishPluginsRun()}}async function Ce(t,e){const{cache:r,fs:R}=e,y=await e.getConfig(),l=Object.values(y.products||{}),c=(await r.load("versions-config","versions-config")).data,s=(await r.load("content-slugs","content-slugs")).data,u=H(s);for(const{duplicateInAllLocales:o,slugSuffix:f,sharedData:i=[],redirectFrom:a=[],...d}of t.newRoutes){const v=D(d.slug?d.slug:u(d.fsPath)),g=L(f?E(v,f):v),n={...d,[B]:{slug:g,fsPath:d.fsPath},slug:g,baseSlug:v,versions:h(d.fsPath,f),product:ge(l,g,u)};pe(g,y)&&await w.panicOnBuildContentError(`Route "${g}" is reserved and cannot be used. Please choose a different slug for "${d.fsPath}".`),t.routesByFsPath.set(n.fsPath,n.slug),t.routesBySlug.set(n.slug,n);for(const{key:p,id:m}of i)t.addRouteSharedData(n.slug,p,m);for(const p of a)t.addRedirect(p.from,{type:p.type,to:n.slug});if(o)for(const p of R.localeFolders){const m={...n,slug:"/"+p.toLowerCase()+n.slug};t.routesByFsPath.set(m.fsPath,m.slug),t.routesBySlug.set(m.slug,m);for(const{key:C,id:A}of i)t.addRouteSharedData(m.slug,C,A);for(const C of a){const A=E(R.localizationFolder,p,C.from);t.addRedirect(A,{type:C.type,to:m.slug},{trackOriginalSource:!1})}}}return t.newRoutes=[],{...e,slugify:u};function h(o,f=""){const i=q(o);if(!i?.versionName)return;const{versionFolderPath:a,filePathInVersion:d,versionName:v}=i,g=c.get(a);if(g)return g.versions.map(n=>{const p=g.defaultVersion===n.version,m=N(E(a,x+n.version,d)),C=u(m);return{version:n.version,label:n.name||n.version,link:D(E(C,f)),default:p,active:v===n.version,folderId:V(`${a}`)}})}}function we(t,e){return{fs:t,cache:e,getConfig:async(r=".")=>(await e.load(r,"nearest-redocly-config",t.localeFolders)).data,isPathIgnored:async r=>(await e.load(r,"is-ignored")).data,withPathPrefix:k,logger:P}}export{he as INTERNAL_PLUGINS,we as createLifecycleContext,gt as initPlugins,pt as runPlugins,O as writeClientEntries};
1
+ import B from"@redocly/portal-plugin-mock-server";import{REDOCLY_ROUTE_RBAC as x}from"@redocly/config";import{combineUrls as E,withPathPrefix as L}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as k}from"../constants/common.js";import{removeTrailingSlash as N}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as j}from"../../utils/url/remove-leading-slash.js";import{isTruthy as $}from"../../utils/guards/is-truthy.js";import{normalizeRouteSlug as D}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as V}from"../../utils/path/parse-path-versions.js";import{reporter as v}from"../tools/notifiers/reporter.js";import{logger as P}from"../tools/notifiers/logger.js";import{envConfig as S}from"../config/env-config.js";import{shaDirPathShort as M}from"../utils/crypto/sha-dir-path-short.js";import{writeServerRebuildTrigger as _}from"../esbuild/generate.js";import{customPagesPlugin as q}from"../../server/plugins/pages/index.js";import{apiDocsPlugin as z}from"../../server/plugins/api-docs/index.js";import{configParserPlugin as H}from"./config-parser/index.js";import{createSlugify as U}from"./create-slugify.js";import{markdownPlugin as G}from"./markdown/index.js";import{generateBrowserPluginsModule as I,generateClientRoutes as W,generateTemplatesModule as K}from"../esbuild/generate.js";import{searchPlugin as Y}from"./search/index.js";import{skillsPlugin as J}from"./skills/index.js";import{defaultThemePlugin as Q}from"./default-theme/index.js";import{apiKeyMgmtPlugin as X}from"./dev-onboarding/index.js";import{apiFunctionsPlugin as Z}from"./api-functions/index.js";import{scorecardClassicPlugin as ee}from"./scorecard-classic/index.js";import{lintPlugin as te}from"./lint/index.js";import{resolveExternalPlugins as oe}from"../external-plugins/resolve-external-plugins.js";import{sidebarsPlugin as ie}from"./sidebars/index.js";import{l10nPlugin as re}from"./l10n/index.js";import{validateRedirects as ne}from"../utils/redirects/validate-redirects.js";import{analyticsPlugins as se}from"./analytics/index.js";import{sitemapPlugin as ae}from"./sitemap/index.js";import{entitlementsPlugin as le}from"./entitlements/index.js";import{getBilledPagesCount as ce}from"../utils/index.js";import{telemetry as ue}from"../../cli/telemetry/index.js";import{telemetryTraceStep as b}from"../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as A}from"../entitlements/entitlements-provider.js";import{enforceLoginPlugin as fe}from"./enforce-login/index.js";import{ssoPlugin as me}from"./sso/index.js";import{Cache as de}from"../fs/cache.js";import{ContentFs as ge}from"../fs/content-fs.js";import{findProductBySlug as pe}from"../utils/product.js";import{isRouteReserved as Pe}from"./get-reserved-routes.js";import{catalogClassicPlugin as ye}from"./catalog-classic/index.js";import{arazzoDocsPlugin as he}from"./arazzo-docs/index.js";const Re=[H,fe,me,Q,re,G,z,he,ee,te,Z,q,X,ye,{importPath:"./catalog-entities/plugin.js",loadCondition:()=>S.NEW_CATALOG_ENABLED??!1},{importPath:"./scorecards/plugin.js",loadCondition:()=>S.NEW_SCORECARDS_ENABLED??!1},{importPath:"./mcp/index.js",loadCondition:()=>A.instance().canAccessFeature("mcp")},ie,ae,le,Y,J,B,...se];async function pt(t,e=Re){return await b("com.redocly.build.pluginsInit",async()=>{const r=[],R=A.instance(),y={};for(const s of e){let u;if("loadCondition"in s){if(!s.loadCondition())continue;const i=await import(s.importPath);if(!i.default||typeof i.default!="function"){await v.panicOnBuild(`Dynamic plugin ${s.importPath} does not export a default export or it is not a function`);continue}u=i.default}else u=s;const h=await u(t);for(const[i,f]of Object.entries(h.loaders||{}))y[i]&&await v.panicOnBuild(`Duplicate loader with name ${i}`),y[i]=f;(!h.requiredEntitlements||h.requiredEntitlements?.every(i=>R.canAccessFeature(i)))&&r.push(h)}const l=new ge(t.contentDir);await l.ready;const c=new de(l);return c.setLoaders(y),P.verbose("All plugins instantiated"),{pluginInstances:r,lifecycleContext:we(l,c)}})}function O(t){P.verbose("Generating templates"),b("com.redocly.build.writeClientEntries",()=>{K(t),I(t),W(t)})}async function Ce(t){const e=t.getAllRoutes();ce(e)||await v.panicOnBuild("No routes created by plugins. Please check your project configuration.")}async function Pt(t,e,r,R={}){const y=A.instance();try{await b("com.redocly.build.pluginsRun",async()=>{e.startPluginsRun();const l=S.isDevelopMode&&e.buildRevision>0,c=l?F(e):"";let s=[];await b("com.redocly.build.pluginsProcessContent",async i=>{for(const o of t){const a=P.startTiming();await o.processContent?.(e,r),P.verboseTime(a,`processContent for ${o.id}`)}s=(await oe(e.contentDir,e.config.plugins)).map(o=>o.lifecyclePlugin).filter(o=>$(o)&&(!o.requiredEntitlements||o.requiredEntitlements?.every(a=>y.canAccessFeature(a)))),r.cache.setLoaders(Object.fromEntries(s.flatMap(o=>Object.entries(o.loaders||{}))));for(const o of s){const a=P.startTiming();await o.processContent?.(e,r),P.verboseTime(a,`processContent for ${o.id}`)}i?.setAttribute("externalPluginsProcessed",s.length.toString())});const u=await ve(e,r),h=[...t,...s];O(e),S.isDevelopMode?await e.userCodeReady:e.buildRevision++,await b("com.redocly.build.pluginsAfterRoutesCreated",async()=>{for(const i of h){const f=P.startTiming();await i.afterRoutesCreated?.(e,u),P.verboseTime(f,`afterRoutesCreated for ${i.id}`)}}),ne(e),await e.reportUnsetEnvVars(),await Ce(e),O(e),l&&c!==F(e)&&(e.markRequestHandlersEntryOutdated(),_(e.serverOutDir))})}catch(l){const c="Unhandled error in plugin. "+l.message+`
2
+ `+l.stack;ue.sendCliErrorCaughtMessage([{id:"cli",object:"error",uri:"urn:redocly:realm:cli:error:cli",message:c}]),R.failFast?await v.panic(c):await v.panicOnBuild(c)}finally{e.finishPluginsRun()}}async function ve(t,e){const{cache:r,fs:R}=e,y=await e.getConfig(),l=Object.values(y.products||{}),c=(await r.load("versions-config","versions-config")).data,s=(await r.load("content-slugs","content-slugs")).data,u=U(s);for(const{duplicateInAllLocales:i,slugSuffix:f,sharedData:o=[],redirectFrom:a=[],...d}of t.newRoutes){const w=D(d.slug?d.slug:u(d.fsPath)),g=N(f?E(w,f):w),n={...d,[x]:{slug:g,fsPath:d.fsPath},slug:g,baseSlug:w,versions:h(d.fsPath,f),product:pe(l,g,u)};Pe(g,y)&&await v.panicOnBuildContentError(`Route "${g}" is reserved and cannot be used. Please choose a different slug for "${d.fsPath}".`),t.routesByFsPath.set(n.fsPath,n.slug),t.routesBySlug.set(n.slug,n);for(const{key:p,id:m}of o)t.addRouteSharedData(n.slug,p,m);for(const p of a)t.addRedirect(p.from,{type:p.type,to:n.slug});if(i)for(const p of R.localeFolders){const m={...n,slug:"/"+p.toLowerCase()+n.slug};t.routesByFsPath.set(m.fsPath,m.slug),t.routesBySlug.set(m.slug,m);for(const{key:C,id:T}of o)t.addRouteSharedData(m.slug,C,T);for(const C of a){const T=E(R.localizationFolder,p,C.from);t.addRedirect(T,{type:C.type,to:m.slug},{trackOriginalSource:!1})}}}return t.newRoutes=[],{...e,slugify:u};function h(i,f=""){const o=V(i);if(!o?.versionName)return;const{versionFolderPath:a,filePathInVersion:d,versionName:w}=o,g=c.get(a);if(g)return g.versions.map(n=>{const p=g.defaultVersion===n.version,m=j(E(a,k+n.version,d)),C=u(m);return{version:n.version,label:n.name||n.version,link:D(E(C,f)),default:p,active:w===n.version,folderId:M(`${a}`)}})}}function we(t,e){return{fs:t,cache:e,getConfig:async(r=".")=>(await e.load(r,"nearest-redocly-config",t.localeFolders)).data,isPathIgnored:async r=>(await e.load(r,"is-ignored")).data,withPathPrefix:L,logger:P}}function F(t){return[...t.apiRoutesRequestHandlers.keys(),...t.getMcpTools().map(e=>`${e.name}:${e.importPath}`)].sort().join(",")}export{Re as INTERNAL_PLUGINS,we as createLifecycleContext,pt as initPlugins,Pt as runPlugins,O as writeClientEntries};
@@ -1 +1 @@
1
- import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as T,GRAPHQL_TEMPLATE_ID as v,OPENAPI_DOCS_TEMPLATE_ID as y}from"../../../../constants/common.js";import{isLocalLink as D}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as h}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as F}from"../../../../utils/path/remove-fragment.js";import{getInnerText as M}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as U}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isAuthRoutePath as W}from"../../../../utils/auth/is-auth-route-path.js";import{isApiDownloadLink as j}from"../../../utils/is-api-download-link.js";import{MdResolveError as g}from"./md-resolve-error.js";import{getLinkOriginalAttrName as B}from"./utils.js";import{isOpenApiURL as $}from"../../openapi-docs/is-openapi-doc.js";import{parseBaseName as C}from"../../utils.js";import{isMarkdownPage as V}from"../is-markdown-page.js";import{copyStaticFile as b}from"../../../utils/fs.js";async function at(i,s,E,{actions:k,context:f}){const{contentDir:d,outdir:S,getRouteByFsPath:w,hasRouteOrRedirectBySlug:A}=k,L=B(s),e=i[L]||U(i,s);if(i[L]=e,!D(e)||j(e)||W(e))return;const[z,t="",R,P]=/^([^\?#]+)?([^#]+)?(.+)?/.exec(e)||[],c=i.type==="image"?"IMAGE":"LINK",u=String(i.attributes.title||i.attributes.alt||M([i])||""),n=F(E);if(i.type!=="image"){const{isOpenapiDetected:r,isOpenapiValid:m}=await $(t,n,k,f);if(r&&!m)throw new g(`OpenAPI route ${e} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c})}if(o.extname(t)===""){if(t.startsWith("/")){if(!A(h(t)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c});p(i,s,t+(R||"")+(P||""))}if(!e.startsWith("#")&&!t.startsWith("/")&&V(n)){const r=w(n)?.slug;if(!r)return;const{isIndexFile:m}=C(n),x=m?h(o.posix.join(r,t)):h(o.posix.join(r,"../",t));if(!A(h(x)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:x,title:u,brokenLinkType:c});p(i,s,x+(R||"")+(P||""))}return}const a=t.startsWith("/")?t.substring(1):o.posix.join(o.posix.dirname(n),decodeURI(t)),_=t.startsWith("/")?o.posix.join("static",t.substring(1)):"",I=f.fs.exists(a),O=f.fs.exists(_),l=w(a);if(!I&&!l&&!O)throw p(i,s,"#"),new g(`File ${a} does not exist`,{rawLink:e,link:a,title:u,brokenLinkType:c});if(l){const r=[y,v,T].includes(l.templateId);p(i,s,(r?l.baseSlug:l.slug)+(P||""))}else if(I){const r=f.fs.getFileInfo(a);if(!r||r.isVirtual)return;const m=await b(d,r.realRelativePath,S);p(i,s,m)}}export{at as resolveLink};
1
+ import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as T,GRAPHQL_TEMPLATE_ID as v,OPENAPI_DOCS_TEMPLATE_ID as y}from"../../../../constants/common.js";import{isLocalLink as D}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as h}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as F}from"../../../../utils/path/remove-fragment.js";import{getInnerText as M}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as U}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isAuthRoutePath as W}from"../../../../utils/auth/is-auth-route-path.js";import{isApiDownloadLink as j}from"../../../utils/is-api-download-link.js";import{MdResolveError as g}from"./md-resolve-error.js";import{getLinkOriginalAttrName as B}from"./utils.js";import{isOpenApiURL as $}from"../../api-docs/utils/is-api-doc.js";import{parseBaseName as C}from"../../utils.js";import{isMarkdownPage as V}from"../is-markdown-page.js";import{copyStaticFile as b}from"../../../utils/fs.js";async function at(i,s,E,{actions:k,context:f}){const{contentDir:d,outdir:S,getRouteByFsPath:w,hasRouteOrRedirectBySlug:A}=k,L=B(s),e=i[L]||U(i,s);if(i[L]=e,!D(e)||j(e)||W(e))return;const[z,t="",R,P]=/^([^\?#]+)?([^#]+)?(.+)?/.exec(e)||[],c=i.type==="image"?"IMAGE":"LINK",u=String(i.attributes.title||i.attributes.alt||M([i])||""),n=F(E);if(i.type!=="image"){const{isOpenapiDetected:r,isOpenapiValid:m}=await $(t,n,k,f);if(r&&!m)throw new g(`OpenAPI route ${e} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c})}if(o.extname(t)===""){if(t.startsWith("/")){if(!A(h(t)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:t,title:u,brokenLinkType:c});p(i,s,t+(R||"")+(P||""))}if(!e.startsWith("#")&&!t.startsWith("/")&&V(n)){const r=w(n)?.slug;if(!r)return;const{isIndexFile:m}=C(n),x=m?h(o.posix.join(r,t)):h(o.posix.join(r,"../",t));if(!A(h(x)))throw new g(`Route ${t} does not exist`,{rawLink:e,link:x,title:u,brokenLinkType:c});p(i,s,x+(R||"")+(P||""))}return}const a=t.startsWith("/")?t.substring(1):o.posix.join(o.posix.dirname(n),decodeURI(t)),_=t.startsWith("/")?o.posix.join("static",t.substring(1)):"",I=f.fs.exists(a),O=f.fs.exists(_),l=w(a);if(!I&&!l&&!O)throw p(i,s,"#"),new g(`File ${a} does not exist`,{rawLink:e,link:a,title:u,brokenLinkType:c});if(l){const r=[y,v,T].includes(l.templateId);p(i,s,(r?l.baseSlug:l.slug)+(P||""))}else if(I){const r=f.fs.getFileInfo(a);if(!r||r.isVirtual)return;const m=await b(d,r.realRelativePath,S);p(i,s,m)}}export{at as resolveLink};
@@ -1 +1 @@
1
- import f from"node:path";import{API_DOCS_SHARED_DATA_PREFIX as p}from"../../../constants/plugins/api-docs.js";import{getNodeAttribute as A}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as w}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isOpenapiDoc as d}from"../../openapi-docs/is-openapi-doc.js";import{MdResolveError as a}from"./md-resolve-error.js";import{getLinkOriginalAttrName as g}from"./utils.js";async function R(r,t,e,{context:n}){const s=g(t);let o=r[s]||A(r,t);if(o||await d(e,n)&&(o=f.basename(e)),r[s]=o,!o)return;const i=f.posix.join(f.posix.dirname(e),o),m=p+i;if(w(r,t,m),!n.fs.exists(i))throw new a(`Definition file ${i} does not exist`,{rawLink:i});if(await n.isPathIgnored(i))throw new a(`Definition file ${i} is ignored in config`,{rawLink:i});return{sharedDataId:m}}export{R as resolveOpenApiRef};
1
+ import f from"node:path";import{API_DOCS_SHARED_DATA_PREFIX as p}from"../../../constants/plugins/api-docs.js";import{getNodeAttribute as A}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as w}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isOpenapiDoc as d}from"../../api-docs/utils/is-api-doc.js";import{MdResolveError as a}from"./md-resolve-error.js";import{getLinkOriginalAttrName as g}from"./utils.js";async function R(r,t,e,{context:n}){const s=g(t);let o=r[s]||A(r,t);if(o||await d(e,n)&&(o=f.basename(e)),r[s]=o,!o)return;const i=f.posix.join(f.posix.dirname(e),o),m=p+i;if(w(r,t,m),!n.fs.exists(i))throw new a(`Definition file ${i} does not exist`,{rawLink:i});if(await n.isPathIgnored(i))throw new a(`Definition file ${i} is ignored in config`,{rawLink:i});return{sharedDataId:m}}export{R as resolveOpenApiRef};
@@ -1,4 +1,4 @@
1
- import{getCallableApis as s,isFetchCapable as o}from"../../../gateway-mcp/fetch-capability.js";import{FETCH_TOOL_NAME as i}from"../../constants.js";const l=["```ts","/**"," * Call a documented API. Only the callable APIs' documented hosts are reachable."," * Responses cap at 1 MiB and redirects are not followed."," */","declare function fetch(url: string | URL, init?: {"," method?: string;"," /** `content-type` is set automatically for URLSearchParams/FormData unless you set one. */"," headers?: Record<string, string>;"," /** string \xB7 URLSearchParams (\u2192 application/x-www-form-urlencoded) \xB7 FormData (\u2192 multipart/form-data) */"," body?: string | URLSearchParams | FormData;","}): Promise<{"," status: number;"," statusText: string;"," ok: boolean;"," headers: { get(name: string): string | null };"," json(): Promise<unknown>;"," text(): Promise<string>;","}>;","```"].join(`
2
- `),c=["Example - list the paid invoices of a billing API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const ep = endpoints.find((e) => e.method === 'GET' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: items[0].name, path: ep.path, method: ep.method });","const url = new URL((info.servers?.[0]?.url ?? '') + ep.path);","// Every name below comes from `info.endpoint.parameters` - read them first, never guess them.","url.searchParams.set('filter', 'status:paid');","url.searchParams.set('sort', '-createdTime');","url.searchParams.set('limit', '100');","try {"," const res = await fetch(url, { method: ep.method });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"].join(`
3
- `);function m(a){const t=new Map;for(const{name:e,version:r}of a){if(!e)continue;const n=t.get(e)??[];r&&n.push(r),t.set(e,n)}return[...t.entries()].map(([e,r])=>r.length>1?`${e} (${r.map(n=>`v${n}`).join(", ")})`:e).join(", ")}const h={id:i,purpose:"Call the documented APIs over HTTP",isActive:o,annotations:{readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},renderSection(a){const t=m(s(a));return["## `fetch` \u2014 call the documented APIs","",l,"","Always call `getEndpointInfo` before `fetch` for the exact URL, required parameters, and body shape. Put filtering, sorting, and paging in the query parameters, and keep sandbox JS for what the endpoint cannot express. Never guess.","",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${t}`,"",c].join(`
4
- `)}};export{l as FETCH_DECLARATION,h as fetchCapability};
1
+ import{getCallableApis as n,isFetchCapable as o}from"../../../gateway-mcp/callable-apis.js";import{FETCH_TOOL_NAME as i}from"../../constants.js";const c=["```ts","/**"," * Call a documented API. Only the callable APIs' documented hosts are reachable."," * Responses cap at 1 MiB and redirects are not followed."," */","declare function fetch(url: string | URL, init?: {"," method?: string;"," /** `content-type` is set automatically for URLSearchParams/FormData unless you set one. */"," headers?: Record<string, string>;"," /** string \xB7 URLSearchParams (\u2192 application/x-www-form-urlencoded) \xB7 FormData (\u2192 multipart/form-data) */"," body?: string | URLSearchParams | FormData;"," /** Security scheme name (from the operation's `security` or `getSecuritySchemes`) whose credential to send. Omit to let the server choose. */"," securityScheme?: string;","}): Promise<{"," status: number;"," statusText: string;"," ok: boolean;"," headers: { get(name: string): string | null };"," json(): Promise<unknown>;"," text(): Promise<string>;","}>;","```"].join(`
2
+ `),l=["Example - list the paid invoices of a billing API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const [api] = items;",`if (!api) return { error: 'no API matches "billing"' };`,"const { endpoints } = await tools.getEndpoints({ name: api.name });","const ep = endpoints.find((e) => e.method === 'GET' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: api.name, path: ep.path, method: ep.method });","const url = new URL((info.servers?.[0]?.url ?? '') + ep.path);","// Every name below comes from `info.endpoint.parameters` - read them first, never guess them.","url.searchParams.set('filter', 'status:paid');","url.searchParams.set('sort', '-createdTime');","url.searchParams.set('limit', '100');","try {"," const res = await fetch(url, { method: ep.method });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"].join(`
3
+ `);function m(s){const t=new Map;for(const{name:e,version:r}of s){if(!e)continue;const a=t.get(e)??[];r&&a.push(r),t.set(e,a)}return[...t.entries()].map(([e,r])=>r.length>1?`${e} (${r.map(a=>`v${a}`).join(", ")})`:e).join(", ")}const p={id:i,purpose:"Call the documented APIs over HTTP",isActive:o,annotations:{readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},renderSection(s){const t=m(n(s));return["## `fetch` \u2014 call the documented APIs","",c,"","Always call `getEndpointInfo` before `fetch` for the exact URL, required parameters, and body shape. Put filtering, sorting, and paging in the query parameters, and keep sandbox JS for what the endpoint cannot express. Never guess.","","When an operation accepts more than one security scheme, pass `securityScheme` with the scheme name the user holds a credential for; without it the server picks one, and a mismatched credential fails upstream.","",`Callable APIs (their documented hosts are reachable via \`fetch\`): ${t}`,"",l].join(`
4
+ `)}};export{c as FETCH_DECLARATION,p as fetchCapability};
@@ -4,8 +4,10 @@ type CodeExecutedEvent = {
4
4
  fetchCount: number;
5
5
  outcome: 'ok' | 'error';
6
6
  durationMs: number;
7
+ client?: string;
8
+ clientVersion?: string;
7
9
  };
8
10
  /** Audit record for one sandbox run. Carries the code fingerprint, never the code. */
9
- export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, }: CodeExecutedEvent): void;
11
+ export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, client, clientVersion, }: CodeExecutedEvent): void;
10
12
  export {};
11
13
  //# sourceMappingURL=code-execution-telemetry.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as c}from"../../../telemetry/index.js";import{logger as s}from"../../../tools/notifiers/logger.js";import{McpServerType as f}from"../constants.js";import{serverAttributes as g}from"../utils/telemetry-attributes.js";function p({audit:e,fetchCount:o,outcome:r,durationMs:t}){try{c.sendMcpCodeExecutedMessage([{...g(f.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:o,outcome:r,flags:e.flags,duration_ms:t}])}catch{}s.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${r} codeLength=${e.length} fetchCount=${o}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${t}`)}export{p as reportCodeExecuted};
1
+ import{telemetry as f}from"../../../telemetry/index.js";import{logger as g}from"../../../tools/notifiers/logger.js";import{McpServerType as l}from"../constants.js";import{serverAttributes as n}from"../utils/telemetry-attributes.js";function $({audit:e,fetchCount:o,outcome:r,durationMs:t,client:c,clientVersion:s}){try{f.sendMcpCodeExecutedMessage([{...n(l.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:o,outcome:r,flags:e.flags,duration_ms:t,client:c,client_version:s}])}catch{}g.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${r} codeLength=${e.length} fetchCount=${o}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${t}`)}export{$ as reportCodeExecuted};
@@ -1 +1 @@
1
- import{executeMcpTool as i}from"../workers/execute-mcp-tool.js";async function p(t,r,n,c){const e=await i({toolName:t,args:r,context:n,extra:c}),o=u(e);if(e.isError)throw new Error(o);return s(o)}function u(t){return t.content.filter(r=>r.type==="text").map(r=>r.text).join("")}function s(t){try{return JSON.parse(t)}catch{return t}}export{p as invokeTool};
1
+ import{executeMcpTool as c}from"../workers/execute-mcp-tool.js";async function a(t,r,o,u){const e=await c({toolName:t,args:r,context:o,extra:u});if(e.isError)throw new Error(n(e));return e.structuredContent!==void 0?e.structuredContent:i(n(e))}function n(t){return t.content.filter(r=>r.type==="text").map(r=>r.text).join("")}function i(t){try{return JSON.parse(t)}catch{return t}}export{a as invokeTool};
@@ -2,6 +2,6 @@ import{buildToolList as i}from"./build-tool-list.js";const l=2048,c="Both `execu
2
2
  `):e}function h(e,t=[]){const o=["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The extra globals are `tools`, `fetch`, `URL`, `URLSearchParams`, and `FormData` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs.","2. Call `describe-tools` with those names to get their exact TypeScript signatures - inputs, result shapes, and a worked example. NEVER call `execute` with guessed method names, parameter names, enum values, or result field names: read fields off the declared return types, not from assumptions.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs."].join(`
3
3
  `);return a(o,t)}const d=["Get the exact TypeScript signatures of the sandbox tools available to `execute`.","Analyze the user request first, then pass `tools` with only the tool names the request needs (every name is listed in this input schema / description); omit `tools` only when you cannot tell which tools apply.","Always call this before your first `execute` and never guess signatures. Request every tool the task may need in ONE call instead of calling this repeatedly."].join(`
4
4
  `);function u(e,t=[]){const o=["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through two tools:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with only the tool names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",...e?["The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs."]:[]].join(`
5
- `);return a(o,t)}const p=["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: items[0].name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"].join(`
5
+ `);return a(o,t)}const p=["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const [api] = items;",`if (!api) return { error: 'no API matches "billing"' };`,"const { endpoints } = await tools.getEndpoints({ name: api.name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: api.name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"].join(`
6
6
  `),m=["Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.","Payload samples live on a media type object (`requestBody.content[mediaType]`, `responses[code].content[mediaType]`): `.example` holds a single value, `.examples[name].value` a named map, and some descriptions only set `.schema.example`. Read each before concluding a sample is absent."].join(`
7
7
  `);export{d as DESCRIBE_TOOLS_DESCRIPTION,l as DESCRIPTION_CHAR_LIMIT,c as EXECUTE_ARGS_NOTE,p as PLAIN_EXECUTE_EXAMPLE,m as USAGE_NOTES,u as buildCodeModeInstructions,h as buildExecuteDescription};
@@ -2,5 +2,5 @@
2
2
  * `fetch`: not a polyfill but a bridge. It takes the host rail off the global object so guest
3
3
  * code cannot reach it directly, encodes the body, and hands the host a plain request.
4
4
  */
5
- export declare const FETCH_SHIM = "\n const hostFetch = globalThis.__fetchBridge.fetch;\n delete globalThis.__fetchBridge;\n // RFC 7578: a field name travels with its quote and line breaks escaped, so a name cannot close its own header and open a part the caller did not write.\n const escapeFieldName = (name) =>\n String(name).replace(\n /[\"\\r\\n]/g,\n (char) => '%' + char.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'),\n );\n globalThis.fetch = (url, init = {}) => {\n let body;\n let autoContentType;\n if (init.body instanceof URLSearchParams) {\n body = init.body.toString();\n autoContentType = 'application/x-www-form-urlencoded';\n } else if (init.body instanceof FormData) {\n const boundary = '----FormBoundary' + Math.random().toString(36).slice(2);\n body = init.body._fields\n .map(([k, v]) =>\n '--' + boundary + '\\r\\nContent-Disposition: form-data; name=\"' + escapeFieldName(k) + '\"\\r\\n\\r\\n' + v,\n )\n .join('\\r\\n') + '\\r\\n--' + boundary + '--';\n autoContentType = 'multipart/form-data; boundary=' + boundary;\n } else if (init.body != null && typeof init.body !== 'string') {\n throw new TypeError('fetch body must be a string, URLSearchParams, or FormData');\n } else {\n body = init.body ?? undefined;\n }\n const callerHeaders = init.headers;\n const hasContentType = callerHeaders != null && Object.keys(callerHeaders).some(\n (k) => k.toLowerCase() === 'content-type',\n );\n const headers = autoContentType && !hasContentType\n ? Object.assign({ 'content-type': autoContentType }, callerHeaders)\n : callerHeaders;\n return hostFetch({ url: String(url), method: init.method, headers, body })\n .then((res) => {\n const resHeaders = res.headers || {};\n return {\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n headers: {\n get: (name) => {\n const value = resHeaders[String(name).toLowerCase()];\n return value === undefined ? null : value;\n },\n },\n json: () => Promise.resolve(JSON.parse(res.bodyText)),\n text: () => Promise.resolve(res.bodyText),\n };\n });\n };\n";
5
+ export declare const FETCH_SHIM = "\n const hostFetch = globalThis.__fetchBridge.fetch;\n delete globalThis.__fetchBridge;\n // RFC 7578: a field name travels with its quote and line breaks escaped, so a name cannot close its own header and open a part the caller did not write.\n const escapeFieldName = (name) =>\n String(name).replace(\n /[\"\\r\\n]/g,\n (char) => '%' + char.charCodeAt(0).toString(16).toUpperCase().padStart(2, '0'),\n );\n globalThis.fetch = (url, init = {}) => {\n let body;\n let autoContentType;\n if (init.body instanceof URLSearchParams) {\n body = init.body.toString();\n autoContentType = 'application/x-www-form-urlencoded';\n } else if (init.body instanceof FormData) {\n const boundary = '----FormBoundary' + Math.random().toString(36).slice(2);\n body = init.body._fields\n .map(([k, v]) =>\n '--' + boundary + '\\r\\nContent-Disposition: form-data; name=\"' + escapeFieldName(k) + '\"\\r\\n\\r\\n' + v,\n )\n .join('\\r\\n') + '\\r\\n--' + boundary + '--';\n autoContentType = 'multipart/form-data; boundary=' + boundary;\n } else if (init.body != null && typeof init.body !== 'string') {\n throw new TypeError('fetch body must be a string, URLSearchParams, or FormData');\n } else {\n body = init.body ?? undefined;\n }\n const callerHeaders = init.headers;\n const hasContentType = callerHeaders != null && Object.keys(callerHeaders).some(\n (k) => k.toLowerCase() === 'content-type',\n );\n const headers = autoContentType && !hasContentType\n ? Object.assign({ 'content-type': autoContentType }, callerHeaders)\n : callerHeaders;\n return hostFetch({\n url: String(url),\n method: init.method,\n headers,\n body,\n securityScheme: init.securityScheme,\n })\n .then((res) => {\n const resHeaders = res.headers || {};\n return {\n status: res.status,\n statusText: res.statusText,\n ok: res.ok,\n headers: {\n get: (name) => {\n const value = resHeaders[String(name).toLowerCase()];\n return value === undefined ? null : value;\n },\n },\n json: () => Promise.resolve(JSON.parse(res.bodyText)),\n text: () => Promise.resolve(res.bodyText),\n };\n });\n };\n";
6
6
  //# sourceMappingURL=fetch-shim.d.ts.map
@@ -1,4 +1,4 @@
1
- import{FETCH_BRIDGE_FUNCTION_NAME as t,FETCH_BRIDGE_GLOBAL_NAME as e}from"../../constants.js";const n=`
1
+ import{FETCH_BRIDGE_FUNCTION_NAME as t,FETCH_BRIDGE_GLOBAL_NAME as e}from"../../constants.js";const a=`
2
2
  const hostFetch = globalThis.${e}.${t};
3
3
  delete globalThis.${e};
4
4
  // RFC 7578: a field name travels with its quote and line breaks escaped, so a name cannot close its own header and open a part the caller did not write.
@@ -33,7 +33,13 @@ import{FETCH_BRIDGE_FUNCTION_NAME as t,FETCH_BRIDGE_GLOBAL_NAME as e}from"../../
33
33
  const headers = autoContentType && !hasContentType
34
34
  ? Object.assign({ 'content-type': autoContentType }, callerHeaders)
35
35
  : callerHeaders;
36
- return hostFetch({ url: String(url), method: init.method, headers, body })
36
+ return hostFetch({
37
+ url: String(url),
38
+ method: init.method,
39
+ headers,
40
+ body,
41
+ securityScheme: init.securityScheme,
42
+ })
37
43
  .then((res) => {
38
44
  const resHeaders = res.headers || {};
39
45
  return {
@@ -51,4 +57,4 @@ import{FETCH_BRIDGE_FUNCTION_NAME as t,FETCH_BRIDGE_GLOBAL_NAME as e}from"../../
51
57
  };
52
58
  });
53
59
  };
54
- `;export{n as FETCH_SHIM};
60
+ `;export{a as FETCH_SHIM};
@@ -1 +1 @@
1
- import{mcpToolHandlers as l}from"../../../../../client/mcp-tool-handlers-entry.js";import{runInSandbox as p}from"../../../../sandbox/sandbox.js";import{isMcpToolAvailable as h}from"../../workers/execute-mcp-tool.js";import{buildExecuteHostFetch as b,isFetchCapable as E}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as T}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as C,EXECUTE_TOOL_NAME as O}from"../constants.js";import{sanitizeToolName as w}from"../build-tool-type-declarations.js";import{invokeTool as A}from"../invoke-tool.js";import{createSandboxSetup as x}from"../sandbox/create-sandbox-setup.js";import{auditCode as y}from"../code-audit.js";import{reportCodeExecuted as M}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as N}from"../code-execution-audit.js";const v=async(e,t,r)=>{const o=await F(t,r),n=[],i=E(t)?await b(t,a=>n.push(a)):void 0;let c=0;const u=i?a=>(c+=1,i(a)):void 0,d=y(e.code);N({audit:d,code:e.code,description:e.description,sessionHandle:e.sessionHandle,toolNames:Object.keys(o),fetchBudget:t.gatewayFetchBudgetPerExec,fetchCapable:i!==void 0});const m=Date.now(),{result:f,error:s}=await p(e.code,{setupContext:x(o,u)});return M({audit:d,fetchCount:c,outcome:s===void 0?"ok":"error",durationMs:Date.now()-m}),T({content:[{type:"text",text:JSON.stringify({result:f,error:s})}],isError:s!==void 0},n)};async function F(e,t){const r={};for(const o of Object.keys(l))C.has(o)||!await h({toolName:o,context:e}).catch(()=>!1)||(r[w(o)]=i=>A(o,i,e,t));return r}var J={[O]:v};export{J as default};
1
+ import{runInSandbox as p}from"../../../../sandbox/sandbox.js";import{isMcpToolAvailable as h}from"../../workers/execute-mcp-tool.js";import{importMcpToolHandlers as E}from"../../workers/import-mcp-tool-handlers.js";import{isFetchCapable as b}from"../../gateway-mcp/callable-apis.js";import{buildExecuteHostFetch as w}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as C}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as O,EXECUTE_TOOL_NAME as y}from"../constants.js";import{sanitizeToolName as T}from"../build-tool-type-declarations.js";import{invokeTool as M}from"../invoke-tool.js";import{createSandboxSetup as A}from"../sandbox/create-sandbox-setup.js";import{auditCode as F}from"../code-audit.js";import{reportCodeExecuted as S}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as _}from"../code-execution-audit.js";const x=async(t,o,d)=>{const r=new Set,a=await N(o,d,r),n=[],e=b(o)?await w(o,l=>n.push(l)):void 0;let c=0;const u=e?l=>(c+=1,e(l)):void 0,i=F(t.code);_({audit:i,code:t.code,description:t.description,sessionHandle:t.sessionHandle,toolNames:Object.keys(a),fetchBudget:o.gatewayFetchBudgetPerExec,fetchCapable:e!==void 0});const m=Date.now(),{result:f,error:s}=await p(t.code,{setupContext:A(a,u)});return S({audit:i,fetchCount:c,outcome:s===void 0?"ok":"error",durationMs:Date.now()-m,client:o.client,clientVersion:o.clientVersion}),C({content:[{type:"text",text:JSON.stringify({result:f,error:s})}],isError:s!==void 0,...s!==void 0&&r.has(s)?{errorClass:"tool_error"}:{}},n)};async function N(t,o,d){const r=Object.keys(await E()).filter(e=>!O.has(e)),a=await Promise.all(r.map(e=>h({toolName:e,context:t}).catch(()=>!1))),n={};return r.forEach((e,c)=>{a[c]&&(n[T(e)]=u=>M(e,u,t,o).catch(i=>{throw i instanceof Error&&d.add(i.message),i}))}),n}var J={[y]:x};export{J as default};
@@ -1,2 +1,2 @@
1
- import{MANAGE_API_CREDENTIALS_TOOL_NAME as v}from"../../constants.js";import{buildUpstreamCredentialFallback as y,buildUpstreamCredentialInputRequired as b,schemeLabelOf as P}from"../../gateway-mcp/elicitation.js";import{getCallableApis as m,isFetchCapable as S}from"../../gateway-mcp/fetch-capability.js";import{secretStore as I}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as w,resolveSecretSubject as k}from"../../gateway-mcp/subject.js";import{resolveUpstreamApiAuth as j}from"../../gateway-mcp/upstream-auth-scheme.js";function H(e){return!!e.elicitationEnabled&&S(e)}function U(e){const t=m(e).map(n=>n.relativePath);return{name:v,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
1
+ import{MANAGE_API_CREDENTIALS_TOOL_NAME as v}from"../../constants.js";import{buildUpstreamCredentialFallback as y,buildUpstreamCredentialInputRequired as b,schemeLabelOf as P}from"../../gateway-mcp/elicitation.js";import{getCallableApis as m,isFetchCapable as S}from"../../gateway-mcp/callable-apis.js";import{secretStore as I}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as w,resolveSecretSubject as k}from"../../gateway-mcp/subject.js";import{resolveUpstreamApiAuth as j}from"../../gateway-mcp/upstream-auth-scheme.js";function H(e){return!!e.elicitationEnabled&&S(e)}function U(e){const t=m(e).map(n=>n.relativePath);return{name:v,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
2
2
  `),annotations:{readOnlyHint:!1,openWorldHint:!1},schema:{type:"object",required:["api"],additionalProperties:!1,properties:{api:{type:"string",description:`The API to manage credentials for.${t.length>0?` One of: ${t.join(", ")}.`:""}`,minLength:1,...t.length>0?{enum:t}:{}},scheme:{type:"string",description:"Name of the security scheme to manage the credential for, as named in the API description (a tool result that reports a rejected credential names it). Omit it to let the link cover every scheme the API accepts.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required while the caller is anonymous, so the credentials are stored against the same subject the API calls use.",minLength:1}}}}}function _(e,c){return async t=>{const n=k(e.user,typeof t.sessionHandle=="string"?t.sessionHandle:void 0);if(n.kind==="invalid")return l(n.message);if(n.kind==="anonymous")return l(w);const{subject:u}=n,h=typeof t.api=="string"?t.api:"",s=m(e).find(o=>o.relativePath===h||o.name===h);if(!s){const o=m(e).map(g=>g.relativePath).join(", ");return l(`Unknown api "${h}". Credentials can only be managed for the APIs this server can call: ${o||"none"}.`)}const r=await j(e,s.relativePath),a=typeof t.scheme=="string"?t.scheme:void 0,A=Object.keys(r.schemes);if(a&&!r.schemes[a])return l(`Unknown scheme "${a}" for api "${s.relativePath}". The security schemes this server can store credentials for are: ${A.join(", ")}.`);const i=a??r.defaultScheme,p=P(r.schemes,i),d=await c.getKv(),f={subject:u,baseUrl:e.baseUrl??"",target:{api:s.relativePath,name:s.name,scheme:i,...p?{schemeLabel:p}:{}},auth:r.schemes[i],apiAuth:r,kv:d,hasExistingSecret:await I.hasSecret(d,u,s.relativePath,i),reason:{kind:"requested"}};return c.getClientCapabilities()?.elicitation?.url?await b(f):{content:[{type:"text",text:await y(f)}],isError:!1}}}function l(e){return{content:[{type:"text",text:e}],isError:!0}}export{H as isManageApiCredentialsToolAvailable,_ as manageApiCredentials,U as manageApiCredentialsSchema};
@@ -4,6 +4,7 @@ export type SandboxFetchRequest = {
4
4
  method?: string;
5
5
  headers?: Record<string, string>;
6
6
  body?: string;
7
+ securityScheme?: string;
7
8
  };
8
9
  export type SandboxFetchResponse = {
9
10
  status: number;
@@ -16,4 +16,5 @@ export declare const DEFAULT_DOCS_MCP_SERVER_NAME = "Docs MCP server";
16
16
  export declare const SUPPORTED_MCP_SCOPES: readonly ['openid', 'profile', 'email', 'offline_access'];
17
17
  export declare const CREATE_ANONYMOUS_SESSION_TOOL_NAME = "createAnonymousSession";
18
18
  export declare const MANAGE_API_CREDENTIALS_TOOL_NAME = "manageApiCredentials";
19
+ export declare const CUSTOM_MCP_TOOLS_META_DIR = "custom-mcp-tools-meta";
19
20
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- import{LATEST_PROTOCOL_VERSION as o}from"@modelcontextprotocol/server";const r={Docs:"docs"},E={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},_=o,t=3e4,s=15e3,O=3,n="Docs MCP server",S=["openid","profile","email","offline_access"],c="createAnonymousSession",A="manageApiCredentials";export{c as CREATE_ANONYMOUS_SESSION_TOOL_NAME,t as DEFAULT_CONNECTION_TIMEOUT_MS,n as DEFAULT_DOCS_MCP_SERVER_NAME,A as MANAGE_API_CREDENTIALS_TOOL_NAME,O as MAX_DOCUMENTS_PER_CATEGORY,_ as MCP_PROTOCOL_VERSION,E as McpErrorCodes,r as McpServerType,s as SSE_KEEPALIVE_INTERVAL_MS,S as SUPPORTED_MCP_SCOPES};
1
+ import{LATEST_PROTOCOL_VERSION as o}from"@modelcontextprotocol/server";const r={Docs:"docs"},t={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},E=o,_=3e4,s=15e3,O=3,n="Docs MCP server",S=["openid","profile","email","offline_access"],c="createAnonymousSession",T="manageApiCredentials",M="custom-mcp-tools-meta";export{c as CREATE_ANONYMOUS_SESSION_TOOL_NAME,M as CUSTOM_MCP_TOOLS_META_DIR,_ as DEFAULT_CONNECTION_TIMEOUT_MS,n as DEFAULT_DOCS_MCP_SERVER_NAME,T as MANAGE_API_CREDENTIALS_TOOL_NAME,O as MAX_DOCUMENTS_PER_CATEGORY,E as MCP_PROTOCOL_VERSION,t as McpErrorCodes,r as McpServerType,s as SSE_KEEPALIVE_INTERVAL_MS,S as SUPPORTED_MCP_SCOPES};
@@ -0,0 +1,13 @@
1
+ import type { ToolDefinitionValidationResult } from '../types.js';
2
+ export type ExtractToolDefinitionParams = {
3
+ toolName: string;
4
+ absoluteSourcePath: string;
5
+ contentDir: string;
6
+ serverOutDir: string;
7
+ };
8
+ /**
9
+ * Reads a tool's schema by bundling the file with esbuild and importing the bundle
10
+ * once at build time; the source file itself only runs in the worker pool.
11
+ */
12
+ export declare function extractToolDefinition(params: ExtractToolDefinitionParams): Promise<ToolDefinitionValidationResult>;
13
+ //# sourceMappingURL=extract-tool-definition.d.ts.map
@@ -0,0 +1 @@
1
+ import{existsSync as p}from"node:fs";import{mkdir as b,rm as g,writeFile as w}from"node:fs/promises";import{dirname as y,join as f}from"node:path";import{pathToFileURL as T}from"node:url";import{build as v}from"esbuild";import{shaHex as x}from"../../../utils/crypto/sha-hex.js";import{CUSTOM_MCP_TOOLS_META_DIR as $}from"../constants.js";import{validateToolDefinition as D}from"./validate-tool-definition.js";const m=new Map;async function C(t){const{toolName:n,absoluteSourcePath:a,contentDir:d,serverOutDir:h}=t;let i;try{const e=f(d,"tsconfig.json");i=(await v({entryPoints:[a],write:!1,bundle:!0,format:"esm",platform:"node",mainFields:["module","main"],logLevel:"silent",...p(e)?{tsconfig:e}:{}})).outputFiles[0].text}catch(e){return{ok:!1,errors:[`the file cannot be bundled: ${u(e)}`]}}const s=x(i),l=`${n}:${a}:${s}`,c=m.get(l);if(c)return c;const o=f(h,$,`${s.slice(0,16)}.mjs`);let r;try{await b(y(o),{recursive:!0}),await w(o,i);const e=await import(T(o).href);r=D(n,e.default)}catch(e){r={ok:!1,errors:[`the file failed to load: ${u(e)}. Tool files must not have module-level side effects.`]}}finally{await g(o,{force:!0}).catch(()=>{})}return m.set(l,r),r}function u(t){return t instanceof Error?t.message:String(t)}export{C as extractToolDefinition};
@@ -0,0 +1,6 @@
1
+ import type { LifecycleContext, ProcessContentActions } from '../../../types';
2
+ import type { CustomMcpToolsState } from '../types.js';
3
+ /** Registers every file in an `@mcp` folder as one MCP tool, named after the file. */
4
+ export declare function scanCustomMcpTools(actions: ProcessContentActions, context: LifecycleContext, state: CustomMcpToolsState): Promise<number>;
5
+ export declare function resetCustomMcpTools(actions: Pick<ProcessContentActions, 'removeMcpTools'>, state: CustomMcpToolsState): void;
6
+ //# sourceMappingURL=scan-custom-tools.d.ts.map
@@ -0,0 +1 @@
1
+ import{basename as f,join as d}from"node:path";import{envConfig as p}from"../../../config/env-config.js";import{reporter as i}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as E}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as O}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as h}from"./extract-tool-definition.js";const T=/(^|\/)@mcp\/.*\.(ts|js)$/,M=/^[a-zA-Z0-9_-]{1,64}$/,_=new Set([...E,...O]);async function S(o,r,a){if(!p.REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED)return 0;C(o,a);const u=new Set(o.getMcpTools().map(n=>n.name)),l=new Map;for(const n of r.fs.scan(T)){if(n.isVirtual||n.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=n,e=f(t).replace(/\.(ts|js)$/,"");if(!M.test(e)){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is derived from the file name and may only contain letters, numbers, hyphens, and underscores (max 64 characters). Rename the file.`);continue}const c=l.get(e);if(c){await i.panicOnBuildContentError(`Duplicate MCP tool name "${e}": defined by both "${c}" and "${t}". Tool names are file names, so each file name must be unique across @mcp folders.`);continue}if(_.has(e)||u.has(e)){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is already used by a built-in MCP tool. Rename the file.`);continue}l.set(e,t);const m=d(o.contentDir,t),s=await h({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!s.ok){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${s.errors.join(" ")}`);continue}o.addMcpTools(m,[s.schema]),a.registeredToolNames.push(e)}return a.registeredToolNames.length}function C(o,r){o.removeMcpTools(r.registeredToolNames),r.registeredToolNames=[]}export{C as resetCustomMcpTools,S as scanCustomMcpTools};
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinitionValidationResult, ToolFileDefaultExport } from '../types.js';
2
+ export declare function validateToolDefinition(toolName: string, moduleDefault: ToolFileDefaultExport): ToolDefinitionValidationResult;
3
+ //# sourceMappingURL=validate-tool-definition.d.ts.map
@@ -0,0 +1 @@
1
+ import{isPlainObject as s}from"../../../../utils/guards/is-plain-object.js";function f(c,a){if(!s(a))return{ok:!1,errors:["the default export must be an object with `description` and `execute` properties. Move shared helper code outside the `@mcp` folder."]};const{description:i,inputSchema:t,outputSchema:n,annotations:o,isAvailable:u,execute:p}=a,e=[];return(typeof i!="string"||i.trim()==="")&&e.push("`description` must be a non-empty string."),typeof p!="function"&&e.push("`execute` must be a function."),t!==void 0&&(s(t)?t.type!==void 0&&t.type!=="object"&&e.push('`inputSchema.type` must be "object" because MCP tool arguments are named.'):e.push("`inputSchema` must be a JSON Schema object.")),n!==void 0&&!s(n)&&e.push("`outputSchema` must be a JSON Schema object."),o!==void 0&&!s(o)&&e.push("`annotations` must be an object."),u!==void 0&&typeof u!="function"&&e.push("`isAvailable` must be a function."),e.length>0||typeof i!="string"?{ok:!1,errors:e}:{ok:!0,schema:{name:c,description:i,schema:{type:"object",...t??{properties:{}}},...n?{outputSchema:n}:{},...o?{annotations:o}:{},hasAvailabilityGate:typeof u=="function"}}}export{f as validateToolDefinition};
@@ -6,5 +6,7 @@ export declare function getDefaultToolSchemas(config: {
6
6
  rbac?: Record<string, unknown>;
7
7
  hasGraphqlApis?: boolean;
8
8
  elicitationEnabled?: boolean;
9
+ hasCallableApis?: boolean;
9
10
  }): McpToolSchema[];
11
+ export declare const ALL_DEFAULT_TOOL_NAMES: ReadonlySet<string>;
10
12
  //# sourceMappingURL=tool-schemas.d.ts.map
@@ -1 +1 @@
1
- import{shouldHandleMcpAuth as d}from"../../../utils/rbac/should-handle-mcp-auth.js";import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as m}from"../constants.js";import{GRAPHQL_TYPE_KINDS as o,GRAPHQL_LIST_SCOPES as h}from"./tools/graphql/constants.js";import{OPERATION_METHODS as p}from"./tools/openapi/constants.js";const i={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},y={codemodeType:"OpenApiDocument"},f={codemodeType:"OpenApiOperation & { path: string; method: string }"},g={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"Matches part of an API name, or of a description when no name matches",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it",minLength:1},version:{type:"string",description:"API version",nullable:!0},filePath:{type:"string",description:"API definition file path",nullable:!0}}},b={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p.map(e=>e.toUpperCase()),...p],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0},filePath:{type:"string",description:"API definition file path",nullable:!0}}},v={type:"object",required:[],additionalProperties:!1,properties:{}},S={type:"object",required:[],additionalProperties:!1,properties:{}};function I(e){const t=[{name:"list-apis",title:"List APIs",description:"Lists available APIs with their context and purpose",schema:g,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:i,version:i,servers:r,filePath:{type:"string",description:"API definition file path"}}}},...n}}},{name:"get-endpoints",title:"Get endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:i,description:i,security:s}}}}}},{name:"get-endpoint-info",title:"Get endpoint info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:b,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:f,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",title:"Get security schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:i,version:i,securitySchemes:l,security:s}}},{name:"get-full-api-description",title:"Get full API description",description:"Get the complete OpenAPI description",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:y}}},G(e.products,e.locales)];return d(e.requiresLogin,e.rbac)&&t.push({name:"whoami",title:"Who am I",description:"Get information about the currently authenticated user",schema:v,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.hasGraphqlApis&&t.push(...q()),e.elicitationEnabled&&t.push({name:m,title:"Create anonymous session",description:"Create an anonymous session handle for storing upstream API credentials. Pass the returned sessionHandle to execute when an API needs credentials and the caller is not signed in. Treat it as a secret and reuse it across calls.",schema:S,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["sessionHandle"],properties:{sessionHandle:{type:"string"}}}}),t}const H={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},P={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:'Optional: return only a single category of schema members. With scope "fields", restricts to the fields of that parent category ("objects", "interfaces", or "inputs" only).',enum:[...o],nullable:!0},scope:{type:"string",description:'Optional: what each list item is. "members" (default) lists top-level types and operations. "fields" flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions \u2014 combine with `filter` to search nested fields anywhere in the schema.',enum:[...h],nullable:!0},filter:{type:"string",description:'Optional: only members whose name or description contains this substring, case-insensitive (e.g. "custom tags")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},A={type:"object",required:["name","type"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},L={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function q(){return[{name:"list-graphql-apis",title:"List GraphQL APIs",description:"Lists available GraphQL schemas with their context and purpose",schema:H,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:i}}},...n}}},{name:"get-graphql-type-list",title:"Get GraphQL type list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (case-insensitive substring of the member name or description, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema. To search nested fields \u2014 not just type names \u2014 set scope "fields": it flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions, so `filter` finds things like an input field whose docstring mentions your keyword.',schema:P,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:{type:"string"},items:{type:"array",items:{type:"object",properties:{kind:{type:"string",enum:o},name:{type:"string"},description:i,type:{type:"string"},args:{type:"string"},directives:{type:"string"}}}},...n}}},{name:"get-graphql-type",title:"Get GraphQL type",description:'Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Without includeReferencedTypes, the SDL is followed by a one-level manifest of every directly referenced type\'s field names (e.g. "input ActionOperationInput { addTags, removeTags }"), so you can see what nested types contain before fetching them. Set includeReferencedTypes to instead pull in the full SDL of every type it references transitively \u2014 the whole structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.',schema:A,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",title:"Get GraphQL schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:L,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function G(e,t){const c=e&&e.length>0,u=t&&t.length>0;return{name:"search",title:"Search documentation",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...c?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...u?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:t,nullable:!0}}:{}}},annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{I as getDefaultToolSchemas};
1
+ import{shouldHandleMcpAuth as d}from"../../../utils/rbac/should-handle-mcp-auth.js";import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as m}from"../constants.js";import{GRAPHQL_TYPE_KINDS as o,GRAPHQL_LIST_SCOPES as h}from"./tools/graphql/constants.js";import{OPERATION_METHODS as p}from"./tools/openapi/constants.js";const i={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},y={codemodeType:"OpenApiDocument"},f={codemodeType:"OpenApiOperation & { path: string; method: string }"},g={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"Matches part of an API name, or of a description when no name matches",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it",minLength:1},version:{type:"string",description:"API version",nullable:!0},filePath:{type:"string",description:"API definition file path",nullable:!0}}},b={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name, or a unique part of it",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p.map(e=>e.toUpperCase()),...p],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0},filePath:{type:"string",description:"API definition file path",nullable:!0}}},S={type:"object",required:[],additionalProperties:!1,properties:{}},v={type:"object",required:[],additionalProperties:!1,properties:{}};function H(e){const t=[{name:"list-apis",title:"List APIs",description:"Lists the APIs documented in this project",schema:g,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:i,version:i,servers:r,filePath:{type:"string",description:"API definition file path"},...e.hasCallableApis?{callable:{type:"boolean",description:"true = the documented hosts of this API are reachable via `fetch`; false = documentation only"}}:{}}}},...n}}},{name:"get-endpoints",title:"Get endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:i,description:i,security:s}}}}}},{name:"get-endpoint-info",title:"Get endpoint info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:b,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:f,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",title:"Get security schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:i,version:i,securitySchemes:l,security:s}}},{name:"get-full-api-description",title:"Get full API description",description:"Get the complete OpenAPI description",schema:a,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:y}}},T(e.products,e.locales)];return d(e.requiresLogin,e.rbac)&&t.push({name:"whoami",title:"Who am I",description:"Get information about the currently authenticated user",schema:S,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.hasGraphqlApis&&t.push(...O()),e.elicitationEnabled&&t.push({name:m,title:"Create anonymous session",description:"Create an anonymous session handle for storing upstream API credentials. Pass the returned sessionHandle to execute when an API needs credentials and the caller is not signed in. Treat it as a secret and reuse it across calls.",schema:v,annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"object",required:["sessionHandle"],properties:{sessionHandle:{type:"string"}}}}),t}const A={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},P={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:'Optional: return only a single category of schema members. With scope "fields", restricts to the fields of that parent category ("objects", "interfaces", or "inputs" only).',enum:[...o],nullable:!0},scope:{type:"string",description:'Optional: what each list item is. "members" (default) lists top-level types and operations. "fields" flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions \u2014 combine with `filter` to search nested fields anywhere in the schema.',enum:[...h],nullable:!0},filter:{type:"string",description:'Optional: only members whose name or description contains this substring, case-insensitive (e.g. "custom tags")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},L={type:"object",required:["name","type"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},q={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function O(){return[{name:"list-graphql-apis",title:"List GraphQL APIs",description:"Lists available GraphQL schemas with their context and purpose",schema:A,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:i}}},...n}}},{name:"get-graphql-type-list",title:"Get GraphQL type list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (case-insensitive substring of the member name or description, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema. To search nested fields \u2014 not just type names \u2014 set scope "fields": it flattens every field of every object/interface/input type into "ParentType.fieldName" entries with their descriptions, so `filter` finds things like an input field whose docstring mentions your keyword.',schema:P,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:{type:"string"},items:{type:"array",items:{type:"object",properties:{kind:{type:"string",enum:o},name:{type:"string"},description:i,type:{type:"string"},args:{type:"string"},directives:{type:"string"}}}},...n}}},{name:"get-graphql-type",title:"Get GraphQL type",description:'Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Without includeReferencedTypes, the SDL is followed by a one-level manifest of every directly referenced type\'s field names (e.g. "input ActionOperationInput { addTags, removeTags }"), so you can see what nested types contain before fetching them. Set includeReferencedTypes to instead pull in the full SDL of every type it references transitively \u2014 the whole structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.',schema:L,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",title:"Get GraphQL schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:q,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function T(e,t){const c=e&&e.length>0,u=t&&t.length>0;return{name:"search",title:"Search documentation",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...c?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...u?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:t,nullable:!0}}:{}}},annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}const E=new Set(H({requiresLogin:!0,hasGraphqlApis:!0,elicitationEnabled:!0}).map(e=>e.name));export{E as ALL_DEFAULT_TOOL_NAMES,H as getDefaultToolSchemas};
@@ -1,6 +1,6 @@
1
- import{removeTrailingSlash as y,withPathPrefix as g,withoutPathPrefix as E}from"@redocly/theme/core/utils";import{ServerRoutes as L}from"../../../../../../constants/api.js";import{DEFAULT_LOCALE_PLACEHOLDER as S}from"../../../../../../constants/common.js";const w=async(n,t)=>{const{query:e,product:i,locale:l}=n,u=t.config.l10n?.defaultLocale||S,h=JSON.stringify({query:e,product:i,locale:l||u}),f=`${t.baseUrl}${g(L.SEMANTIC_SEARCH)}`,o=t.accessToken?`authorization=${String(t.accessToken).replace(/^Bearer /,"")}`:"";try{const s=await fetch(f,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...o?{Cookie:o}:{}},body:h});if(!s.ok)return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0};const p=await s.json(),d=new Set(t.searchIgnoredRoutes??[]),a=(p||[]).filter(r=>!R(r.url,d));if(a.length===0)return{content:[{type:"text",text:"No results found."}]};const m=r=>{try{return new URL(r,t.baseUrl).toString()}catch{return r}},c=a.map(r=>`### [${r.title}](${m(r.url)})
1
+ import{removeTrailingSlash as g,withPathPrefix as y,withoutPathPrefix as E}from"@redocly/theme/core/utils";import{ServerRoutes as L}from"../../../../../../constants/api.js";import{DEFAULT_LOCALE_PLACEHOLDER as S}from"../../../../../../constants/common.js";const w=async(n,t)=>{const{query:e,product:c,locale:l}=n,u=t.config.l10n?.defaultLocale||S,h=JSON.stringify({query:e,product:c,locale:l||u}),f=`${t.internalBaseUrl||t.baseUrl}${y(L.SEMANTIC_SEARCH)}`,o=t.accessToken?`authorization=${String(t.accessToken).replace(/^Bearer /,"")}`:"";try{const s=await fetch(f,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...o?{Cookie:o}:{}},body:h});if(!s.ok)return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0};const p=await s.json(),d=new Set(t.searchIgnoredRoutes??[]),a=(p||[]).filter(r=>!R(r.url,d));if(a.length===0)return{content:[{type:"text",text:"No results found."}]};const m=r=>{try{return new URL(r,t.baseUrl).toString()}catch{return r}},i=a.map(r=>`### [${r.title}](${m(r.url)})
2
2
 
3
3
  ${r.content}
4
4
  `).join(`
5
5
 
6
- `).trim();return{content:[{type:"text",text:c.length?c:"No results found."}]}}catch{return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0}}};function R(n,t){if(t.size===0)return!1;let e;try{e=new URL(n,"https://relative.invalid").pathname}catch{return!1}e=y(E(e));try{e=decodeURI(e)}catch{}return t.has(e)}var k={search:w};export{k as default};
6
+ `).trim();return{content:[{type:"text",text:i.length?i:"No results found."}]}}catch{return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0}}};function R(n,t){if(t.size===0)return!1;let e;try{e=new URL(n,"https://relative.invalid").pathname}catch{return!1}e=g(E(e));try{e=decodeURI(e)}catch{}return t.has(e)}var v={search:w};export{v as default};
@@ -1 +1 @@
1
- import{loadApiDescription as i}from"./load-api-description.js";import{getEndpointsFromPaths as s}from"./utils.js";const p=async(n,r)=>{let t;try{t=await i(n,r)}catch(o){return{content:[{type:"text",text:o.message}],isError:!0}}const e=s(t);return e.length===0?{content:[{type:"text",text:"No endpoints found"}]}:{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",servers:t.servers||[],endpoints:e},null,2)}]}};var d={"get-endpoints":p};export{d as default};
1
+ import{loadApiDescription as i}from"./load-api-description.js";import{getEndpointsFromPaths as s}from"./utils.js";const p=async(e,r)=>{let t;try{t=await i(e,r)}catch(o){return{content:[{type:"text",text:o.message}],isError:!0}}const n=s(t);return{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",servers:t.servers||[],endpoints:n},null,2)}]}};var d={"get-endpoints":p};export{d as default};
@@ -1 +1 @@
1
- import{filterApiDescriptionsByName as g}from"../../utils/api-name-matching.js";const h=async(l,a)=>{const{filter:i,page:n=1,limit:e=300}=l;let t=Object.values(a.apiDescriptionsMap);i&&(t=g(t,i));const s=(n-1)*e,o=s+e,c=Math.ceil(t.length/e),p=t.length;return t=t.slice(s,o),t.length===0?{content:[{type:"text",text:"No APIs available"}]}:{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:r,fetchEligible:x,...f})=>({filePath:r,...f})),limit:e,total:p,page:n,totalPages:c})}]}};var u={"list-apis":h};export{u as default};
1
+ import{isFetchCapable as d}from"../../../gateway-mcp/callable-apis.js";import{filterApiDescriptionsByName as g}from"../../utils/api-name-matching.js";const h=async(n,i)=>{const{filter:s,page:l=1,limit:e=300}=n,o=d(i);let t=Object.values(i.apiDescriptionsMap);s&&(t=g(t,s));const a=(l-1)*e,c=a+e,p=Math.ceil(t.length/e),r=t.length;return t=t.slice(a,c),{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:f,fetchEligible:m,...u})=>({filePath:f,...u,...o?{callable:m===!0}:{}})),limit:e,total:r,page:l,totalPages:p})}]}};var y={"list-apis":h};export{y as default};
@@ -1 +1 @@
1
- import a from"node:path";import{existsSync as f}from"node:fs";import{readFile as d}from"node:fs/promises";import{replaceFileExtension as h}from"../../../../../plugins/openapi-docs/store-definition-bundles.js";import{PUBLIC_API_DEFINITIONS_FOLDER as u}from"../../../../../constants/common.js";import{filterDataByAccessDeep as l}from"../../../../../utils/rbac.js";import{checkEndpointAndDeleteXMcp as c}from"../../../utils/xmcp-utils.js";import{HTTP_METHODS as y}from"./constants.js";function P(t){return typeof t=="object"&&t!==null&&"responses"in t&&typeof t.responses=="object"}function S(t){const{paths:n={}}=t,e=[];for(const[r,i]of Object.entries(n)){const s=!c(i,"docs");for(const[p,o]of Object.entries(i))y.has(p.toLowerCase())&&(s||!c(o,"docs")||e.push({path:r,method:p.toUpperCase(),summary:o.summary,description:o.description,security:o.security}))}return e}async function T({relativePath:t,outdir:n,user:e,rbac:r={},requiresLogin:i=!1}){const s=a.join(n||"",u,h(t,".json"));if(!f(s))return;const o=await d(s,"utf-8"),m=JSON.parse(o);return l(m,{isAuthenticated:e?.isAuthenticated,email:e?.email,teams:e?.teams},r,i)}export{T as getApiDescriptionFromFs,S as getEndpointsFromPaths,P as isMcpEndpoint};
1
+ import a from"node:path";import{existsSync as f}from"node:fs";import{readFile as d}from"node:fs/promises";import{replaceFileExtension as h}from"../../../../../plugins/api-docs/utils/replace-file-extension.js";import{PUBLIC_API_DEFINITIONS_FOLDER as u}from"../../../../../constants/common.js";import{filterDataByAccessDeep as l}from"../../../../../utils/rbac.js";import{checkEndpointAndDeleteXMcp as c}from"../../../utils/xmcp-utils.js";import{HTTP_METHODS as y}from"./constants.js";function P(t){return typeof t=="object"&&t!==null&&"responses"in t&&typeof t.responses=="object"}function S(t){const{paths:n={}}=t,e=[];for(const[r,i]of Object.entries(n)){const s=!c(i,"docs");for(const[p,o]of Object.entries(i))y.has(p.toLowerCase())&&(s||!c(o,"docs")||e.push({path:r,method:p.toUpperCase(),summary:o.summary,description:o.description,security:o.security}))}return e}async function T({relativePath:t,outdir:n,user:e,rbac:r={},requiresLogin:i=!1}){const s=a.join(n||"",u,h(t,".json"));if(!f(s))return;const o=await d(s,"utf-8"),m=JSON.parse(o);return l(m,{isAuthenticated:e?.isAuthenticated,email:e?.email,teams:e?.teams},r,i)}export{T as getApiDescriptionFromFs,S as getEndpointsFromPaths,P as isMcpEndpoint};