@redocly/redoc-reef 0.135.0-next.5 → 0.135.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 (126) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  3. package/dist/cli/build/analytics/collectors/get-nested-configs-usage.js +1 -1
  4. package/dist/cli/develop.js +1 -1
  5. package/dist/cli/telemetry/get-portal-config-stats.js +1 -1
  6. package/dist/cli/telemetry/index.js +1 -1
  7. package/dist/client/app/Sidebar/RequestAccessButton.js +2 -2
  8. package/dist/client/app/Sidebar/Sidebar.js +3 -3
  9. package/dist/client/app/hooks/catalog/useCatalogClassic.js +1 -1
  10. package/dist/client/app/hooks/catalog/useCatalogFilter.js +1 -1
  11. package/dist/client/app/hooks/useRouteChangeTracker.js +1 -1
  12. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  13. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  14. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  15. package/dist/client/app/pages/DevLogin/DevLogin.js +1 -1
  16. package/dist/client/app/search/useSearch.js +1 -1
  17. package/dist/client/templates/openapi-docs/helpers.js +1 -1
  18. package/dist/constants/l10n/langs/ar.js +1 -1
  19. package/dist/constants/l10n/langs/de.js +1 -1
  20. package/dist/constants/l10n/langs/en.js +1 -1
  21. package/dist/constants/l10n/langs/es.js +1 -1
  22. package/dist/constants/l10n/langs/fr.js +1 -1
  23. package/dist/constants/l10n/langs/hi.js +1 -1
  24. package/dist/constants/l10n/langs/it.js +1 -1
  25. package/dist/constants/l10n/langs/ja.js +1 -1
  26. package/dist/constants/l10n/langs/ko.js +1 -1
  27. package/dist/constants/l10n/langs/pl.js +1 -1
  28. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  29. package/dist/constants/l10n/langs/pt.js +1 -1
  30. package/dist/constants/l10n/langs/ru.js +1 -1
  31. package/dist/constants/l10n/langs/uk.js +1 -1
  32. package/dist/constants/l10n/langs/zh.js +1 -1
  33. package/dist/markdoc/helpers/get-operation/get-operation.js +1 -0
  34. package/dist/markdoc/helpers/get-operation/index.d.ts +4 -0
  35. package/dist/markdoc/helpers/get-operation/index.js +1 -0
  36. package/dist/markdoc/helpers/get-resolved-sample-code-block.d.ts +3 -0
  37. package/dist/markdoc/helpers/get-resolved-sample-code-block.js +5 -0
  38. package/dist/markdoc/tags/openapi-code-sample.js +1 -1
  39. package/dist/markdoc/tags/openapi-response-sample.js +1 -1
  40. package/dist/server/api-routes/execute-api-route.js +1 -1
  41. package/dist/server/api-routes/import-api-routes-handlers.js +1 -1
  42. package/dist/server/constants/common.d.ts +2 -2
  43. package/dist/server/constants/common.js +1 -1
  44. package/dist/server/constants/plugins/openapi-docs.d.ts +0 -1
  45. package/dist/server/constants/plugins/openapi-docs.js +1 -1
  46. package/dist/server/esbuild/plugins/api-request-handlers-resolver.js +1 -1
  47. package/dist/server/esbuild/plugins/on-rebuild.d.ts +4 -4
  48. package/dist/server/plugins/api-functions/index.js +1 -1
  49. package/dist/server/plugins/catalog-classic/index.d.ts +0 -1
  50. package/dist/server/plugins/catalog-classic/index.js +1 -1
  51. package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
  52. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  53. package/dist/server/plugins/lifecycle.js +2 -2
  54. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.d.ts +4 -0
  55. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.js +1 -0
  56. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +7 -0
  57. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.js +1 -0
  58. package/dist/server/plugins/markdown/attribute-resolvers/index.js +1 -1
  59. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.d.ts +4 -0
  60. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -0
  61. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.d.ts +4 -0
  62. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.js +1 -0
  63. package/dist/server/plugins/markdown/attribute-resolvers/utils.d.ts +2 -0
  64. package/dist/server/plugins/markdown/attribute-resolvers/utils.js +1 -1
  65. package/dist/server/plugins/markdown/compiler.js +1 -1
  66. package/dist/server/plugins/markdown/index.js +1 -1
  67. package/dist/server/plugins/markdown/markdoc/partials.js +1 -1
  68. package/dist/server/plugins/markdown/search/get-ai-search-documents.js +1 -1
  69. package/dist/server/plugins/markdown/search/search-resolver.js +1 -1
  70. package/dist/server/plugins/markdown/search/walk-sections.js +3 -1
  71. package/dist/server/plugins/mcp/constants.d.ts +1 -0
  72. package/dist/server/plugins/mcp/constants.js +1 -1
  73. package/dist/server/plugins/mcp/docs-mcp/codemode/build-tool-type-declarations.d.ts +4 -0
  74. package/dist/server/plugins/mcp/docs-mcp/codemode/build-tool-type-declarations.js +8 -0
  75. package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.d.ts +5 -0
  76. package/dist/server/plugins/mcp/docs-mcp/codemode/prompts.js +4 -0
  77. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +3 -0
  78. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  79. package/dist/server/plugins/mcp/docs-mcp/tools/core/search.js +2 -2
  80. package/dist/server/plugins/mcp/docs-mcp/tools/core/types.d.ts +1 -0
  81. package/dist/server/plugins/mcp/docs-mcp/tools/execute.js +1 -1
  82. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/list-graphql-apis.js +1 -1
  83. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  84. package/dist/server/plugins/mcp/index.js +1 -1
  85. package/dist/server/plugins/mcp/servers/docs-server.js +3 -1
  86. package/dist/server/plugins/openapi-docs/index.js +1 -1
  87. package/dist/server/plugins/scorecard-classic/get-scorecard-config.d.ts +16 -0
  88. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  89. package/dist/server/plugins/search/engines/typesense/index.js +1 -1
  90. package/dist/server/plugins/search/index.js +1 -1
  91. package/dist/server/plugins/sso/index.js +1 -1
  92. package/dist/server/ssr/server-side-props/get-server-props-from-system-handlers.js +1 -1
  93. package/dist/server/store.d.ts +5 -3
  94. package/dist/server/store.js +1 -1
  95. package/dist/server/telemetry/index.js +1 -1
  96. package/dist/server/utils/ai-agent-detection.d.ts +6 -0
  97. package/dist/server/utils/ai-agent-detection.js +1 -1
  98. package/dist/server/web-server/routes/otel/otel.js +1 -1
  99. package/dist/server/web-server/routes/page-data.js +1 -1
  100. package/dist/server/web-server/utils.js +1 -1
  101. package/dist/types/markdoc.d.ts +5 -0
  102. package/package.json +9 -9
  103. package/dist/client/app/markdoc/custom-components/openapi/get-operation/get-operation.js +0 -1
  104. package/dist/client/app/markdoc/custom-components/openapi/get-operation/index.d.ts +0 -4
  105. package/dist/client/app/markdoc/custom-components/openapi/get-operation/index.js +0 -1
  106. package/dist/server/plugins/catalog-classic/get-server-props.d.ts +0 -4
  107. package/dist/server/plugins/catalog-classic/get-server-props.js +0 -1
  108. package/dist/server/plugins/catalog-classic/get-template-path.d.ts +0 -2
  109. package/dist/server/plugins/catalog-classic/get-template-path.js +0 -1
  110. package/dist/server/plugins/mcp/docs-mcp/codemode/build-execute-tool-description.d.ts +0 -4
  111. package/dist/server/plugins/mcp/docs-mcp/codemode/build-execute-tool-description.js +0 -4
  112. package/dist/server/plugins/openapi-docs/get-server-props-custom-fields.d.ts +0 -11
  113. package/dist/server/plugins/openapi-docs/get-server-props-custom-fields.js +0 -1
  114. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/get-operation-info-by-id.d.ts +0 -0
  115. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/get-operation-info-by-id.js +0 -0
  116. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/get-operation-info-by-pointer.d.ts +0 -0
  117. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/get-operation-info-by-pointer.js +0 -0
  118. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/get-operation.d.ts +0 -0
  119. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/index.d.ts +0 -0
  120. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/index.js +0 -0
  121. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-identifier.d.ts +0 -0
  122. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-identifier.js +0 -0
  123. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-info.d.ts +0 -0
  124. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-info.js +0 -0
  125. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-parameters.d.ts +0 -0
  126. /package/dist/{client/app/markdoc/custom-components/openapi → markdoc/helpers}/get-operation/types/operation-parameters.js +0 -0
@@ -1 +1 @@
1
- import{REDOCLY_TEAMS_RBAC as y}from"@redocly/config";import{MARKDOC_PARTIALS_DATA_KEY as D}from"../../store.js";import{reporter as R}from"../../tools/notifiers/reporter.js";import{canAccessFeature as g}from"../../utils/entitlements/can-access-feature.js";import{extractMdFirstHeading as A,getAst as T}from"./compiler.js";import{getTemplatePath as w}from"./get-template-path.js";import{prepareMarkdocPartials as M}from"./markdoc/partials.js";import{searchResolver as C}from"./search/search-resolver.js";import{markdownStaticDataLoader as E}from"./markdown-static-data-loader.js";import{makeErrorRoute as I}from"../error-route.js";import{validateRbacConfig as O}from"../validate-rbac-config.js";import{findFrontmatterSlugs as _,getSidebarSharedDataId as G,resolveFrontmatterSlugs as L}from"../utils.js";import{isPartial as j}from"./is-partial.js";import{markdownFrontmatterLoader as B}from"./markdown-frontmatter-loader.js";import{resolveRawPartials as K}from"./markdoc/resolve-raw-partials.js";import{getAiDocumentsStore as N}from"./search/get-ai-search-documents.js";import{registerPageProps as Y}from"../register-page-props.js";import{resolveMarkdownTemplate as q}from"./utils/resolve-markdown-template.js";import{sanitizeMalformedMdContent as z}from"./utils/sanitize-malformed-md-content.js";import{telemetryTraceStep as H}from"../../../cli/telemetry/helpers/trace-step.js";async function le(h){return{id:"markdoc",requiredEntitlements:["markdown"],loaders:{"markdown-frontmatter":B,"markdown-ast":async(e,t)=>{const i=await t.fs.read(e),m=await t.getConfig(),s=await K(i,e,m?.markdown?.partialsFolders,t),n=z(s);return T(e,n)}},processContent:async(e,t)=>{await H("build.plugin.markdown",async i=>{const{markdown:m}=await t.getConfig();i?.setAttribute("config",JSON.stringify(m||{}));const s=m?.partialsFolders??[],n=e.createTemplate("markdown","@redocly/theme/core/templates/Markdown"),S=e.registerServerPropsGetter("markdown",w("./get-server-props.js"));e.createTemplate("error",w("../../../client/app/Error/ErrorDetails.js"));for(const o of t.fs.scan(/\.md$/))if(!await t.isPathIgnored(o.relativePath)&&!j(o.relativePath,s))try{await k(o)}catch(a){e.addRoute(I(o.relativePath,a)),i?.error(a),await R.panicOnBuild("Failed to create route for markdown file: %s",a.message)}async function k(o){const{relativePath:a,realRelativePath:b}=o,{data:{frontmatter:r}}=await t.cache.load(a,"markdown-frontmatter"),P=r?.metadata||{},F=await _(a,"markdown-frontmatter",r,t),p=L(F,a);let d=null;r?.sidebar&&(d=await G(r.sidebar,a,t.fs));let u=n;const f=q({realRelativePath:b,frontmatter:r,markdown:m,contentDir:h.contentDir});f&&(u=e.createTemplate(f.templateRef,f.templatePath)),r?.rbac&&(g("rbac")?O({content:{[a]:r.rbac}}):r.rbac=void 0),g("banner")||(r.banner=void 0),await Y(o,t.fs,e),(p.length?p.reverse():[void 0]).forEach(v=>{e.addRoute({excludeFromSearch:r?.excludeFromSearch||!1,slug:v,fsPath:a,templateId:u,sharedData:d?[{id:d,key:"sidebar"}]:void 0,redirectFrom:Object.entries(r.redirects||{}).map(([l,{type:c}])=>({type:c||301,from:l})),[y]:r?.rbac,getNavText:async()=>(r?.seo?.title||await A(a,t)||"").toString(),metadata:{type:"markdown",...P},async getStaticData(l,c){return E(o,l,t,r,c)},getSearchDocuments:C(r,a,e.getSearchFacets,e.setSearchFacets),getAiDocumentsStore:N(e.getSearchFacets,r),serverPropsGetterIds:[S]})})}})},afterRoutesCreated:async(e,t)=>{const i=await M(t,e);e.setGlobalConfig({[D]:i})}}}export{le as markdownPlugin};
1
+ import{REDOCLY_TEAMS_RBAC as y}from"@redocly/config";import{MARKDOC_PARTIALS_DATA_KEY as D}from"../../constants/common.js";import{reporter as R}from"../../tools/notifiers/reporter.js";import{canAccessFeature as g}from"../../utils/entitlements/can-access-feature.js";import{extractMdFirstHeading as A,getAst as T}from"./compiler.js";import{getTemplatePath as w}from"./get-template-path.js";import{prepareMarkdocPartials as M}from"./markdoc/partials.js";import{searchResolver as C}from"./search/search-resolver.js";import{markdownStaticDataLoader as E}from"./markdown-static-data-loader.js";import{makeErrorRoute as I}from"../error-route.js";import{validateRbacConfig as O}from"../validate-rbac-config.js";import{findFrontmatterSlugs as _,getSidebarSharedDataId as G,resolveFrontmatterSlugs as L}from"../utils.js";import{isPartial as j}from"./is-partial.js";import{markdownFrontmatterLoader as B}from"./markdown-frontmatter-loader.js";import{resolveRawPartials as K}from"./markdoc/resolve-raw-partials.js";import{getAiDocumentsStore as N}from"./search/get-ai-search-documents.js";import{registerPageProps as Y}from"../register-page-props.js";import{resolveMarkdownTemplate as q}from"./utils/resolve-markdown-template.js";import{sanitizeMalformedMdContent as z}from"./utils/sanitize-malformed-md-content.js";import{telemetryTraceStep as H}from"../../../cli/telemetry/helpers/trace-step.js";async function le(h){return{id:"markdoc",requiredEntitlements:["markdown"],loaders:{"markdown-frontmatter":B,"markdown-ast":async(e,t)=>{const i=await t.fs.read(e),m=await t.getConfig(),s=await K(i,e,m?.markdown?.partialsFolders,t),n=z(s);return T(e,n)}},processContent:async(e,t)=>{await H("build.plugin.markdown",async i=>{const{markdown:m}=await t.getConfig();i?.setAttribute("config",JSON.stringify(m||{}));const s=m?.partialsFolders??[],n=e.createTemplate("markdown","@redocly/theme/core/templates/Markdown"),S=e.registerServerPropsGetter("markdown",w("./get-server-props.js"));e.createTemplate("error",w("../../../client/app/Error/ErrorDetails.js"));for(const o of t.fs.scan(/\.md$/))if(!await t.isPathIgnored(o.relativePath)&&!j(o.relativePath,s))try{await k(o)}catch(a){e.addRoute(I(o.relativePath,a)),i?.error(a),await R.panicOnBuild("Failed to create route for markdown file: %s",a.message)}async function k(o){const{relativePath:a,realRelativePath:b}=o,{data:{frontmatter:r}}=await t.cache.load(a,"markdown-frontmatter"),P=r?.metadata||{},F=await _(a,"markdown-frontmatter",r,t),p=L(F,a);let d=null;r?.sidebar&&(d=await G(r.sidebar,a,t.fs));let u=n;const f=q({realRelativePath:b,frontmatter:r,markdown:m,contentDir:h.contentDir});f&&(u=e.createTemplate(f.templateRef,f.templatePath)),r?.rbac&&(g("rbac")?O({content:{[a]:r.rbac}}):r.rbac=void 0),g("banner")||(r.banner=void 0),await Y(o,t.fs,e),(p.length?p.reverse():[void 0]).forEach(v=>{e.addRoute({excludeFromSearch:r?.excludeFromSearch||!1,slug:v,fsPath:a,templateId:u,sharedData:d?[{id:d,key:"sidebar"}]:void 0,redirectFrom:Object.entries(r.redirects||{}).map(([l,{type:c}])=>({type:c||301,from:l})),[y]:r?.rbac,getNavText:async()=>(r?.seo?.title||await A(a,t)||"").toString(),metadata:{type:"markdown",...P},async getStaticData(l,c){return E(o,l,t,r,c)},getSearchDocuments:C(r,a,e.getSearchFacets,e.setSearchFacets),getAiDocumentsStore:N(e.getSearchFacets,r),serverPropsGetterIds:[S]})})}})},afterRoutesCreated:async(e,t)=>{const i=await M(t,e);e.setGlobalConfig({[D]:i})}}}export{le as markdownPlugin};
@@ -1 +1 @@
1
- import*as f from"path";import{MARKDOC_PARTIALS_DATA_KEY as D,MARKDOC_PARTIALS_DEPS_KEY as A}from"../../../store.js";import{isPartial as y}from"../is-partial.js";function h(t,s){return Promise.all(t.map(s)).then(i=>t.filter((o,n)=>i[n]))}async function b(t,s){const{markdown:i}=await t.getConfig(),o=i?.partialsFolders??[],n=await h(t.fs.scan(/\.md$/),async a=>!(!f.posix.basename(a.relativePath).endsWith(".md")||await t.isPathIgnored(a.relativePath)||!y(a.relativePath,o)));s.setGlobalConfig({[D]:Object.fromEntries(n.map(a=>[a.relativePath,{}]))});const p={},m={};for(const a of n){const{ast:e,info:r}=await s.parseMarkdoc({input:a,context:t});p[a.relativePath]=e;const l=Array.isArray(r.dynamicMarkdocComponents)?r.dynamicMarkdocComponents:[],c=r.sharedDataDeps instanceof Set?Array.from(r.sharedDataDeps):Array.isArray(r.sharedDataDeps)?r.sharedDataDeps:[],d=Array.isArray(r.partials)?r.partials:[];m[a.relativePath]={dynamicComponents:new Set(l),sharedDataDeps:new Set(c),partials:new Set(d)}}return s.setGlobalConfig({[A]:Object.fromEntries(Object.entries(m).map(([a,e])=>[a,{dynamicComponents:Array.from(e.dynamicComponents),sharedDataDeps:Array.from(e.sharedDataDeps),partials:Array.from(e.partials)}]))}),p}export{b as prepareMarkdocPartials};
1
+ import*as f from"path";import{MARKDOC_PARTIALS_DATA_KEY as D,MARKDOC_PARTIALS_DEPS_KEY as A}from"../../../constants/common.js";import{isPartial as y}from"../is-partial.js";function h(t,s){return Promise.all(t.map(s)).then(i=>t.filter((o,n)=>i[n]))}async function b(t,s){const{markdown:i}=await t.getConfig(),o=i?.partialsFolders??[],n=await h(t.fs.scan(/\.md$/),async a=>!(!f.posix.basename(a.relativePath).endsWith(".md")||await t.isPathIgnored(a.relativePath)||!y(a.relativePath,o)));s.setGlobalConfig({[D]:Object.fromEntries(n.map(a=>[a.relativePath,{}]))});const p={},m={};for(const a of n){const{ast:e,info:r}=await s.parseMarkdoc({input:a,context:t});p[a.relativePath]=e;const l=Array.isArray(r.dynamicMarkdocComponents)?r.dynamicMarkdocComponents:[],c=r.sharedDataDeps instanceof Set?Array.from(r.sharedDataDeps):Array.isArray(r.sharedDataDeps)?r.sharedDataDeps:[],d=Array.isArray(r.partials)?r.partials:[];m[a.relativePath]={dynamicComponents:new Set(l),sharedDataDeps:new Set(c),partials:new Set(d)}}return s.setGlobalConfig({[A]:Object.fromEntries(Object.entries(m).map(([a,e])=>[a,{dynamicComponents:Array.from(e.dynamicComponents),sharedDataDeps:Array.from(e.sharedDataDeps),partials:Array.from(e.partials)}]))}),p}export{b as prepareMarkdocPartials};
@@ -1,4 +1,4 @@
1
- import _ from"@markdoc/markdoc";import D from"node:path";import{AI_SEARCH_CHUNK_SIZE as E,AI_SEARCH_DOCUMENT_CHUNK_SIZE as M}from"../../../constants/plugins/search.js";import{slugger as P}from"../../../../utils/slugger.js";import{joinSectionContent as U}from"./join-section-content.js";import{toMarkdown as b}from"./to-markdown.js";import{AstToSearchNodeTransformer as I}from"./walk-sections.js";import{createRenderTagFn as x}from"./create-render-tag-fn.js";import{getLocaleFromRelativePath as y}from"../../../fs/utils/get-locale-from-relative-path.js";import{HeadingNode as L}from"./nodes/heading-node.js";import{extractDocumentSearchFacets as H}from"./search-facets.js";import{formatDocumentMetadata as K}from"../../search/utils.js";import{TagNode as N}from"./nodes/tag-node.js";import{MARKDOC_PARTIALS_DATA_KEY as R}from"../../../store.js";const j=Symbol(),et=(n,r)=>async(e,c,i,s)=>{if(r?.excludeFromSearch)return;P.reset();const a=await e.getNavText?.()||D.basename(e.fsPath),u=_.Ast.fromJSON(c.ast),f=new I({partials:s.getGlobalConfig(R)||{},renderTag:x(s.markdocOptions.tags),getInnerContent:b,ast:u,skipConditionals:!0}),d=Array.from(f.transform());return{async getLLMsTxts(){const o=r?.seo,g=o&&typeof o=="object"&&"description"in o?String(o.description):void 0,C=U(d);return[{title:a,description:g,slug:e.slug,fsPath:e.fsPath,content:C,includeInLLMsTxt:!0}]},async getSearchDocuments(){return F(e,d,n,a)}}};function F(n,r,e,c){const i=n.slug,s=new Map,a=n.metadata||{},u=H(a,e),f=K(a),d=f?`Metadata:
1
+ import _ from"@markdoc/markdoc";import D from"node:path";import{AI_SEARCH_CHUNK_SIZE as E,AI_SEARCH_DOCUMENT_CHUNK_SIZE as M}from"../../../constants/plugins/search.js";import{slugger as P}from"../../../../utils/slugger.js";import{joinSectionContent as U}from"./join-section-content.js";import{toMarkdown as b}from"./to-markdown.js";import{AstToSearchNodeTransformer as I}from"./walk-sections.js";import{createRenderTagFn as x}from"./create-render-tag-fn.js";import{getLocaleFromRelativePath as y}from"../../../fs/utils/get-locale-from-relative-path.js";import{HeadingNode as L}from"./nodes/heading-node.js";import{extractDocumentSearchFacets as H}from"./search-facets.js";import{formatDocumentMetadata as K}from"../../search/utils.js";import{TagNode as N}from"./nodes/tag-node.js";import{MARKDOC_PARTIALS_DATA_KEY as R}from"../../../constants/common.js";const j=Symbol(),et=(n,r)=>async(e,c,i,s)=>{if(r?.excludeFromSearch)return;P.reset();const a=await e.getNavText?.()||D.basename(e.fsPath),u=_.Ast.fromJSON(c.ast),f=new I({partials:s.getGlobalConfig(R)||{},renderTag:x(s.markdocOptions.tags),getInnerContent:b,ast:u,skipConditionals:!0}),d=Array.from(f.transform());return{async getLLMsTxts(){const o=r?.seo,g=o&&typeof o=="object"&&"description"in o?String(o.description):void 0,C=U(d);return[{title:a,description:g,slug:e.slug,fsPath:e.fsPath,content:C,includeInLLMsTxt:!0}]},async getSearchDocuments(){return F(e,d,n,a)}}};function F(n,r,e,c){const i=n.slug,s=new Map,a=n.metadata||{},u=H(a,e),f=K(a),d=f?`Metadata:
2
2
  ${f}
3
3
  `:"";let o=[];for(const t of r)if(t instanceof L){o.splice(t.attributes.level-1,6);const l=t.attributes.level>2,m=o[o.length-1]?.title,S=o[o.length-1]?.url,T=l&&m?m:O(c,t),A=l&&S?S:t.getUrl(i),h={title:T,content:"",url:A,level:t.attributes.level,toc:o.map(v=>p(v.section)).join(`
4
4
  `)};(t.attributes.level>1||p(t)!==c)&&(h.content+=h.content?`
@@ -1 +1 @@
1
- import p from"@markdoc/markdoc";import{REDOCLY_ROUTE_RBAC as l,REDOCLY_TEAMS_RBAC as A}from"@redocly/config";import{getInnerText as h}from"../../../../markdoc/helpers/get-inner-text.js";import{getSearchDocuments as T}from"./get-search-documents.js";import{AstToSearchNodeTransformer as R}from"./walk-sections.js";import{setDocumentSearchFacets as S,extractDocumentSearchFacets as C}from"./search-facets.js";import{MARKDOC_PARTIALS_DATA_KEY as D}from"../../../store.js";import{normalizeFrontmatterKeywords as _}from"../../helpers/normalize-frontmatter-keywords.js";function K(e,m,o,c){return async(t,r,a)=>{if(e?.excludeFromSearch)return[];const i=p.Ast.fromJSON(r.ast),f=new R({ast:i,getInnerContent:h,partials:a.getGlobalConfig(D)||{}}),u=t.metadata||{},n=C(u,o);S(n,o,c);const d=e?.seo?.title||m,{result:s}=_(e?.keywords);return T(f,t.slug,d,r[A],r[l],n,s||void 0)}}export{K as searchResolver};
1
+ import p from"@markdoc/markdoc";import{REDOCLY_ROUTE_RBAC as l,REDOCLY_TEAMS_RBAC as A}from"@redocly/config";import{getInnerText as h}from"../../../../markdoc/helpers/get-inner-text.js";import{getSearchDocuments as T}from"./get-search-documents.js";import{AstToSearchNodeTransformer as R}from"./walk-sections.js";import{setDocumentSearchFacets as S,extractDocumentSearchFacets as C}from"./search-facets.js";import{MARKDOC_PARTIALS_DATA_KEY as D}from"../../../constants/common.js";import{normalizeFrontmatterKeywords as _}from"../../helpers/normalize-frontmatter-keywords.js";function K(e,m,o,c){return async(t,r,a)=>{if(e?.excludeFromSearch)return[];const i=p.Ast.fromJSON(r.ast),f=new R({ast:i,getInnerContent:h,partials:a.getGlobalConfig(D)||{}}),u=t.metadata||{},n=C(u,o);S(n,o,c);const d=e?.seo?.title||m,{result:s}=_(e?.keywords);return T(f,t.slug,d,r[A],r[l],n,s||void 0)}}export{K as searchResolver};
@@ -1 +1,3 @@
1
- import{logger as N}from"../../../tools/notifiers/logger.js";import{isNode as f}from"../../../../markdoc/helpers/guards/is-node.js";import{isConditionalNode as T}from"../../../../markdoc/helpers/guards/is-conditional-node.js";import{isContentNode as m}from"../../../../markdoc/helpers/guards/is-content-node.js";import{getNodeAttribute as u}from"../../../../markdoc/helpers/get-node-attribute.js";import{extractRbacFromCondition as w}from"../../../../markdoc/helpers/extract-rbac-from-condition-node.js";import{TextNode as l}from"./nodes/text-node.js";import{TAG_TITLE_ATTRIBUTES as b,TagNode as p}from"./nodes/tag-node.js";import{HeadingNode as y}from"./nodes/heading-node.js";import{joinSectionContent as d}from"./join-section-content.js";class B{#r;#o;#e;#s;#c;constructor({ast:i,partials:t,skipConditionals:s=!1,getInnerContent:r,renderTag:o}){if(this.#r=i,this.#o=t,this.#e=s,this.#s=r,this.#c=o,!this.#r||!f(this.#r))throw new Error("ast is not a valid Markdoc Node.")}#i(){return{skipConditionals:this.#e,renderTag:this.#c}}*transform(){yield*this.#l(this.#r,{parentNode:null})}*#l(i,t,s=this.#s){if(!(!i||!f(i))){if(T(i)){if(this.#e)return;const r=w(i);r&&r.length>0&&(yield*this.#t(i,{...t,rbacTeams:r},s));return}if(m(i)){yield new l({node:i,content:s([i],this.#i()),...t});return}if(i.type==="heading"){yield new y({node:i,content:s([i],this.#i()),rbacTeams:t?.rbacTeams});return}if(i.type==="tag"){yield*this.#n(i,t,s);return}yield*this.#t(i,t,s)}}*#n(i,t,s=this.#s){switch(i.tag){case"partial":{const r=i.attributes.file,o=i.attributes.variables??{};if(r&&this.#o[r]){yield*this.#l(this.#o[r],t,(e,n)=>s(e,{...n,variables:o}));return}N.warn(`Could not create search indexes for partial \u201C${r}\u201D: file not found`);return}case"cards":case"tabs":case"code-walkthrough":{yield*this.#t(i,t,s);return}case"markdoc-example":{const r=s([i],this.#i());yield new l({node:i,content:r,...t});return}case"code-snippet":{const r=u(i,"title"),o=s([i],this.#i());if(r){const e=new p({node:i,content:r,...t});t={...t,parentNode:e},yield e}o&&(yield new l({node:i,content:o,...t}));return}default:{const r=this.#h(i,t,s);if(r){yield*r;return}const o=b.find(c=>c in i.attributes),e=(o&&u(i,o))??"",n=typeof e=="string"?e:s([e]);if(n){const c=new p({node:i,content:n,...t});t={...t,parentNode:c},yield c}if(a(i))yield*this.#t(i,t,s);else{const c=s([i],this.#i());c&&(yield new l({node:i,content:c,...t}))}return}}}#h(i,t,s){const r=()=>a(i)?d([...this.#t(i,t,s)]):"",o=this.#c?.(i,{getBody:r});return o===void 0?void 0:[new l({node:i,content:o,...t})]}*#t(i,t,s=this.#s){for(const r of[...Object.values(i.slots),...i.children])for(const o of this.#l(r,t,s))o instanceof y&&(t={...t,parentNode:o}),yield o}}function a(h){return h.children.length>0||Object.keys(h.slots).length>0}export{B as AstToSearchNodeTransformer};
1
+ import{logger as N}from"../../../tools/notifiers/logger.js";import{isNode as f}from"../../../../markdoc/helpers/guards/is-node.js";import{isConditionalNode as T}from"../../../../markdoc/helpers/guards/is-conditional-node.js";import{isContentNode as m}from"../../../../markdoc/helpers/guards/is-content-node.js";import{getNodeAttribute as u}from"../../../../markdoc/helpers/get-node-attribute.js";import{extractRbacFromCondition as w}from"../../../../markdoc/helpers/extract-rbac-from-condition-node.js";import{TextNode as n}from"./nodes/text-node.js";import{TAG_TITLE_ATTRIBUTES as b,TagNode as p}from"./nodes/tag-node.js";import{HeadingNode as y}from"./nodes/heading-node.js";import{joinSectionContent as d}from"./join-section-content.js";class B{#s;#o;#e;#r;#c;constructor({ast:i,partials:t,skipConditionals:r=!1,getInnerContent:s,renderTag:o}){if(this.#s=i,this.#o=t,this.#e=r,this.#r=s,this.#c=o,!this.#s||!f(this.#s))throw new Error("ast is not a valid Markdoc Node.")}#i(){return{skipConditionals:this.#e,renderTag:this.#c}}*transform(){yield*this.#n(this.#s,{parentNode:null})}*#n(i,t,r=this.#r){if(!(!i||!f(i))){if(T(i)){if(this.#e)return;const s=w(i);s&&s.length>0&&(yield*this.#t(i,{...t,rbacTeams:s},r));return}if(m(i)){yield new n({node:i,content:r([i],this.#i()),...t});return}if(i.type==="heading"){yield new y({node:i,content:r([i],this.#i()),rbacTeams:t?.rbacTeams});return}if(i.type==="tag"){yield*this.#l(i,t,r);return}yield*this.#t(i,t,r)}}*#l(i,t,r=this.#r){switch(i.tag){case"partial":{const s=i.attributes.file,o=i.attributes.variables??{};if(s&&this.#o[s]){yield*this.#n(this.#o[s],t,(e,l)=>r(e,{...l,variables:o}));return}N.warn(`Could not create search indexes for partial \u201C${s}\u201D: file not found`);return}case"cards":case"tabs":case"code-walkthrough":{yield*this.#t(i,t,r);return}case"markdoc-example":{const s=r([i],this.#i());yield new n({node:i,content:s,...t});return}case"code-snippet":{const s=u(i,"title"),o=r([i],this.#i());if(s){const e=new p({node:i,content:s,...t});t={...t,parentNode:e},yield e}o&&(yield new n({node:i,content:o,...t}));return}default:{const s=this.#h(i,t,r);if(s){yield*s;return}const o=b.find(c=>c in i.attributes),e=(o&&u(i,o))??"",l=typeof e=="string"?e:r([e]);if(l){const c=new p({node:i,content:l,...t});t={...t,parentNode:c},yield c}if(a(i))yield*this.#t(i,t,r);else{const c=r([i],this.#i());c&&(yield new n({node:i,content:c,...t}))}return}}}#h(i,t,r){const s=()=>a(i)?d([...this.#t(i,t,r)]):"",o=this.#c?.(i,{getBody:s});return o===void 0?void 0:[new n({node:i,content:o.endsWith(`
2
+ `)?o:`${o}
3
+ `,...t})]}*#t(i,t,r=this.#r){for(const s of[...Object.values(i.slots),...i.children])for(const o of this.#n(s,t,r))o instanceof y&&(t={...t,parentNode:o}),yield o}}function a(h){return h.children.length>0||Object.keys(h.slots).length>0}export{B as AstToSearchNodeTransformer};
@@ -11,4 +11,5 @@ export declare const McpErrorCodes: {
11
11
  export declare const DEFAULT_CONNECTION_TIMEOUT_MS = 30000;
12
12
  export declare const SSE_KEEPALIVE_INTERVAL_MS = 15000;
13
13
  export declare const MAX_DOCUMENTS_PER_CATEGORY = 3;
14
+ export declare const MCP_NOT_ALLOWED_TEMPLATE_ID = "mcp-not-allowed";
14
15
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- const r={Docs:"docs"},o={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},e=3e4,t=15e3,E=3;export{e as DEFAULT_CONNECTION_TIMEOUT_MS,E as MAX_DOCUMENTS_PER_CATEGORY,o as McpErrorCodes,r as McpServerType,t as SSE_KEEPALIVE_INTERVAL_MS};
1
+ const o={Docs:"docs"},r={InternalError:-32603,ServerError:-32e3,InvalidRequest:-32600,MethodNotFound:-32601,InvalidParams:-32602},e=3e4,t=15e3,E=3,_="mcp-not-allowed";export{e as DEFAULT_CONNECTION_TIMEOUT_MS,E as MAX_DOCUMENTS_PER_CATEGORY,_ as MCP_NOT_ALLOWED_TEMPLATE_ID,r as McpErrorCodes,o as McpServerType,t as SSE_KEEPALIVE_INTERVAL_MS};
@@ -0,0 +1,4 @@
1
+ import type { McpToolSchema } from '../../../../types';
2
+ export declare function sanitizeToolName(name: string): string;
3
+ export declare function buildToolTypeDeclarations(tools: McpToolSchema[]): string;
4
+ //# sourceMappingURL=build-tool-type-declarations.d.ts.map
@@ -0,0 +1,8 @@
1
+ const f=/^[A-Za-z_$][\w$]*$/;function y(n){const e=n.split(/[^A-Za-z0-9]+/).filter(Boolean).map((o,i)=>i===0?o:o[0].toUpperCase()+o.slice(1)).join("");return f.test(e)?e:`_${e}`}function T(n){return["```ts","declare const tools: {",n.map(e=>{const o=e.schema,i=e.outputSchema?u(e.outputSchema):"unknown",s=o.required?.length?"input":"input?";return` /** ${l(e.description)} */
2
+ ${y(e.name)}(${s}: ${u(o," ")}): Promise<${i}>;`}).join(`
3
+ `),"};","```"].join(`
4
+ `)}function l(n){return(n??"").replace(/\*\//g,"*\\/")}function u(n,r=""){if(!n||typeof n!="object")return"unknown";const e=n.nullable?" | null":"";if(typeof n.codemodeType=="string")return n.codemodeType+e;if(Array.isArray(n.enum))return n.enum.map(m).join(" | ")+e;switch(n.type){case"string":return"string"+e;case"number":case"integer":return"number"+e;case"boolean":return"boolean"+e;case"array":return`Array<${u(n.items,r)}>`+e;case"object":return b(n,r)+e;default:return"unknown"}}function m(n){return typeof n=="string"?`'${n.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`:String(n)}function b(n,r){const e=n.properties??{},o=Object.keys(e),i=n.additionalProperties,s=i?i===!0?"unknown":u(i,r):void 0;if(o.length===0)return i===!1?"{}":`Record<string, ${s??"unknown"}>`;const $=new Set(n.required??[]),c=o.map(t=>{const p=e[t],d=$.has(t)?"":"?",g=f.test(t)?t:JSON.stringify(t);return{doc:p.description,field:`${g}${d}: ${u(p,r+" ")}`}});if(s&&c.push({field:`[key: string]: ${s}`}),!c.some(({doc:t})=>t))return`{ ${c.map(({field:t})=>t).join("; ")} }`;const a=r+" ";return`{
5
+ ${c.map(({doc:t,field:p})=>`${t?`${a}/** ${l(t)} */
6
+ `:""}${a}${p};`).join(`
7
+ `)}
8
+ ${r}}`}export{T as buildToolTypeDeclarations,y as sanitizeToolName};
@@ -0,0 +1,5 @@
1
+ export declare const EXECUTE_DESCRIPTION: string;
2
+ export declare const DESCRIBE_TOOLS_DESCRIPTION: string;
3
+ export declare const CODE_MODE_INSTRUCTIONS: string;
4
+ export declare const USAGE_NOTES = "Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.";
5
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1,4 @@
1
+ const e=["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.","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 user request and decide which sandbox tools it needs (every tool name is listed in the `describe-tools` input schema).","2. Call `describe-tools` with those names to get their exact TypeScript signatures. NEVER call `execute` with guessed method names, parameter names, or enum values.","3. Batch everything the request needs into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript (filter, map, aggregate), and `return` only what the request needs.","","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(`
2
+ `),t=["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); 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(`
3
+ `),s=["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."].join(`
4
+ `),o="Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.";export{s as CODE_MODE_INSTRUCTIONS,t as DESCRIBE_TOOLS_DESCRIPTION,e as EXECUTE_DESCRIPTION,o as USAGE_NOTES};
@@ -1,8 +1,11 @@
1
1
  import type { McpToolSchema } from '../../../types';
2
2
  export declare const EXECUTE_TOOL_NAME = "execute";
3
3
  export declare const EXECUTE_TOOL_SCHEMA: McpToolSchema;
4
+ export declare const DESCRIBE_TOOLS_TOOL_NAME = "describe-tools";
5
+ export declare const CODE_MODE_TOOL_NAMES: ReadonlySet<string>;
4
6
  export declare function getDefaultToolSchemas(config: {
5
7
  products?: string[];
8
+ locales?: string[];
6
9
  requiresLogin: boolean;
7
10
  rbac?: Record<string, unknown>;
8
11
  hasGraphqlApis?: boolean;
@@ -1 +1 @@
1
- import{shouldHandleMcpAuth as p}from"../auth/auth-handlers.js";import{GRAPHQL_TYPE_KINDS as l}from"./tools/graphql/types.js";const s=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],t={type:"string",nullable:!0},n={codemodeType:"OpenApiServer[]"},r={codemodeType:"OpenApiSecurityRequirement[]"},o={codemodeType:"Record<string, OpenApiSecurityScheme>"},c={codemodeType:"OpenApiDocument"},u={codemodeType:"OpenApiOperation & { path: string; method: string }"},m="execute",P={name:m,description:"Run JavaScript in a sandbox to orchestrate multiple documentation tools in one call.",schema:{type:"object",required:["code","description"],additionalProperties:!1,properties:{code:{type:"string",description:"JavaScript to run in the sandbox. Return a value to receive it as the result.",minLength:1},description:{type:"string",description:"A short, human-readable summary of what this code does (shown to users in place of the raw call).",minLength:1}}}},d={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API 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 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",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},h={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",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:[...s,...s.map(e=>e.toLowerCase())],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},y={type:"object",required:[],additionalProperties:!1,properties:{}};function q(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:d,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:n}}},limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:n,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:t,description:t,security:r}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:h,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:n,endpoint:u,globalSecurity:r,securitySchemes:o}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:o,security:r}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:c}}},v(e.products)];return p(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:y,annotations:{title:"Who Am I",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&&i.push(...H()),i}const g={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}}},f={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",enum:[...l],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',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}}},b={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}}},S={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function H(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:g,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"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) and/or `filter` (member-name substring, e.g. "book") to explore a domain cheaply instead of pulling the full schema.',schema:f,annotations:{title:"Get GraphQL Type List",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches).",schema:b,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}},{name:"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:S,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1}}]}function v(e){return{name:"search",description:"Search across the documentation to fetch relevant content for a given query",schema:e&&e.length>0?{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},product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}}:{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}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{m as EXECUTE_TOOL_NAME,P as EXECUTE_TOOL_SCHEMA,q as getDefaultToolSchemas};
1
+ import{shouldHandleMcpAuth as d}from"../auth/auth-handlers.js";import{EXECUTE_DESCRIPTION as h}from"./codemode/prompts.js";import{GRAPHQL_TYPE_KINDS as o}from"./tools/graphql/types.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],t={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"},g={codemodeType:"OpenApiOperation & { path: string; method: string }"},c="execute",j={name:c,description:h,schema:{type:"object",required:["code","description"],additionalProperties:!1,properties:{code:{type:"string",description:"JavaScript to run in the sandbox. Return a value to receive it as the result.",minLength:1},description:{type:"string",description:"A short, human-readable summary of what this code does (shown to users in place of the raw call).",minLength:1}}}},f="describe-tools",I=new Set([c,f]),b={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API 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 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",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},S={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",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,...p.map(e=>e.toLowerCase())],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},v={type:"object",required:[],additionalProperties:!1,properties:{}};function w(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:b,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:r}}},...n}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",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:t,description:t,security:s}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:S,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:g,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:l,security:s}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:y}}},P(e.products,e.locales)];return d(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:v,annotations:{title:"Who Am I",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&&i.push(...O()),i}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}}},L={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",enum:[...o],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',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}}},T={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}}},A={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function O(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:H,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t}}},...n}}},{name:"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` (member-name substring, 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.',schema:L,annotations:{title:"Get GraphQL Type List",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:t,type:{type:"string"},args:{type:"string"}}}},...n}}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full 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:T,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"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:A,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function P(e,i){const u=e&&e.length>0,m=i&&i.length>0;return{name:"search",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},...u?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...m?{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:i,nullable:!0}}:{}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{I as CODE_MODE_TOOL_NAMES,f as DESCRIBE_TOOLS_TOOL_NAME,c as EXECUTE_TOOL_NAME,j as EXECUTE_TOOL_SCHEMA,w as getDefaultToolSchemas};
@@ -1,6 +1,6 @@
1
- import{withPathPrefix as p}from"@redocly/theme/core/utils";import{ServerRoutes as h}from"../../../../../../constants/api.js";const f=async(a,t)=>{const{query:c,product:u}=a,l=JSON.stringify({query:c,product:u});let e=`${t.baseUrl}${p(h.SEMANTIC_SEARCH)}`;e.startsWith("http://")&&(e=e.replace(/^http:\/\//,"https://"));const o=t.accessToken?`authorization=${String(t.accessToken).replace(/^Bearer /,"")}`:"";try{const s=await fetch(e,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...o?{Cookie:o}:{}},body:l});if(!s.ok)return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0};const r=await s.json();if(!r||r.length===0)return{content:[{type:"text",text:"No results found."}]};const i=r.map(n=>`### [${n.title}](${new URL(n.url,t.baseUrl).toString()})
1
+ import{withPathPrefix as f}from"@redocly/theme/core/utils";import{ServerRoutes as d}from"../../../../../../constants/api.js";import{DEFAULT_LOCALE_PLACEHOLDER as m}from"../../../../../../constants/common.js";const y=async(i,t)=>{const{query:c,product:l,locale:u}=i,p=t.config.l10n?.defaultLocale||m,h=JSON.stringify({query:c,product:l,locale:u||p});let e=`${t.baseUrl}${f(d.SEMANTIC_SEARCH)}`;e.startsWith("http://")&&(e=e.replace(/^http:\/\//,"https://"));const o=t.accessToken?`authorization=${String(t.accessToken).replace(/^Bearer /,"")}`:"";try{const s=await fetch(e,{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 r=await s.json();if(!r||r.length===0)return{content:[{type:"text",text:"No results found."}]};const a=r.map(n=>`### [${n.title}](${new URL(n.url,t.baseUrl).toString()})
2
2
 
3
3
  ${n.content}
4
4
  `).join(`
5
5
 
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}}};var m={search:f};export{m as default};
6
+ `).trim();return{content:[{type:"text",text:a.length?a:"No results found."}]}}catch{return{content:[{type:"text",text:"Error retrieving search results."}],isError:!0}}};var C={search:y};export{C as default};
@@ -1,6 +1,7 @@
1
1
  export type SearchArgs = {
2
2
  query: string;
3
3
  product?: string;
4
+ locale?: string;
4
5
  };
5
6
  export type WhoamiArgs = Record<string, never>;
6
7
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- import{mcpToolHandlers as s}from"../../../../../client/mcp-tool-handlers-entry.js";import{EXECUTE_TOOL_NAME as c}from"../tool-schemas.js";import{sanitizeToolName as u}from"../codemode/build-execute-tool-description.js";import{runInSandbox as f}from"../codemode/sandbox.js";import{executeMcpTool as l,isMcpToolAvailable as m}from"../../workers/execute-mcp-tool.js";const p=async(t,r,n)=>{const o=await y(r,n),{result:i,error:e}=await f(t.code,o);return{content:[{type:"text",text:JSON.stringify({result:i,error:e})}],isError:e!==void 0}};async function y(t,r){const n={};for(const o of Object.keys(s))o!==c&&await d(o,t)&&(n[u(o)]=async i=>{const e=await l({toolName:o,args:i,context:t,extra:r}),a=x(e);if(e.isError)throw new Error(a);return T(a)});return n}async function d(t,r){try{return await m({toolName:t,context:r})}catch{return!1}}function x(t){return t.content.filter(r=>r.type==="text").map(r=>r.text).join("")}function T(t){try{return JSON.parse(t)}catch{return t}}var g={[c]:p};export{g as default};
1
+ import{mcpToolHandlers as s}from"../../../../../client/mcp-tool-handlers-entry.js";import{EXECUTE_TOOL_NAME as c,CODE_MODE_TOOL_NAMES as u}from"../tool-schemas.js";import{sanitizeToolName as f}from"../codemode/build-tool-type-declarations.js";import{runInSandbox as l}from"../codemode/sandbox.js";import{executeMcpTool as m,isMcpToolAvailable as p}from"../../workers/execute-mcp-tool.js";const y=async(t,r,n)=>{const o=await E(r,n),{result:i,error:e}=await l(t.code,o);return{content:[{type:"text",text:JSON.stringify({result:i,error:e})}],isError:e!==void 0}};async function E(t,r){const n={};for(const o of Object.keys(s))u.has(o)||await d(o,t)&&(n[f(o)]=async i=>{const e=await m({toolName:o,args:i,context:t,extra:r}),a=O(e);if(e.isError)throw new Error(a);return T(a)});return n}async function d(t,r){try{return await p({toolName:t,context:r})}catch{return!1}}function O(t){return t.content.filter(r=>r.type==="text").map(r=>r.text).join("")}function T(t){try{return JSON.parse(t)}catch{return t}}var _={[c]:y};export{_ as default};
@@ -1 +1 @@
1
- import{paginate as p,textResult as r}from"./tool-helpers.js";const c=async(l,n)=>{const{filter:a,page:o=1,limit:m=300}=l;let e=n.graphqlDescriptions;if(a){const s=a.toLowerCase();e=e.filter(i=>i.name.toLowerCase().includes(s))}const t=p(e,o,m);return t.items.length===0?r("No GraphQL schemas available"):r(JSON.stringify({...t,items:t.items.map(({name:s,description:i})=>({name:s,description:i}))}))};var f={"list-graphql-apis":c};export{f as default};
1
+ import{paginate as p,textResult as m}from"./tool-helpers.js";const c=async(r,l)=>{const{filter:i,page:o=1,limit:n=300}=r;let t=l.graphqlDescriptions;if(i){const e=i.toLowerCase();t=t.filter(s=>s.name.toLowerCase().includes(e))}const a=p(t,o,n);return m(JSON.stringify({...a,items:a.items.map(({name:e,description:s})=>({name:e,description:s}))}))};var g={"list-graphql-apis":c};export{g as default};
@@ -1 +1 @@
1
- import{withPathPrefix as d}from"@redocly/theme/core/utils";import{importApiRoutesHandler as f}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as h}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as A}from"../../../telemetry/index.js";import{KvService as D}from"../../../persistence/kv/services/kv-service.js";import{envConfig as s}from"../../../config/env-config.js";async function v(i,a,e){const t=a.get("auth"),r=await e.resolveRouteStaticData(i)||{},o=d(i.slug),{requestHandlers:c}=await f(e.serverOutDir),p=c[i.requestHandlerId],u=(await p()).default,l=async()=>await D.getInstance({baseDbDir:e.serverOutDir,sqldRemoteDatabaseUrl:s.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:s.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),m=h({honoCtx:a,ctx:{user:{teams:t.teams,email:t.claims.email,claims:t.claims,idpAccessToken:t.idpAccessToken,idpId:t.claims.idpId,isAuthenticated:t.isAuthenticated},config:e.config,outdir:e.outdir,baseUrl:new URL(a.req.url).origin},telemetry:A,getKv:l}),n=await u(a.req.raw,m,{...r,props:{...r.props,routeSlug:o,outdir:e.outdir}});return n instanceof Response?n:typeof n=="string"?new Response(n,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(n),{headers:{"Content-Type":"application/json"}})}export{v as handleMcpRequest};
1
+ import{withPathPrefix as h}from"@redocly/theme/core/utils";import{importApiRoutesHandler as g}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as A}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as T}from"../../../telemetry/index.js";import{KvService as D}from"../../../persistence/kv/services/kv-service.js";import{envConfig as o}from"../../../config/env-config.js";import{acceptsHtml as R}from"../../../utils/ai-agent-detection.js";import{handleErrorPageRender as E}from"../../../web-server/utils.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as c}from"../constants.js";async function b(n,t,e){const i=t.req.raw;if(i.method==="GET"&&R(i.headers.get("accept"))&&e.templates.has(c))return E(t,e,{slug:n.slug},405,c);const r=t.get("auth"),s=await e.resolveRouteStaticData(n)||{},m=h(n.slug),{requestHandlers:p}=await g(e.serverOutDir),l=p[n.requestHandlerId],u=(await l()).default,d=async()=>await D.getInstance({baseDbDir:e.serverOutDir,sqldRemoteDatabaseUrl:o.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:o.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),f=A({honoCtx:t,ctx:{user:{teams:r.teams,email:r.claims.email,claims:r.claims,idpAccessToken:r.idpAccessToken,idpId:r.claims.idpId,isAuthenticated:r.isAuthenticated},config:e.config,outdir:e.outdir,baseUrl:new URL(t.req.url).origin},telemetry:T,getKv:d}),a=await u(t.req.raw,f,{...s,props:{...s.props,routeSlug:m,outdir:e.outdir}});return a instanceof Response?a:typeof a=="string"?new Response(a,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(a),{headers:{"Content-Type":"application/json"}})}export{b as handleMcpRequest};
@@ -1 +1 @@
1
- import{fileURLToPath as E}from"node:url";import{dirname as O,join as a}from"node:path";import{logger as u}from"../../tools/notifiers/logger.js";import{reporter as R}from"../../tools/notifiers/reporter.js";import{isDefined as q}from"../../../utils/guards/is-defined.js";import{buildGraphqlDescriptions as w,filterIgnoredApiDescriptions as h,getCleanedUpApiDescriptions as A,isMcpInRedirects as T}from"./utils.js";import{isMcpCodeModeEnabled as _}from"./mode.js";import{getDefaultToolSchemas as j,EXECUTE_TOOL_SCHEMA as L}from"./docs-mcp/tool-schemas.js";import{telemetryTraceStep as G}from"../../../cli/telemetry/helpers/trace-step.js";const D="mcp-docs-server-handler",p=O(E(import.meta.url));async function H(){let o=!1;return{id:"mcp",async processContent(e,i){o||await G("build.plugin.mcp",async c=>{const r=await e.loadOpenApiDefinitions(i),d=await e.loadGraphqlDefinitions(i),n=await i.getConfig(),{mcp:t,redirects:v}=n;if(c?.setAttribute("config",JSON.stringify(t||{})),!(t?.hide||t?.docs?.hide)&&(T(v)&&await R.panicOnBuildContentError('The reserved route "/mcp" cannot be used in redirect configuration. Please remove any redirects involving "/mcp" from your redocly.yaml config.'),!t?.docs?.hide)){u.info("Configuring MCP servers...");const C=a(p,"./handlers/docs-mcp-handler.js"),M=A(h(r,t?.docs?.ignore||[])),l=new Map;for(const s of M){const f=s.definition.info?.title||"",g=s.definition.info?.version||"";l.set(`${f.toLowerCase()}@${g}`,{name:f,description:s.definition.info?.description||"",version:g,servers:s.definition.servers||[],relativePath:s.relativePath})}const m=w(h(d,t?.docs?.ignore||[])),P=Object.values(n.products||{}).map(s=>s?.name).filter(q),S=!!n?.access?.requiresLogin,b=n?.access?.rbac||{},y=j({products:P,requiresLogin:S,rbac:b,hasGraphqlApis:m.length>0});e.addMcpTools(a(p,"./docs-mcp/tools/index.js"),y),_()&&e.addMcpTools(a(p,"./docs-mcp/tools/execute.js"),[L]),await I({actions:e,handlerPath:C,apiDescriptionsMap:Object.fromEntries(l),graphqlDescriptions:m,mcpConfig:t}),o=!0}})},async afterRoutesCreated(e,i){const c=await i.getConfig(),{mcp:r}=c;e.setGlobalData({mcpData:{docs:{enabled:!r?.hide&&!r?.docs?.hide,name:r?.docs?.name}}})}}}var z=H;async function I({actions:o,handlerPath:e,apiDescriptionsMap:i,graphqlDescriptions:c,mcpConfig:r}){o.createRequestHandler(D,e),o.addApiRoute({slug:"/mcp",requestHandlerId:D,httpMethod:"all",getStaticData:async()=>({props:{config:{apiDescriptionsMap:i,graphqlDescriptions:c,mcpDocsServerName:r?.docs?.name||"Docs MCP Server"},serverOutDir:o.serverOutDir,tools:o.getMcpTools().map(({importPath:d,...n})=>n)}})}),u.info("Registered Docs MCP Server endpoint at /mcp")}export{D as MCP_DOCS_SERVER_HANDLER_ID,z as default,H as mcpServerPlugin};
1
+ import{fileURLToPath as b}from"node:url";import{dirname as A,join as a}from"node:path";import{logger as g}from"../../tools/notifiers/logger.js";import{reporter as O}from"../../tools/notifiers/reporter.js";import{isDefined as _}from"../../../utils/guards/is-defined.js";import{buildGraphqlDescriptions as w,filterIgnoredApiDescriptions as h,getCleanedUpApiDescriptions as R,isMcpInRedirects as q}from"./utils.js";import{isMcpCodeModeEnabled as L}from"./mode.js";import{getDefaultToolSchemas as j,EXECUTE_TOOL_SCHEMA as N}from"./docs-mcp/tool-schemas.js";import{telemetryTraceStep as G}from"../../../cli/telemetry/helpers/trace-step.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as H}from"./constants.js";const D="mcp-docs-server-handler",p=A(b(import.meta.url));async function I(){let i=!1;return{id:"mcp",async processContent(e,r){i||await G("build.plugin.mcp",async c=>{const t=await e.loadOpenApiDefinitions(r),d=await e.loadGraphqlDefinitions(r),s=await r.getConfig(),{mcp:n,redirects:v}=s;if(c?.setAttribute("config",JSON.stringify(n||{})),!(n?.hide||n?.docs?.hide)&&(q(v)&&await O.panicOnBuildContentError('The reserved route "/mcp" cannot be used in redirect configuration. Please remove any redirects involving "/mcp" from your redocly.yaml config.'),e.createTemplate(H,"@redocly/theme/layouts/McpNotAllowed"),!n?.docs?.hide)){g.info("Configuring MCP servers...");const M=a(p,"./handlers/docs-mcp-handler.js"),C=R(h(t,n?.docs?.ignore||[])),l=new Map;for(const o of C){const f=o.definition.info?.title||"",u=o.definition.info?.version||"";l.set(`${f.toLowerCase()}@${u}`,{name:f,description:o.definition.info?.description||"",version:u,servers:o.definition.servers||[],relativePath:o.relativePath})}const m=w(h(d,n?.docs?.ignore||[])),P=Object.values(s.products||{}).map(o=>o?.name).filter(_),y=s.l10n?.locales?.map(o=>o.code)??r.fs.localeFolders,E=!!s?.access?.requiresLogin,S=s?.access?.rbac||{},T=j({products:P,locales:y,requiresLogin:E,rbac:S,hasGraphqlApis:m.length>0});e.addMcpTools(a(p,"./docs-mcp/tools/index.js"),T),L()&&e.addMcpTools(a(p,"./docs-mcp/tools/execute.js"),[N]),await U({actions:e,handlerPath:M,apiDescriptionsMap:Object.fromEntries(l),graphqlDescriptions:m,mcpConfig:n}),i=!0}})},async afterRoutesCreated(e,r){const c=await r.getConfig(),{mcp:t}=c;e.setGlobalData({mcpData:{docs:{enabled:!t?.hide&&!t?.docs?.hide,name:t?.docs?.name}}})}}}var K=I;async function U({actions:i,handlerPath:e,apiDescriptionsMap:r,graphqlDescriptions:c,mcpConfig:t}){i.createRequestHandler(D,e),i.addApiRoute({slug:"/mcp",requestHandlerId:D,httpMethod:"all",getStaticData:async()=>({props:{config:{apiDescriptionsMap:r,graphqlDescriptions:c,mcpDocsServerName:t?.docs?.name||"Docs MCP Server"},serverOutDir:i.serverOutDir,tools:i.getMcpTools().map(({importPath:d,...s})=>s)}})}),g.info("Registered Docs MCP Server endpoint at /mcp")}export{D as MCP_DOCS_SERVER_HANDLER_ID,K as default,I as mcpServerPlugin};
@@ -1 +1,3 @@
1
- import{McpServer as T}from"@redocly/mcp-typescript-sdk/server/mcp.js";import{StreamableHTTPServerTransport as b}from"@redocly/mcp-typescript-sdk/server/streamableHttp.js";import{logger as m}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as u,MCP_TOOL_WORKER_KEY as _,MCP_TOOL_IS_AVAILABLE_KEY as g}from"../../../workers/mcp-tool-worker-pool.js";import{EXECUTE_TOOL_NAME as i,EXECUTE_TOOL_SCHEMA as I}from"../docs-mcp/tool-schemas.js";import{buildExecuteToolDescription as M}from"../docs-mcp/codemode/build-execute-tool-description.js";import{isMcpCodeModeEnabled as S}from"../mode.js";async function A({name:e,tools:f,context:d}){const a=new T({name:e,version:new Date().toISOString().slice(0,10)},{capabilities:{logging:{}}}),s=new b({sessionIdGenerator:void 0}),n=C(d),c=o=>async(r,t)=>{m.info(`MCP tool called: ${o}`);const E={toolName:o,args:r,context:n,extra:h(t)};return await u.exec(_,[E],{timeout:6e4})},l=async o=>{try{return await u.exec(g,[{toolName:o,context:n}],{timeout:1e4})}catch(r){return m.error(`Failed to check MCP tool availability for "${o}": ${r instanceof Error?r.message:String(r)}`),!1}},p=f.filter(o=>o.name!==i);if(S()){const o=[];for(const r of p)await l(r.name)&&o.push(r);a.tool(i,M(o),I.schema,c(i))}else for(const o of p){const r=o.annotations||{title:o.name},t=a.tool(o.name,o.description,o.schema,r,c(o.name));await l(o.name)||t.disable()}return await a.connect(s),{server:a,transport:s,cleanup:async()=>{s.close()}}}function h(e){return{sessionId:e.sessionId,authInfo:e.authInfo,requestId:e.requestId,requestInfo:e.requestInfo,_meta:e._meta}}function C(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata}}export{A as createDocsMcpServer};
1
+ import{McpServer as _}from"@redocly/mcp-typescript-sdk/server/mcp.js";import{StreamableHTTPServerTransport as S}from"@redocly/mcp-typescript-sdk/server/streamableHttp.js";import{logger as p}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as u,MCP_TOOL_WORKER_KEY as b,MCP_TOOL_IS_AVAILABLE_KEY as y}from"../../../workers/mcp-tool-worker-pool.js";import{EXECUTE_TOOL_NAME as d,EXECUTE_TOOL_SCHEMA as f,DESCRIBE_TOOLS_TOOL_NAME as I,CODE_MODE_TOOL_NAMES as C}from"../docs-mcp/tool-schemas.js";import{buildToolTypeDeclarations as M,sanitizeToolName as E}from"../docs-mcp/codemode/build-tool-type-declarations.js";import{CODE_MODE_INSTRUCTIONS as D,DESCRIBE_TOOLS_DESCRIPTION as g,USAGE_NOTES as h}from"../docs-mcp/codemode/prompts.js";import{isMcpCodeModeEnabled as T}from"../mode.js";async function B({name:e,tools:o,context:n}){const a=new _({name:e,version:new Date().toISOString().slice(0,10)},{capabilities:{logging:{}},instructions:T()?D:void 0}),s=new S({sessionIdGenerator:void 0}),c=L(n),l=r=>async(t,m)=>{p.info(`MCP tool called: ${r}`);const O={toolName:r,args:t,context:c,extra:w(m)};return await u.exec(b,[O],{timeout:6e4})},i=async r=>{try{return await u.exec(y,[{toolName:r,context:c}],{timeout:1e4})}catch(t){return p.error(`Failed to check MCP tool availability for "${r}": ${t instanceof Error?t.message:String(t)}`),!1}};if(T()){const r=o.filter(t=>!C.has(t.name));a.tool(d,f.description,f.schema,l(d)),a.tool(I,g,q(r),v(r,i))}else await Promise.all(o.map(async r=>{const t=r.annotations||{title:r.name},m=a.tool(r.name,r.description,r.schema,t,l(r.name));await i(r.name)||m.disable()}));return await a.connect(s),{server:a,transport:s,cleanup:async()=>{s.close()}}}function q(e){const o=[...new Set(e.map(n=>E(n.name)))];return{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:"Tool names to describe. Omit to describe every tool.",items:{type:"string",enum:o},nullable:!0}}}}function v(e,o){return async n=>{const a=n.tools,s=a?.length?e.filter(i=>a.includes(E(i.name))):e,c=await Promise.all(s.map(i=>o(i.name))),l=s.filter((i,r)=>c[r]);return{content:[{type:"text",text:`${M(l)}
2
+
3
+ ${h}`}]}}}function w(e){return{sessionId:e.sessionId,authInfo:e.authInfo,requestId:e.requestId,requestInfo:e.requestInfo,_meta:e._meta}}function L(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata}}export{B as createDocsMcpServer};
@@ -1 +1 @@
1
- import{simplifyAstStructure as te}from"@redocly/openapi-docs";import{REDOCLY_ROUTE_RBAC as E,REDOCLY_TEAMS_RBAC as P}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as U,PUBLIC_RBAC_SCOPE_ITEM as V}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as oe,PUBLIC_API_DEFINITIONS_FOLDER as ae}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as re,OPENAPI_SHARED_DATA_PREFIX as $}from"../../constants/plugins/openapi-docs.js";import{envConfig as q}from"../../config/env-config.js";import{isRbacScopeItems as se}from"../../utils/rbac/is-rbac-scope-items.js";import{getRouteSlugsForPath as ie}from"../utils.js";import{searchResolver as ne}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as pe,shouldAddRoute as ce}from"./utils.js";import{getTemplatePath as M}from"./get-template-path.js";import{storeDefinitionBundles as de}from"./store-definition-bundles.js";import{definitionLoader as le,definitionsLoader as ue}from"./load-definition.js";import{getAiDocumentsStore as fe}from"./search/get-ai-search-documents.js";import{fromCurrentDir as me}from"../../utils/paths.js";import{telemetryTraceStep as ge}from"../../../cli/telemetry/helpers/trace-step.js";import{getApiConfigByPath as he}from"../get-api-config.js";const B="openapi-spec-download";async function Me(){let k=[],_={},N=new Set,f={};return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":ue,"load-oas":le},processContent:async(e,c)=>{await ge("build.plugin.openapi_docs",async m=>{e.createRequestHandler(B,me(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:ae+"/*",requestHandlerId:B,httpMethod:"all",[P]:V,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:oe+"/*",requestHandlerId:B,httpMethod:"all",[P]:V,getStaticData:async()=>({props:{}})});const C=e.createTemplate(U,M("../../../client/templates/openapi-docs/template.js")),o=e.registerServerPropsGetter(U,M("./get-server-props.js")),a=e.registerServerPropsGetter(re,M("./get-server-props-custom-fields.js")),s=await c.getConfig();m?.setAttribute("config",JSON.stringify(s.openapi||{}));const d=s.rules?.["custom-fields-schema"];_={},f={};const g=await e.loadOpenApiDefinitions(c);k=g.map(({markdocChunks:p,relativePath:l,customOutputRelativeFile:i,isVirtual:n,realRelativePath:h})=>({chunks:p,relativePath:l,realRelativePath:h,isVirtual:i!=null||n})),de(g,e.outdir);for(const p of g||[]){const{definition:l,config:i,relativePath:n,customOutputRelativeFile:h,contentItems:I,flatItems:D,parser:v,options:x,rawOptions:Y,hash:J}=p,O=h||n,r=[],G={},{definition:Q}=v||{},{info:u}=Q||{},b=u?.["x-metadata"],y=!!i.openapi?.excludeFromSearch||!!i.theme?.openapi?.excludeFromSearch||!!s.openapi?.excludeFromSearch||!!s.theme?.openapi?.excludeFromSearch,j={title:u?.title,description:u?.description,summary:u?.summary,...i.metadata,...b},S={untagged:[],tagged:new Map};for(const t of D){const{id:F,href:R,operationDefinition:T}=t;if(T){const{tags:A}=T;if(A)for(const L of A)S.tagged.has(L)||S.tagged.set(L,[]),S.tagged.get(L)?.push(t);else S.untagged.push(t);q.isDevelopMode&&(G[`#${T.pointer}`]=t.href)}if(!ce({item:t}))continue;const w=t,z=w.type==="section"&&!!w.infoDefinition,K=R.split("#")[0]+"/",Z=t?.operationDefinition?.[P],ee=se(i.access?.rbac)?i.access.rbac:void 0;r.push({excludeFromSearch:y,slugSuffix:K,fsPath:O,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:n,templateId:C,[P]:Z||ee,getAiDocumentsStore:fe({parser:v,options:x,info:u,tagOperations:S,openapiContentItem:w,metadata:j,relativePath:n,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:z,excludeFromSearch:y}),getStaticData:async A=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:A.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:F,disableAutoScroll:!0}})})}if(r[0]={...r[0],metadata:{type:"openapi",...j},hasClientRoutes:!0,getSidebar:(t,F)=>{const R=[];return pe({contentItems:I,sidebarItems:R,routeSlug:t.slug,navItem:F}),R},getNavText:()=>u?.title,getSearchDocuments:ne(v,x,D,e.getSearchFacets,e.setSearchFacets,y)},b?.apiId&&!p.isVirtual){const t=he(p.config.apis,p.realRelativePath);f[b.apiId]={[P]:t.rbac,[E]:{fsPath:O}}}const W=r[0];r[0]=r[r.length-1],r[r.length-1]=W;for(const t of r)e.addRoute({...t,serverPropsGetterIds:d?[o,a]:[o]});const X=q.isDevelopMode?n:void 0,H=`${$}${n}`;_[H]={fsPath:O,definition:l,options:Y,sourcePath:X,routesMapping:G,hash:J};for(const t of r)e.addRoute({...t,sharedData:[{id:H,key:"openAPIDocsStore"}],serverPropsGetterIds:d?[o,a]:[o]})}})},afterRoutesCreated:async(e,c)=>{const m=new Set;for(const{chunks:o,relativePath:a,isVirtual:s,realRelativePath:d}of k){const g=ie(e.getAllRoutes(),a),p=(await c.cache.load(d,"load-oas")).compoundHash;await c.cache.load(a,{loader:async function(){for(const{node:i,markdown:n,key:h,relativePath:I}of o){const{ast:D}=await e.parseMarkdoc({input:{content:n,relativePath:I,isVirtual:s},context:c,deps:{sharedDataIds:[`${$}${I}`],routeSlugs:g}});i[`x-parsed-md-${h}`]={result:te(D)}}},name:"openapi-markdoc-inline-parser"},[p]);for(const{pointer:l}of o)m.add(l)}const C=N.difference(m);for(const o of C)c.cache.delete(o);N=m;for(const[o,a]of Object.entries(_))await e.createSharedData(o,{...a,baseSlug:e.getRouteByFsPath(a.fsPath)?.baseSlug},a.hash);Object.entries(f).forEach(([o,a])=>{const s=a[E]?.fsPath;if(!s)return;const d=e.getRouteByFsPath(s)?.baseSlug;f[o]={...a,[E]:{...a[E],slug:d},slug:d}}),e.setGlobalData({apiProducts:f})}}}export{Me as openAPIDocsPlugin};
1
+ import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_ROUTE_RBAC as A,REDOCLY_TEAMS_RBAC as S}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as H,PUBLIC_RBAC_SCOPE_ITEM as $}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_SHARED_DATA_PREFIX as j}from"../../constants/plugins/openapi-docs.js";import{envConfig as G}from"../../config/env-config.js";import{isRbacScopeItems as oe}from"../../utils/rbac/is-rbac-scope-items.js";import{getRouteSlugsForPath as ae}from"../utils.js";import{searchResolver as re}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as se,shouldAddRoute as ne}from"./utils.js";import{getTemplatePath as U}from"./get-template-path.js";import{storeDefinitionBundles as ie}from"./store-definition-bundles.js";import{definitionLoader as pe,definitionsLoader as ce}from"./load-definition.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{fromCurrentDir as le}from"../../utils/paths.js";import{telemetryTraceStep as fe}from"../../../cli/telemetry/helpers/trace-step.js";import{getApiConfigByPath as ue}from"../get-api-config.js";const B="openapi-spec-download";async function Te(){let L=[],E={},M=new Set,f={};return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":ce,"load-oas":pe},processContent:async(e,c)=>{await fe("build.plugin.openapi_docs",async u=>{e.createRequestHandler(B,le(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:B,httpMethod:"all",[S]:$,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:B,httpMethod:"all",[S]:$,getStaticData:async()=>({props:{}})});const _=e.createTemplate(H,U("../../../client/templates/openapi-docs/template.js")),a=e.registerServerPropsGetter(H,U("./get-server-props.js")),o=await c.getConfig();u?.setAttribute("config",JSON.stringify(o.openapi||{})),E={},f={};const p=await e.loadOpenApiDefinitions(c);L=p.map(({markdocChunks:r,relativePath:m,customOutputRelativeFile:i,isVirtual:n,realRelativePath:g})=>({chunks:r,relativePath:m,realRelativePath:g,isVirtual:i!=null||n})),ie(p,e.outdir);for(const r of p||[]){const{definition:m,config:i,relativePath:n,customOutputRelativeFile:g,contentItems:C,flatItems:D,parser:d,options:I,rawOptions:V,hash:q}=r,b=g||n,s=[],k={},{definition:Y}=d||{},{info:l}=Y||{},y=l?.["x-metadata"],v=!!i.openapi?.excludeFromSearch||!!i.theme?.openapi?.excludeFromSearch||!!o.openapi?.excludeFromSearch||!!o.theme?.openapi?.excludeFromSearch,x={title:l?.title,description:l?.description,summary:l?.summary,...i.metadata,...y},h={untagged:[],tagged:new Map};for(const t of D){const{id:O,href:P,operationDefinition:F}=t;if(F){const{tags:R}=F;if(R)for(const w of R)h.tagged.has(w)||h.tagged.set(w,[]),h.tagged.get(w)?.push(t);else h.untagged.push(t);G.isDevelopMode&&(k[`#${F.pointer}`]=t.href)}if(!ne({item:t}))continue;const T=t,W=T.type==="section"&&!!T.infoDefinition,X=P.split("#")[0]+"/",z=t?.operationDefinition?.[S],K=oe(i.access?.rbac)?i.access.rbac:void 0;s.push({excludeFromSearch:v,slugSuffix:X,fsPath:b,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:n,templateId:_,[S]:z||K,getAiDocumentsStore:de({parser:d,options:I,info:l,tagOperations:h,openapiContentItem:T,metadata:x,relativePath:n,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:W,excludeFromSearch:v}),getStaticData:async R=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:R.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:O,disableAutoScroll:!0}})})}if(s[0]={...s[0],metadata:{type:"openapi",...x},hasClientRoutes:!0,getSidebar:(t,O)=>{const P=[];return se({contentItems:C,sidebarItems:P,routeSlug:t.slug,navItem:O}),P},getNavText:()=>l?.title,getSearchDocuments:re(d,I,D,e.getSearchFacets,e.setSearchFacets,v)},y?.apiId&&!r.isVirtual){const t=ue(r.config.apis,r.realRelativePath);f[y.apiId]={[S]:t.rbac,[A]:{fsPath:b}}}const J=s[0];s[0]=s[s.length-1],s[s.length-1]=J;for(const t of s)e.addRoute({...t,serverPropsGetterIds:[a]});const Q=G.isDevelopMode?n:void 0,N=`${j}${n}`;E[N]={fsPath:b,definition:m,options:V,sourcePath:Q,routesMapping:k,hash:q};for(const t of s)e.addRoute({...t,sharedData:[{id:N,key:"openAPIDocsStore"}],serverPropsGetterIds:[a]})}})},afterRoutesCreated:async(e,c)=>{const u=new Set;for(const{chunks:a,relativePath:o,isVirtual:p,realRelativePath:r}of L){const m=ae(e.getAllRoutes(),o),i=(await c.cache.load(r,"load-oas")).compoundHash;await c.cache.load(o,{loader:async function(){for(const{node:g,markdown:C,key:D,relativePath:d}of a){const{ast:I}=await e.parseMarkdoc({input:{content:C,relativePath:d,isVirtual:p},context:c,deps:{sharedDataIds:[`${j}${d}`],routeSlugs:m}});g[`x-parsed-md-${D}`]={result:Z(I)}}},name:"openapi-markdoc-inline-parser"},[i]);for(const{pointer:n}of a)u.add(n)}const _=M.difference(u);for(const a of _)c.cache.delete(a);M=u;for(const[a,o]of Object.entries(E))await e.createSharedData(a,{...o,baseSlug:e.getRouteByFsPath(o.fsPath)?.baseSlug},o.hash);Object.entries(f).forEach(([a,o])=>{const p=o[A]?.fsPath;if(!p)return;const r=e.getRouteByFsPath(p)?.baseSlug;f[a]={...o,[A]:{...o[A],slug:r},slug:r}}),e.setGlobalData({apiProducts:f})}}}export{Te as openAPIDocsPlugin};
@@ -13,6 +13,17 @@ export declare const getScorecardConfig: (config: Partial<RedoclyConfig>) => {
13
13
  [x: string]: unknown;
14
14
  };
15
15
  } | undefined;
16
+ arazzo1_1Decorators?: {
17
+ [x: string]: unknown;
18
+ } | undefined;
19
+ arazzo1_1Preprocessors?: {
20
+ [x: string]: unknown;
21
+ } | undefined;
22
+ arazzo1_1Rules?: {
23
+ [x: string]: string | {
24
+ [x: string]: unknown;
25
+ };
26
+ } | undefined;
16
27
  async2Decorators?: {
17
28
  [x: string]: unknown;
18
29
  } | undefined;
@@ -40,6 +51,11 @@ export declare const getScorecardConfig: (config: Partial<RedoclyConfig>) => {
40
51
  [x: string]: unknown;
41
52
  } | undefined;
42
53
  extends?: string[] | undefined;
54
+ graphqlRules?: {
55
+ [x: string]: string | {
56
+ [x: string]: unknown;
57
+ };
58
+ } | undefined;
43
59
  name: string;
44
60
  oas2Decorators?: {
45
61
  [x: string]: unknown;
@@ -1 +1 @@
1
- import{writeFileSync as E}from"node:fs";import D from"path";import{SCORECARD_OUTPUT_FILE_NAME as b}from"../../constants/common.js";import{mapObject as T}from"../../../utils/object/map-object.js";import{envConfig as w}from"../../config/env-config.js";import{removeLeadingSlash as A}from"../../../utils/url/remove-leading-slash.js";import{combineUrls as R}from"@redocly/theme/core/utils";import{logger as j}from"../../tools/notifiers/logger.js";import{getRouteSlugToCatalogSlugMap as F}from"../../utils/catalog-classic/get-route-slug-to-catalog-slug-map.js";import{deepEqual as I}from"../../../utils/object/deep-equal.js";import{ensureDir as N}from"../../utils/index.js";import{getTemplatePath as U}from"./get-template-path.js";import{getAllRuleNames as q}from"./lint.js";import{getScorecardConfig as L}from"./get-scorecard-config.js";import{CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as M}from"../catalog-classic/index.js";import{getScorecardSlug as k}from"./shared-utils.js";import{scorecardConfigLoader as W}from"./loaders/scorecard-config.js";import{scorecardLoader as B}from"./loaders/scorecard.js";import{computeScorecard as J}from"./compute-scorecard.js";import{telemetryTraceStep as $}from"../../../cli/telemetry/helpers/trace-step.js";const G="scorecardClassic";let u={},h={};async function ue({id:P,requiredEntitlements:_,loadersPrefix:v=""}){let p=null,y=null,O=!1;return{id:P??"scorecardClassic",requiredEntitlements:_??["scorecard"],loaders:{[`${v}scorecard-config`]:W,[`${v}scorecard`]:B},async processContent(r,l){await $("build.plugin.scorecard_classic",async S=>{const a=r.createTemplate(G,U("./template/index.js")),g=await l.getConfig(),m=L(g),f=g?.reunite??{},i=[()=>p===null,()=>!I(u,m),()=>!I(h,f)].some(e=>e());u=m,S?.setAttribute("config",JSON.stringify(u||{})),h=f;const n=g.catalogClassic??{},c=u.levels||[];if(c.length<1)throw Error("Invalid configuration of levels config");i&&(p=await J({actions:r,context:l,scorecardConfig:u,reuniteConfig:h}));const{data:{configs:t}}=await l.cache.load("",`${v}scorecard-config`),{perLevel:d,all:s}=q(t);y={levelNames:c.map(e=>e.name),rules:s,rulesPerLevel:d};for(const[e,o]of Object.entries(n)){const C=R(o.slug,"scorecard/");r.addRoute({duplicateInAllLocales:!0,slug:C,fsPath:R(o.slug,"scorecard/"),templateId:a,hasClientRoutes:!0,excludeFromSidebar:!0,serverPropsGetterIds:[M],sharedData:[{id:"scorecard",key:"scorecard"},{key:"catalog",id:"catalog-"+e}],getNavText:()=>Promise.resolve(o.title||"API design scorecard"),getStaticData:async()=>({props:{catalogId:e,catalogConfig:{...o,items:void 0},scorecardConfig:u,scorecardInfo:y}})})}})},afterRoutesCreated:async(r,l)=>{const S=await l.getConfig(),a=S.catalogClassic??{},g=L(S);if(Object.keys(a).length){const i=Object.keys(a).length>1?await F(r,l,a):null,n={};for(const[c,t]of Object.entries(p||{})){const d=r.getRouteByFsPath(c),s=d?.slug;if(s){if(d&&!g.ignoreMetadata){const e=i?i.get(s)??Object.values(a)[0].slug:Object.values(a)[0].slug,o=R(e,"scorecard/");d.metadata={...d.metadata,scorecardStatus:t.status,scorecardLevel:t.scorecardLevel,scorecardLevelIdx:t.scorecardLevelIdx,scorecardLevels:T(t.levels,C=>({uniqueErrors:C.uniqueErrors,uniqueWarnings:C.uniqueWarnings})),scoreCardSlug:o+"apis/"+encodeURIComponent(A(s))}}if(n[s]={...t,levels:T(t.levels,e=>({...e,problems:e.problems.map(o=>({ruleId:o.ruleId,severity:o.severity}))}))},!O){const e=D.resolve(r.outdir,"_scorecard",k(s));E(N(e),JSON.stringify(t))}}}await r.createSharedData("scorecard",n)}const m={};for(const[i,n]of Object.entries(p||{})){const c=r.getRouteByFsPath(i)?.slug;c&&(m[c]=n)}const f=w.REDOCLY_METADATA_OUTPUT_FOLDER;!O&&f&&(j.info("Writing scorecard data..."),E(D.join(f,b),JSON.stringify({scorecardData:m,...y}))),O=!0}}}export{ue as scorecardClassicPlugin};
1
+ import{writeFileSync as D}from"node:fs";import L from"path";import{SCORECARD_OUTPUT_FILE_NAME as w}from"../../constants/common.js";import{mapObject as E}from"../../../utils/object/map-object.js";import{envConfig as A}from"../../config/env-config.js";import{removeLeadingSlash as j}from"../../../utils/url/remove-leading-slash.js";import{combineUrls as O}from"@redocly/theme/core/utils";import{logger as _}from"../../tools/notifiers/logger.js";import{getRouteSlugToCatalogSlugMap as F}from"../../utils/catalog-classic/get-route-slug-to-catalog-slug-map.js";import{deepEqual as I}from"../../../utils/object/deep-equal.js";import{ensureDir as N}from"../../utils/index.js";import{getTemplatePath as q}from"./get-template-path.js";import{getAllRuleNames as U}from"./lint.js";import{getScorecardConfig as T}from"./get-scorecard-config.js";import{getScorecardSlug as k}from"./shared-utils.js";import{scorecardConfigLoader as M}from"./loaders/scorecard-config.js";import{scorecardLoader as W}from"./loaders/scorecard.js";import{computeScorecard as B}from"./compute-scorecard.js";import{telemetryTraceStep as J}from"../../../cli/telemetry/helpers/trace-step.js";const $="scorecardClassic";let u={},R={};async function ne({id:b,requiredEntitlements:P,loadersPrefix:v=""}){let p=null,y=null,h=!1;return{id:b??"scorecardClassic",requiredEntitlements:P??["scorecard"],loaders:{[`${v}scorecard-config`]:M,[`${v}scorecard`]:W},async processContent(r,l){await J("build.plugin.scorecard_classic",async S=>{const a=r.createTemplate($,q("./template/index.js")),g=await l.getConfig(),m=T(g),f=g?.reunite??{},i=[()=>p===null,()=>!I(u,m),()=>!I(R,f)].some(e=>e());u=m,S?.setAttribute("config",JSON.stringify(u||{})),R=f;const n=g.catalogClassic??{},c=u.levels||[];if(c.length<1)throw Error("Invalid configuration of levels config");i&&(p=await B({actions:r,context:l,scorecardConfig:u,reuniteConfig:R}));const{data:{configs:t}}=await l.cache.load("",`${v}scorecard-config`),{perLevel:d,all:s}=U(t);y={levelNames:c.map(e=>e.name),rules:s,rulesPerLevel:d};for(const[e,o]of Object.entries(n)){const C=O(o.slug,"scorecard/");r.addRoute({duplicateInAllLocales:!0,slug:C,fsPath:O(o.slug,"scorecard/"),templateId:a,hasClientRoutes:!0,excludeFromSidebar:!0,serverPropsGetterIds:[],sharedData:[{id:"scorecard",key:"scorecard"},{key:"catalog",id:"catalog-"+e}],getNavText:()=>Promise.resolve(o.title||"API design scorecard"),getStaticData:async()=>({props:{catalogId:e,catalogConfig:{...o,items:void 0},scorecardConfig:u,scorecardInfo:y}})})}})},afterRoutesCreated:async(r,l)=>{const S=await l.getConfig(),a=S.catalogClassic??{},g=T(S);if(Object.keys(a).length){const i=Object.keys(a).length>1?await F(r,l,a):null,n={};for(const[c,t]of Object.entries(p||{})){const d=r.getRouteByFsPath(c),s=d?.slug;if(s){if(d&&!g.ignoreMetadata){const e=i?i.get(s)??Object.values(a)[0].slug:Object.values(a)[0].slug,o=O(e,"scorecard/");d.metadata={...d.metadata,scorecardStatus:t.status,scorecardLevel:t.scorecardLevel,scorecardLevelIdx:t.scorecardLevelIdx,scorecardLevels:E(t.levels,C=>({uniqueErrors:C.uniqueErrors,uniqueWarnings:C.uniqueWarnings})),scoreCardSlug:o+"apis/"+encodeURIComponent(j(s))}}if(n[s]={...t,levels:E(t.levels,e=>({...e,problems:e.problems.map(o=>({ruleId:o.ruleId,severity:o.severity}))}))},!h){const e=L.resolve(r.outdir,"_scorecard",k(s));D(N(e),JSON.stringify(t))}}}await r.createSharedData("scorecard",n)}const m={};for(const[i,n]of Object.entries(p||{})){const c=r.getRouteByFsPath(i)?.slug;c&&(m[c]=n)}const f=A.REDOCLY_METADATA_OUTPUT_FOLDER;!h&&f&&(_.info("Writing scorecard data..."),D(L.join(f,w),JSON.stringify({scorecardData:m,...y}))),h=!0}}}export{ne as scorecardClassicPlugin};
@@ -1 +1 @@
1
- import{appendFile as g}from"node:fs/promises";import{existsSync as I}from"node:fs";import m from"node:path";import{Client as $}from"typesense";import{SEARCH_GROUP_FACET_FIELD as E,SEARCH_PRODUCT_FIELD as R,SEARCH_RBAC_FIELD as A,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as T,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as O,HIGHLIGHTED_TEXT_MAX_LENGTH as b,SEARCH_DATA_EXPORT_FOLDER as F,SEARCH_DOCUMENT_METADATA_KEY as P,SEARCH_GROUP_LIMIT as N,SEARCH_MAX_FACET_VALUES as S,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as C}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as D}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class U{#e=null;#o="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:R,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:A,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#o=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new $({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(T);const{locale:n,outDir:r}=t,s=e.map(a=>{const o={...a},c=a[P];return c&&(c.curated&&(o.metadata_curated=c.curated),c.excludes&&(o.metadata_keywords_excludes=c.excludes),c.includes&&(o.metadata_keywords_includes=c.includes)),o}),i=this.#s.get(n)??[];this.#s.set(n,i.concat(s)),i.length+e.length>=C&&await this.exportDocuments(r)}async search(e,t){return await D("search",async n=>{const{query:r,locale:s,filter:i,loadMore:a}=e,o=this.#c(s),c={collection:o,q:r||"*",query_by:this.#l(),max_facet_values:S};if(n?.setAttribute("collectionName",o),n?.setAttribute("locale",s),this.#e)if(a){const{groupKey:l,offset:u}=a,h={offset:u,filter_by:this.#r(t,i),facet_by:"*"};return n?.setAttribute("isLoadMore",!0),n?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(o).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:N,filter_by:this.#r(t,i)};n?.setAttribute("groups",l.group_by),n?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(t,i)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),i)}else return{facets:{},documents:{}}})}#u(e,t){const n={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const r of e.hits)n.documents[t].push({document:this.#i(r),highlight:this.#a(r)});return n}#f(e,t){const n={facets:{},documents:{}};for(const r of this.#_(t))n.documents[r]=[];if("results"in e)for(const r of e.results){if(r.facet_counts&&r.facet_counts.length)for(const s of r.facet_counts)n.facets[s.field_name]=s.counts.map(i=>({value:i.value,count:i.count}));if(r.grouped_hits&&r.grouped_hits.length)for(const s of r.grouped_hits){const i=s.group_key[0],a=[];for(const o of s.hits)a.push({document:this.#i(o),highlight:this.#a(o)});n.documents[i]=a}}return n}#i(e){return this.#h(e)}#a(e){const t={},n=[];for(const[r,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(r==="path"){const i=s,a=[];for(const o of i)a.push(o.snippet);t.path=a}else if(r==="parameters"){const i=s;for(const a of i){let o=!1;for(const[c,l]of Object.entries(a))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(o=!0);else l.matched_tokens?.length&&(o=!0);if(o){const c={name:a.name?.snippet||"",description:a.description?.snippet||"",place:a.place?.snippet||"",path:a.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[r]=s.snippet,n.push(r);for(const[r,s]of Object.entries(e.document))!n.includes(r)&&typeof s=="string"&&(t[r]=s.length>b?`${s.substring(0,b)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const n=Object.keys(e.highlight);for(const s of O)if(n.some(i=>i===s))return e.document;const r=e.highlight.parameters;if(r){for(const s of r)for(const[i,a]of Object.entries(s))if(i!=="deepLink"){if(Array.isArray(a)){for(const o of a)if(o.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(a.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',n=d(m.join(e,F));for(const[r,s]of this.#s){if(s.length===0)continue;const i=d(m.join(n,`${r}.json`)),a=!I(i),o=JSON.stringify(s).substring(1).slice(0,-1),c=a?t+o:","+o;await g(i,c,{encoding:"utf8"}),this.#s.set(r,[])}}async exportIndexes(e){const t=d(m.join(e,F));for(const n of this.#s.keys()){const r=d(m.join(t,`${n}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await g(r,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await D("search.facets",async n=>{const{locale:r,query:s,facetQuery:i,filter:a,field:o}=e,c=this.#c(r),l={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(i,o),filter_by:this.#r(t,a,o),max_facet_values:S};if(n?.setAttribute("collectionName",c),n?.setAttribute("query",l.q),n?.setAttribute("facetQuery",l.facet_query),n?.setAttribute("filter",l.filter_by),this.#e){const u={},h=await this.#e.collections(c).documents().search(l);if(h.facet_counts&&h.facet_counts.length)for(const _ of h.facet_counts)u[_.field_name]=_.counts.map(y=>({value:y.value,count:y.count,isCounterVisible:!!s||(a?.length||0)>0}));return u}else return{}})}#c(e){return`${this.#o}${e}`}#p(e){for(const[t,{queryable:n}]of e)this.#t.find(r=>r.name===t)||this.#t.push({queryable:n,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===E).map(e=>e.name).join(",")}#r(e,t,n){const r=`${A}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const i=t.filter(o=>o.field!==n&&o.field!==f).map(o=>{const c=o.values.map(l=>`'${l}'`);return c.length?`${o.field}:[${c.join(", ")}]`:""}).join(" && "),a=t.find(o=>o.field===f);if(a&&a.values.length&&a.values.length===2){const o=a.values[0],c=a.values[1],l=`(${f}.folderId:! ${o} && ${f}.isDefault:true)`,u=`(${f}.folderId:${o} && ${f}.version:${c})`;s=`(${l} || ${u})`}return i?`${r} && ${i} && ${s}`:`${r} && ${s}`}else return`${r} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const n of e)n.field===E&&t.push(...n.values);return t}#y(e,t){const n=[],r=this.#t.filter(s=>s.facet);for(const s of r){const i={facet_by:s.name,filter_by:this.#r(e,t,s.name)};n.push(i)}return n}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(n=>{n.values=[]}),e.setSearchFacets(t)}}export{U as Typesense};
1
+ import{appendFile as g}from"node:fs/promises";import{existsSync as I}from"node:fs";import m from"node:path";import{Client as $}from"typesense";import{SEARCH_GROUP_FACET_FIELD as E,SEARCH_PRODUCT_FIELD as R,SEARCH_RBAC_FIELD as A,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as T,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as O,HIGHLIGHTED_TEXT_MAX_LENGTH as b,SEARCH_DATA_EXPORT_FOLDER as F,SEARCH_DOCUMENT_METADATA_KEY as P,SEARCH_GROUP_LIMIT as N,SEARCH_MAX_FACET_VALUES as S,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as C}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as D}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class U{#e=null;#r="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"deprecated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:R,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:A,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#r=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new $({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(T);const{locale:n,outDir:o}=t,s=e.map(i=>{const r={...i},c=i[P];return c&&(c.curated&&(r.metadata_curated=c.curated),c.excludes&&(r.metadata_keywords_excludes=c.excludes),c.includes&&(r.metadata_keywords_includes=c.includes)),r}),a=this.#s.get(n)??[];this.#s.set(n,a.concat(s)),a.length+e.length>=C&&await this.exportDocuments(o)}async search(e,t){return await D("search",async n=>{const{query:o,locale:s,filter:a,loadMore:i}=e,r=this.#c(s),c={collection:r,q:o||"*",query_by:this.#l(),max_facet_values:S};if(n?.setAttribute("collectionName",r),n?.setAttribute("locale",s),this.#e)if(i){const{groupKey:l,offset:u}=i,h={offset:u,filter_by:this.#o(t,a),facet_by:"*"};return n?.setAttribute("isLoadMore",!0),n?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(r).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:N,filter_by:this.#o(t,a)};n?.setAttribute("groups",l.group_by),n?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(t,a)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),a)}else return{facets:{},documents:{}}})}#u(e,t){const n={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const o of e.hits)n.documents[t].push({document:this.#a(o),highlight:this.#i(o)});return n}#f(e,t){const n={facets:{},documents:{}};for(const o of this.#_(t))n.documents[o]=[];if("results"in e)for(const o of e.results){if(o.facet_counts&&o.facet_counts.length)for(const s of o.facet_counts)n.facets[s.field_name]=s.counts.map(a=>({value:a.value,count:a.count}));if(o.grouped_hits&&o.grouped_hits.length)for(const s of o.grouped_hits){const a=s.group_key[0],i=[];for(const r of s.hits)i.push({document:this.#a(r),highlight:this.#i(r)});n.documents[a]=i}}return n}#a(e){return this.#h(e)}#i(e){const t={},n=[];for(const[o,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(o==="path"){const a=s,i=[];for(const r of a)i.push(r.snippet);t.path=i}else if(o==="parameters"){const a=s;for(const i of a){let r=!1;for(const[c,l]of Object.entries(i))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(r=!0);else l.matched_tokens?.length&&(r=!0);if(r){const c={name:i.name?.snippet||"",description:i.description?.snippet||"",place:i.place?.snippet||"",path:i.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[o]=s.snippet,n.push(o);for(const[o,s]of Object.entries(e.document))!n.includes(o)&&typeof s=="string"&&(t[o]=s.length>b?`${s.substring(0,b)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const n=Object.keys(e.highlight);for(const s of O)if(n.some(a=>a===s))return e.document;const o=e.highlight.parameters;if(o){for(const s of o)for(const[a,i]of Object.entries(s))if(a!=="deepLink"){if(Array.isArray(i)){for(const r of i)if(r.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(i.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',n=d(m.join(e,F));for(const[o,s]of this.#s){if(s.length===0)continue;const a=d(m.join(n,`${o}.json`)),i=!I(a),r=JSON.stringify(s).substring(1).slice(0,-1),c=i?t+r:","+r;await g(a,c,{encoding:"utf8"}),this.#s.set(o,[])}}async exportIndexes(e){const t=d(m.join(e,F));for(const n of this.#s.keys()){const o=d(m.join(t,`${n}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await g(o,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await D("search.facets",async n=>{const{locale:o,query:s,facetQuery:a,filter:i,field:r}=e,c=this.#c(o),l={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(a,r),filter_by:this.#o(t,i,r),max_facet_values:S};if(n?.setAttribute("collectionName",c),n?.setAttribute("query",l.q),n?.setAttribute("facetQuery",l.facet_query),n?.setAttribute("filter",l.filter_by),this.#e){const u={},h=await this.#e.collections(c).documents().search(l);if(h.facet_counts&&h.facet_counts.length)for(const _ of h.facet_counts)u[_.field_name]=_.counts.map(y=>({value:y.value,count:y.count,isCounterVisible:!!s||(i?.length||0)>0}));return u}else return{}})}#c(e){return`${this.#r}${e}`}#p(e){for(const[t,{queryable:n}]of e)this.#t.find(o=>o.name===t)||this.#t.push({queryable:n,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===E).map(e=>e.name).join(",")}#o(e,t,n){const o=`${A}:[${e.teams.map(a=>`'${a}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const a=t.filter(r=>r.field!==n&&r.field!==f).map(r=>{const c=r.values.map(l=>`'${l}'`);return c.length?`${r.field}:=[${c.join(", ")}]`:""}).join(" && "),i=t.find(r=>r.field===f);if(i&&i.values.length&&i.values.length===2){const r=i.values[0],c=i.values[1],l=`(${f}.folderId:! ${r} && ${f}.isDefault:true)`,u=`(${f}.folderId: ${r} && ${f}.version:='${c}')`;s=`(${l} || ${u})`}return a?`${o} && ${a} && ${s}`:`${o} && ${s}`}else return`${o} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const n of e)n.field===E&&t.push(...n.values);return t}#y(e,t){const n=[],o=this.#t.filter(s=>s.facet);for(const s of o){const a={facet_by:s.name,filter_by:this.#o(e,t,s.name)};n.push(a)}return n}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(n=>{n.values=[]}),e.setSearchFacets(t)}}export{U as Typesense};
@@ -1 +1 @@
1
- import{REDOCLY_TEAMS_RBAC as g}from"@redocly/config";import{DEFAULT_SEARCH_ENGINE as c}from"../../constants/plugins/search.js";import{envConfig as s}from"../../config/env-config.js";import{logger as p}from"../../tools/notifiers/logger.js";import{reporter as E}from"../../tools/notifiers/reporter.js";import{prepareSearchDocuments as u}from"./documents/search-documents.js";import{SearchEngine as S}from"./engines/search-engine.js";import{prepareSemanticDocuments as b}from"./ai-indexer/prepare-semantic-documents.js";import{isAiSearchEnabled as D,shouldGenerateEmbeddings as y}from"./utils.js";import{telemetryTraceStep as C}from"../../../cli/telemetry/helpers/trace-step.js";async function H(){let e=!0;return{async afterRoutesCreated(a,i){(s.SEARCH_DEV_REINIT||e)&&await A(a,i),e=!1},id:"search"}}async function A(e,a){await C("build.plugin.search",async i=>{const r=e.getConfig();if(i?.setAttribute("config",JSON.stringify(r.search||{})),r.search?.hide){p.info("Search is disabled in the config, skipping");return}const o=r.search?.engine||c,m=s.isDevelopMode?s.SEARCH_DEV_DEBUG?o:c:o,{l10n:f}=e.getGlobalData(),h=D(r),n=r.access?.rbac?.features?.aiSearch,l=y(r);let t;try{t=new S(m,f)}catch(d){await E.panic(d);return}await t.initIndexSchema(e.getSearchFacets()),e.setSearchEngine(t),e.setGlobalData({searchFeatures:{advanced:{enabled:m!==c&&!r.search?.filters?.hide},ai:{enabled:h,[g]:n&&Object.keys(n).length?n:void 0}}}),await u(a.fs,e,t),await b(e,a,{embeddingsEnabled:l,llmstxtEnabled:r.seo?.llmstxt?.hide!==!0})})}export{H as searchPlugin};
1
+ import{REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{DEFAULT_SEARCH_ENGINE as s}from"../../constants/plugins/search.js";import{envConfig as c}from"../../config/env-config.js";import{logger as E}from"../../tools/notifiers/logger.js";import{reporter as u}from"../../tools/notifiers/reporter.js";import{prepareSearchDocuments as S}from"./documents/search-documents.js";import{SearchEngine as b}from"./engines/search-engine.js";import{prepareSemanticDocuments as D}from"./ai-indexer/prepare-semantic-documents.js";import{isAiSearchEnabled as y,shouldGenerateEmbeddings as A}from"./utils.js";import{telemetryTraceStep as C}from"../../../cli/telemetry/helpers/trace-step.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";async function B(){let e=!0;return{async afterRoutesCreated(t,i){(c.SEARCH_DEV_REINIT||e)&&await _(t,i),e=!1},id:"search"}}async function _(e,t){await C("build.plugin.search",async i=>{const r=e.getConfig();if(i?.setAttribute("config",JSON.stringify(r.search||{})),r.search?.hide){E.info("Search is disabled in the config, skipping");return}const o=r.search?.engine||s,m=c.isDevelopMode?c.SEARCH_DEV_DEBUG?o:s:o,{l10n:l}=e.getGlobalData(),d=y(r),n=r.access?.rbac?.features?.aiSearch,f=A(r);let a;try{a=new b(m,l)}catch(g){await u.panic(g);return}await a.initIndexSchema(e.getSearchFacets()),e.setSearchEngine(a),e.setGlobalData({searchFeatures:{advanced:{enabled:m!==s&&!r.search?.filters?.hide},ai:{enabled:d,[p]:n&&Object.keys(n).length?n:void 0}}}),await S(t.fs,e,a);const h=R.instance().canAccessFeature("seo")===!0&&r.seo?.llmstxt?.hide!==!0;await D(e,t,{embeddingsEnabled:f,llmstxtEnabled:h})})}export{B as searchPlugin};
@@ -1 +1 @@
1
- import{DEFAULT_SSO_IDP_TITLE as u}from"../../../constants/common.js";import{envConfig as a}from"../../config/env-config.js";import{telemetryTraceStep as g}from"../../../cli/telemetry/helpers/trace-step.js";const y="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",C="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function I(O){return{id:"sso",async processContent(t){await g("build.plugin.sso",async l=>{const s=t.getConfig(),o=s.access;if(l?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(s.ssoDirect||{})}}, {"sso": ${JSON.stringify(o?.sso||{})}}`),s.ssoDirect&&typeof s.ssoDirect=="object"&&Object.keys(s.ssoDirect).length!==0||o?.sso&&Array.isArray(o.sso)&&!o.sso.length)return;const p=!!(o?.rbac&&typeof o.rbac=="object"&&Object.keys(o.rbac).length!==0),d=o?.requiresLogin;if(!p&&!d)return;let n=y,c=a.REDOCLY_OAUTH_USE_INTROSPECT?C:"";const e=o?.residency;if(e){const r=e.endsWith("/")?e.slice(0,-1):e;n=`${r.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,c=a.REDOCLY_OAUTH_USE_INTROSPECT?`${r}/api/sso/oidc/introspect`:""}let i="AUTO";o?.sso&&(Array.isArray(o.sso)?i=o.sso.join(","):i=o.sso);const f={oidc:{title:u,type:"OIDC",configurationUrl:n,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:{login_hint:"{{ process.env.ORGANIZATION_ID }}",login_type:i,prompt:"login"},audience:"{{ process.env.ORGANIZATION_ID }}",introspectEndpoint:c}};t.setGlobalConfig({ssoDirect:f})})},async afterRoutesCreated(t){}}}export{I as ssoPlugin};
1
+ import{DEFAULT_SSO_IDP_TITLE as A}from"../../../constants/common.js";import{envConfig as d}from"../../config/env-config.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{logger as C}from"../../tools/notifiers/logger.js";const O="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",_="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function S(T){return{id:"sso",async processContent(i){await I("build.plugin.sso",async f=>{const o=i.getConfig(),s=o.access;if(f?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(s?.sso||{})}}, {"idps": ${JSON.stringify(s?.idps||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0)return;const y=!!s?.sso&&(Array.isArray(s.sso)?s.sso.length>0:!0),r=!!s?.idps&&(Array.isArray(s.idps)?s.idps.length>0:!0);if(s?.sso&&Array.isArray(s.sso)&&!s.sso.length&&!r)return;const g=!!(s?.rbac&&typeof s.rbac=="object"&&Object.keys(s.rbac).length!==0),u=s?.requiresLogin;if(!g&&!u)return;y&&r&&C.error("access.sso and access.idps both set \u2014 should have been rejected by config validation",{sso:s.sso,idps:s.idps});let c=O,a=d.REDOCLY_OAUTH_USE_INTROSPECT?_:"";const e=s?.residency;if(e){const l=e.endsWith("/")?e.slice(0,-1):e;c=`${l.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,a=d.REDOCLY_OAUTH_USE_INTROSPECT?`${l}/api/sso/oidc/introspect`:""}let n="AUTO";s?.sso&&(Array.isArray(s.sso)?n=s.sso.join(","):n=s.sso);let t="";s?.idps&&(Array.isArray(s.idps)?t=s.idps.join(","):t=s.idps);const p={login_hint:"{{ process.env.ORGANIZATION_ID }}",login_type:n,prompt:"login"};t&&(p.login_idps=t);const m={oidc:{title:A,type:"OIDC",configurationUrl:c,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:p,audience:"{{ process.env.ORGANIZATION_ID }}",introspectEndpoint:a}};i.setGlobalConfig({ssoDirect:m})})},async afterRoutesCreated(i){}}}export{S as ssoPlugin};
@@ -1 +1 @@
1
- import{reporter as f}from"../../tools/notifiers/reporter.js";import{MARKDOC_PARTIALS_DATA_KEY as u}from"../../store.js";async function c(r,e,n,i,l,o,a){const m=!!e?.props?.compilationErrors?.length,s=r?.serverPropsGetterIds;return s?.length?Promise.all(s.map(async t=>{const p=l[t];if(!p){if(m)return{...e.props};await f.panicOnBuild(`Invalid server props getter id: "${t}" for route "${r.slug}"`)}return await(await p()).default({...r,...a},e,{variables:{...n,pageProps:i},partials:o.getGlobalConfig(u)},o)})||[]):[]}export{c as getServerPropsFromSystemHandlers};
1
+ import{reporter as f}from"../../tools/notifiers/reporter.js";import{MARKDOC_PARTIALS_DATA_KEY as u}from"../../constants/common.js";async function c(r,e,n,i,l,o,a){const m=!!e?.props?.compilationErrors?.length,s=r?.serverPropsGetterIds;return s?.length?Promise.all(s.map(async t=>{const p=l[t];if(!p){if(m)return{...e.props};await f.panicOnBuild(`Invalid server props getter id: "${t}" for route "${r.slug}"`)}return await(await p()).default({...r,...a},e,{variables:{...n,pageProps:i},partials:o.getGlobalConfig(u)},o)})||[]):[]}export{c as getServerPropsFromSystemHandlers};
@@ -9,8 +9,6 @@ import type { BundledDefinition as AsyncApiBundledDefinition } from './plugins/a
9
9
  import type { BundledDefinition as GraphqlBundledDefinition } from './plugins/graphql-docs/graphql-doc-loader.js';
10
10
  import type { SearchEngine } from './plugins/search/engines/search-engine.js';
11
11
  import { KvService } from './persistence/kv/services/kv-service.js';
12
- export declare const MARKDOC_PARTIALS_DATA_KEY = "markdown/partials";
13
- export declare const MARKDOC_PARTIALS_DEPS_KEY = "markdown/partials-deps";
14
12
  export declare const USER_DEFINED_API_FUNCTIONS_COUNTER_KEY = "userDefinedApiFunctions";
15
13
  type LifecycleEventType = 'global-data-updated' | 'shared-data-updated' | 'routes-updated' | 'build-updated' | 'build-started' | 'errors-updated' | 'pages-updated';
16
14
  export type StoreOptions = {
@@ -80,10 +78,14 @@ export declare class Store {
80
78
  queueEvent: <T extends Array<unknown>>(type: LifecycleEventType, id?: string, ...args: T) => void;
81
79
  runListeners: <T extends Array<unknown>>(type: LifecycleEventType, id?: string, ...args: T) => void;
82
80
  startPluginsRun(): void;
83
- waitForPluginsLifecycle(): Promise<[void, void]>;
81
+ waitForPluginsLifecycle(): Promise<[void, void, void]>;
82
+ waitForPluginsRun(): Promise<void>;
84
83
  finishPluginsRun(): void;
85
84
  startEsbuildRun(): void;
86
85
  finishEsbuildRun(): void;
86
+ markRequestHandlersEntryOutdated(): void;
87
+ noteRequestHandlersEntryBuildStart(): void;
88
+ markRequestHandlersEntryUpdated(): void;
87
89
  get contentDir(): string;
88
90
  markUserCodeReady(): void;
89
91
  reloadMarkdocOptions(): Promise<void>;