@redocly/realm 0.130.0-next.1 → 0.130.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/develop.js +1 -1
  4. package/dist/cli/eject/resolveEjectParams.js +1 -1
  5. package/dist/cli/prepare/copy-env-files.js +1 -1
  6. package/dist/cli/stats/collectors/openapi.d.ts +3 -0
  7. package/dist/cli/stats/collectors/openapi.js +1 -0
  8. package/dist/cli/stats/index.d.ts +7 -0
  9. package/dist/cli/stats/index.js +1 -0
  10. package/dist/cli/stats/options.d.ts +3 -0
  11. package/dist/cli/stats/options.js +1 -0
  12. package/dist/cli/telemetry/index.d.ts +2 -2
  13. package/dist/cli/telemetry/index.js +1 -1
  14. package/dist/client/ErrorBoundary.js +1 -1
  15. package/dist/client/app/Sidebar/RequestAccessButton.js +2 -2
  16. package/dist/client/app/Sidebar/Sidebar.js +2 -2
  17. package/dist/client/app/hooks/catalog/useCatalogClassic.js +1 -1
  18. package/dist/client/app/hooks/catalog/useCatalogFilter.js +1 -1
  19. package/dist/client/app/hooks/catalog/useCatalogViewMode.js +1 -1
  20. package/dist/client/app/hooks/catalog/useSearchTracker.js +1 -1
  21. package/dist/client/app/hooks/usePageTimeTracker.js +1 -1
  22. package/dist/client/app/hooks/useRouteChangeTracker.js +1 -1
  23. package/dist/client/app/hooks/useTelemetry.d.ts +2 -2
  24. package/dist/client/app/pages/DevLogin/DevLogin.js +1 -1
  25. package/dist/client/app/search/useAiSearch.js +1 -1
  26. package/dist/client/app/search/useSearch.js +1 -1
  27. package/dist/client/app/telemetry/index.d.ts +11 -1
  28. package/dist/client/app/telemetry/index.js +1 -1
  29. package/dist/client/browser-entry.js +3 -3
  30. package/dist/constants/common.d.ts +3 -1
  31. package/dist/constants/common.js +1 -1
  32. package/dist/constants/l10n/langs/ar.js +1 -1
  33. package/dist/constants/l10n/langs/de.js +1 -1
  34. package/dist/constants/l10n/langs/en.js +1 -1
  35. package/dist/constants/l10n/langs/es.js +1 -1
  36. package/dist/constants/l10n/langs/fr.js +1 -1
  37. package/dist/constants/l10n/langs/hi.js +1 -1
  38. package/dist/constants/l10n/langs/it.js +1 -1
  39. package/dist/constants/l10n/langs/ja.js +1 -1
  40. package/dist/constants/l10n/langs/ko.js +1 -1
  41. package/dist/constants/l10n/langs/pl.js +1 -1
  42. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  43. package/dist/constants/l10n/langs/pt.js +1 -1
  44. package/dist/constants/l10n/langs/ru.js +1 -1
  45. package/dist/constants/l10n/langs/uk.js +1 -1
  46. package/dist/constants/l10n/langs/zh.js +1 -1
  47. package/dist/server/api-routes/execute-api-route.js +1 -1
  48. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  49. package/dist/server/constants/plugins/catalog-entities.d.ts +1 -0
  50. package/dist/server/constants/plugins/catalog-entities.js +1 -1
  51. package/dist/server/esbuild/esbuild.js +3 -3
  52. package/dist/server/fs/cache.js +1 -1
  53. package/dist/server/node-bundle-entry.js +1 -1
  54. package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +1 -0
  55. package/dist/server/persistence/kv/repositories/kv-remote-repository.js +2 -1
  56. package/dist/server/persistence/kv/services/kv-service.js +1 -1
  57. package/dist/server/plugins/asyncapi-docs/store-definition-bundles.js +1 -1
  58. package/dist/server/plugins/asyncapi-docs/template/AsyncApiDocs.js +5 -3
  59. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +11 -12
  60. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  61. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +8 -0
  62. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.js +1 -0
  63. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.d.ts +1 -1
  64. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-read-model.js +1 -1
  65. package/dist/server/plugins/catalog-entities/database/mappers/map-entity-relation-row.js +1 -1
  66. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +27 -0
  67. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.js +1 -0
  68. package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.d.ts +36 -0
  69. package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.js +1 -0
  70. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.d.ts +2 -2
  71. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.js +34 -27
  72. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +5 -4
  73. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +27 -14
  74. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +10 -8
  75. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  76. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.d.ts +3 -1
  77. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  78. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -1
  79. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.d.ts +2 -5
  80. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  81. package/dist/server/plugins/catalog-entities/database/repositories/utils/create-merged-entity-fields-for-select.d.ts +34 -0
  82. package/dist/server/plugins/catalog-entities/database/repositories/utils/create-merged-entity-fields-for-select.js +13 -0
  83. package/dist/server/plugins/catalog-entities/database/repositories/utils/normalize-revision-flags.d.ts +23 -0
  84. package/dist/server/plugins/catalog-entities/database/repositories/utils/normalize-revision-flags.js +1 -0
  85. package/dist/server/plugins/catalog-entities/database/repositories/utils/semantic-version-sort.d.ts +78 -0
  86. package/dist/server/plugins/catalog-entities/database/repositories/utils/semantic-version-sort.js +34 -0
  87. package/dist/server/plugins/catalog-entities/entities/validate-entity.d.ts +3 -1
  88. package/dist/server/plugins/catalog-entities/entities/validate-entity.js +1 -1
  89. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  90. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  91. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +4 -3
  92. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  93. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  94. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +1 -1
  95. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  96. package/dist/server/plugins/catalog-entities/get-server-props.js +1 -1
  97. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  98. package/dist/server/plugins/catalog-entities/schemas/database-schemas.d.ts +3 -0
  99. package/dist/server/plugins/catalog-entities/schemas/database-schemas.js +1 -1
  100. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.d.ts +15 -1
  101. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.js +1 -1
  102. package/dist/server/plugins/catalog-entities/schemas/read-model-schemas.d.ts +1 -0
  103. package/dist/server/plugins/catalog-entities/types/extractors.d.ts +4 -4
  104. package/dist/server/plugins/catalog-entities/utils/ajv-validator.js +1 -1
  105. package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
  106. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  107. package/dist/server/plugins/default-theme/index.js +1 -1
  108. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.d.ts +54 -0
  109. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +1 -0
  110. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +9 -8
  111. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
  112. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.d.ts +9 -8
  113. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
  114. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.d.ts +9 -8
  115. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
  116. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.d.ts +9 -8
  117. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
  118. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +7 -13
  119. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  120. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +9 -6
  121. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.js +1 -1
  122. package/dist/server/plugins/mcp/docs-mcp/tools/search.d.ts +9 -2
  123. package/dist/server/plugins/mcp/docs-mcp/tools/search.js +1 -1
  124. package/dist/server/plugins/mcp/docs-mcp/tools/utils.d.ts +2 -1
  125. package/dist/server/plugins/mcp/docs-mcp/tools/utils.js +6 -6
  126. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.d.ts +9 -2
  127. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.js +1 -1
  128. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  129. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  130. package/dist/server/plugins/mcp/handlers/handle-mcp-request.d.ts +5 -0
  131. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -0
  132. package/dist/server/plugins/mcp/handlers/mcp-request-handler.d.ts +0 -1
  133. package/dist/server/plugins/mcp/handlers/mcp-request-handler.js +1 -1
  134. package/dist/server/plugins/mcp/servers/base-server.js +1 -1
  135. package/dist/server/plugins/mcp/types.d.ts +40 -0
  136. package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +3 -0
  137. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -0
  138. package/dist/server/plugins/openapi-docs/index.js +1 -1
  139. package/dist/server/plugins/openapi-docs/template/OpenAPIDocs.js +8 -4
  140. package/dist/server/plugins/openapi-docs/template/helpers.d.ts +1 -1
  141. package/dist/server/plugins/openapi-docs/template/helpers.js +3 -3
  142. package/dist/server/plugins/scorecard-classic/loaders/scorecard-config.js +1 -1
  143. package/dist/server/plugins/scorecard-classic/types.d.ts +3 -3
  144. package/dist/server/plugins/scorecard-classic/types.js +1 -1
  145. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.d.ts +12 -0
  146. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.js +1 -0
  147. package/dist/server/plugins/scorecards/database/scorecards-config-service.d.ts +11 -0
  148. package/dist/server/plugins/scorecards/database/scorecards-config-service.js +1 -0
  149. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.d.ts +2 -1
  150. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.js +1 -1
  151. package/dist/server/plugins/scorecards/workers/scorecards.d.ts +1 -12
  152. package/dist/server/plugins/scorecards/workers/scorecards.js +1 -1
  153. package/dist/server/plugins/search/ai-indexer/prepare-ai-search-documents.js +1 -1
  154. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  155. package/dist/server/plugins/sso/index.js +1 -1
  156. package/dist/server/providers/database/base-repository.d.ts +1 -0
  157. package/dist/server/providers/database/base-repository.js +1 -1
  158. package/dist/server/providers/database/database-connection-factory.js +1 -1
  159. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0005_catalog-relations-constraint-fix.sql +2 -0
  160. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0006_add-catalog-entitities-attributes-table.sql +11 -0
  161. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0005_snapshot.json +393 -0
  162. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0006_snapshot.json +458 -0
  163. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/_journal.json +14 -0
  164. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.d.ts +143 -0
  165. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js +1 -0
  166. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js +1 -1
  167. package/dist/server/providers/database/databases/main-sqlite/migrations/0006_change-scorecards-config-timestamps-field-types.sql +19 -0
  168. package/dist/server/providers/database/databases/main-sqlite/migrations/meta/0006_snapshot.json +261 -0
  169. package/dist/server/providers/database/databases/main-sqlite/migrations/meta/_journal.json +7 -0
  170. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.d.ts +24 -18
  171. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.js +1 -1
  172. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0007_catalog-relations-constraint-fix.sql +2 -0
  173. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0008_add-catalog-entitities-attributes-table.sql +11 -0
  174. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0007_snapshot.json +833 -0
  175. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0008_snapshot.json +898 -0
  176. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/_journal.json +14 -0
  177. package/dist/server/providers/database/pagination/entities-to-filter.d.ts +15 -0
  178. package/dist/server/providers/database/pagination/entities-to-filter.js +1 -0
  179. package/dist/server/providers/database/pagination/utils/index.d.ts +4 -0
  180. package/dist/server/providers/database/pagination/utils/index.js +1 -1
  181. package/dist/server/providers/database/pagination/utils/is-nested-condition.d.ts +16 -0
  182. package/dist/server/providers/database/pagination/utils/is-nested-condition.js +1 -0
  183. package/dist/server/providers/database/pagination/utils/is-simple-condition.d.ts +18 -0
  184. package/dist/server/providers/database/pagination/utils/is-simple-condition.js +1 -0
  185. package/dist/server/providers/database/pagination/utils/map-operator.d.ts +10 -0
  186. package/dist/server/providers/database/pagination/utils/map-operator.js +1 -0
  187. package/dist/server/providers/database/pagination/utils/transform-condition.d.ts +12 -0
  188. package/dist/server/providers/database/pagination/utils/transform-condition.js +1 -0
  189. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.js +1 -1
  190. package/dist/server/store.d.ts +3 -1
  191. package/dist/server/store.js +1 -1
  192. package/dist/server/tools/notifiers/logger.js +1 -1
  193. package/dist/server/tools/notifiers/reporter.js +7 -7
  194. package/dist/server/types/plugins/common.d.ts +3 -1
  195. package/dist/server/types/plugins/scorecards.d.ts +30 -0
  196. package/dist/server/types/plugins/scorecards.js +0 -0
  197. package/dist/server/utils/envs/load-env-variables.d.ts +1 -1
  198. package/dist/server/utils/envs/load-env-variables.js +1 -1
  199. package/dist/server/utils/envs/sanitize-branch-name.d.ts +6 -0
  200. package/dist/server/utils/envs/sanitize-branch-name.js +1 -0
  201. package/dist/server/utils/lifecycle-hooks.js +1 -1
  202. package/dist/server/utils/rbac.d.ts +11 -7
  203. package/dist/server/utils/rbac.js +1 -1
  204. package/dist/server/utils/time/with-timestamp.d.ts +42 -10
  205. package/dist/server/utils/time/with-timestamp.js +1 -1
  206. package/dist/server/web-server/auth.js +2 -2
  207. package/dist/server/web-server/dev-server.js +1 -1
  208. package/dist/server/web-server/handle-api-route-request.js +1 -1
  209. package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
  210. package/dist/server/web-server/routes/auth.js +1 -1
  211. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  212. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  213. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  214. package/dist/server/web-server/routes/mcp-oauth.js +1 -1
  215. package/dist/server/web-server/routes/page-data.js +1 -1
  216. package/dist/server/workers/mcp-tool-worker-pool.d.ts +4 -0
  217. package/dist/server/workers/mcp-tool-worker-pool.js +1 -0
  218. package/dist/server/workers/mcp-tool-worker.d.ts +2 -0
  219. package/dist/server/workers/mcp-tool-worker.js +1 -0
  220. package/dist/server/workers/types.d.ts +7 -1
  221. package/dist/utils/env/is-local-development.js +1 -1
  222. package/package.json +15 -18
  223. package/dist/server/plugins/mcp/workers/run-api-routes-worker.d.ts +0 -5
  224. package/dist/server/plugins/mcp/workers/run-api-routes-worker.js +0 -1
  225. package/dist/server/workers/mcp-worker-pool.d.ts +0 -4
  226. package/dist/server/workers/mcp-worker-pool.js +0 -1
@@ -1 +1 @@
1
- import{FileType as c}from"../../persistence/file-hashes/types.js";import{telemetryTraceStep as _}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as P}from"./utils/catalog-data-collector.js";import{CATALOG_BASE_SLUG as p,CATALOG_FILTERS_CACHE_NAMESPACE as I,ENTITIES_MAP_GLOBAL_DATA_KEY as v}from"../../constants/plugins/catalog-entities.js";import{CacheService as h}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as E}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as N}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as b}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as L}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as w}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as R}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as G}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as x}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as F}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as B}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const H="catalog-entity-template",M="catalog-entity";let u=!0;async function Y(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(t,i){await _("build.plugin.catalog_entities",async r=>{if(process.env.NEW_CATALOG_ENABLED!=="true")return;const f=await i.getConfig(),s=N(f.entitiesCatalog);if(r?.setAttribute("config",JSON.stringify(s)),!s.show)return;const{logger:l}=i,A=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",a=u&&A,e=await R.getInstance({baseDbDir:t.serverOutDir,removeExisting:a,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),C=await w.getInstance({baseDbDir:t.serverOutDir}),o=new F(C),T=[new x({fileHashManager:o,context:i,catalogEntitiesService:e,catalogConfig:s,shouldCalculateEntities:a}),new B({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.OPENAPI_DESCRIPTION,shouldCalculateEntities:a}),new b({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:a}),new L({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.GRAPHQL_DESCRIPTION,shouldCalculateEntities:a}),new G({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ARAZZO_DESCRIPTION,shouldCalculateEntities:a})];l.info("Starting entities extractors...");const y=l.startTiming();await e.transaction(async()=>{await Promise.all(T.map(async m=>m.extract()))});const d=e.getEntitySources();t.setGlobalData({[v]:d}),await(await h.getInstance({baseDbDir:t.serverOutDir})).deleteByNamespace(I),l.infoTime(y,"Entities extractors finished");const S=t.registerServerPropsGetter(M,E("../get-server-props.js")),D=t.createTemplate(H,E("../template/index.js"));t.addRoute({duplicateInAllLocales:!0,slug:p,fsPath:"",templateId:D,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[S],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:s}})});const[g]=Object.entries(s.catalogs??{}).find(([m,O])=>!O?.hide)||[];g&&t.addRedirect(p,{type:302,to:`${p}/${g}`});const n=await P.getCatalogEntitiesData(e);r?.setAttribute("totalEntities",n.totalEntitiesCount),r?.setAttribute("entitiesCountByType",JSON.stringify(n.countOfEntitiesByType)),r?.setAttribute("totalFilesSkippedByHash",n.totalFilesSkippedByHash),r?.setAttribute("totalProcessedFiles",n.totalProcessedFiles),r?.setAttribute("extractors",n.extractors),l.info("Catalog Entities plugin finished"),u=!1})}}}var rt=Y;export{Y as catalogEntitiesPlugin,rt as default};
1
+ import{FileType as u}from"../../persistence/file-hashes/types.js";import{deepEqual as O}from"../../../utils/object/deep-equal.js";import{telemetryTraceStep as P}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as I}from"./utils/catalog-data-collector.js";import{CATALOG_BASE_SLUG as m,CATALOG_FILTERS_CACHE_NAMESPACE as _,ENTITIES_MAP_GLOBAL_DATA_KEY as b}from"../../constants/plugins/catalog-entities.js";import{CacheService as v}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as f}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as C}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as w}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as N}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as R}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as L}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as G}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as x}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as F}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as H}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const B="catalog-entity-template",M="catalog-entity";let d=!0,A;async function Y(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(t,e){const i=await e.getConfig(),r=C(i.entitiesCatalog);if(!r.show)return;const{logger:o}=e,n=t.registerServerPropsGetter(M,f("../get-server-props.js")),p=t.createTemplate(B,f("../template/index.js"));t.addRoute({duplicateInAllLocales:!0,slug:m,fsPath:"",templateId:p,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[n],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([E,s])=>!s?.hide)||[];l&&t.addRedirect(m,{type:302,to:`${m}/${l}`}),o.info("Catalog Entities plugin finished")},async afterRoutesCreated(t,e){await P("build.plugin.catalog_entities",async i=>{const r=await e.getConfig(),o=C(r.entitiesCatalog);if(i?.setAttribute("config",JSON.stringify(o)),!o.show)return;const{logger:n}=e,p=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",l=d&&p,E=!O(A,r.rbac);A=r.rbac;const s=l||E,a=await L.getInstance({baseDbDir:t.serverOutDir,removeExisting:l,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),T=await R.getInstance({baseDbDir:t.serverOutDir}),c=new F(T),y=[new x({fileHashManager:c,context:e,catalogEntitiesService:a,catalogConfig:o,shouldCalculateEntities:s}),new H({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.OPENAPI_DESCRIPTION,shouldCalculateEntities:s}),new w({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:s}),new N({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.GRAPHQL_DESCRIPTION,shouldCalculateEntities:s}),new G({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.ARAZZO_DESCRIPTION,shouldCalculateEntities:s})];n.info("Starting entities extractors...");const h=n.startTiming();await a.transaction(async()=>{await Promise.all(y.map(async D=>D.extract()))});const S=a.getEntitySources();t.setGlobalData({[b]:S}),await(await v.getInstance({baseDbDir:t.serverOutDir})).deleteByNamespace(_),n.infoTime(h,"Entities extractors finished");const g=await I.getCatalogEntitiesData(a);i?.setAttribute("totalEntities",g.totalEntitiesCount),i?.setAttribute("entitiesCountByType",JSON.stringify(g.countOfEntitiesByType)),i?.setAttribute("totalFilesSkippedByHash",g.totalFilesSkippedByHash),i?.setAttribute("totalProcessedFiles",g.totalProcessedFiles),i?.setAttribute("extractors",g.extractors),d=!1})}}}var rt=Y;export{Y as catalogEntitiesPlugin,rt as default};
@@ -129,6 +129,9 @@ export declare const entityDatabaseSchema: {
129
129
  readonly is_deleted: {
130
130
  readonly type: readonly ["boolean", "null"];
131
131
  };
132
+ readonly rbac_teams: {
133
+ readonly type: readonly ["string", "null"];
134
+ };
132
135
  };
133
136
  readonly required: readonly ["id", "organization_id", "project_id", "key", "type", "title", "created_at", "updated_at", "source"];
134
137
  readonly additionalProperties: false;
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]},is_deleted:{type:["boolean","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},r={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1},s={type:"object",properties:{id:{type:"string",minLength:1},key:{type:"string",minLength:1},title:{type:"string",minLength:1},type:{type:"string",minLength:1},summary:{type:["string","null"]},source:{type:"string",minLength:1},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","object","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},direction:{type:"string",enum:["outgoing","incoming"]},relation_field:{type:"string",minLength:1}},required:["id","key","title","type","source","direction","relation_field"],additionalProperties:!1};export{n as entityDatabaseSchema,i as entityRelationDatabaseSchema,r as relatedEntityDatabaseSchema,s as relatedEntityQueryRowDatabaseSchema};
1
+ import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]},is_deleted:{type:["boolean","null"]},rbac_teams:{type:["string","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},r={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1},s={type:"object",properties:{id:{type:"string",minLength:1},key:{type:"string",minLength:1},title:{type:"string",minLength:1},type:{type:"string",minLength:1},summary:{type:["string","null"]},source:{type:"string",minLength:1},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","object","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},direction:{type:"string",enum:["outgoing","incoming"]},relation_field:{type:"string",minLength:1}},required:["id","key","title","type","source","direction","relation_field"],additionalProperties:!1};export{n as entityDatabaseSchema,i as entityRelationDatabaseSchema,r as relatedEntityDatabaseSchema,s as relatedEntityQueryRowDatabaseSchema};
@@ -1,5 +1,16 @@
1
1
  import { type EntityBaseFileSchema } from '@redocly/config';
2
2
  import type { FromSchema } from 'json-schema-to-ts';
3
+ export declare const entityAttributesDtoSchema: {
4
+ readonly type: "object";
5
+ readonly properties: {
6
+ readonly rbacTeams: {
7
+ readonly type: "array";
8
+ readonly items: {
9
+ readonly type: "string";
10
+ };
11
+ };
12
+ };
13
+ };
3
14
  export declare const entityRelationDtoSchema: {
4
15
  readonly type: "object";
5
16
  readonly properties: {
@@ -89,5 +100,8 @@ export declare const entitiesRelationsDtoSchema: {
89
100
  };
90
101
  export type EntityRelationDtoSchema = FromSchema<typeof entityRelationDtoSchema>;
91
102
  export type EntitiesRelationsDtoSchema = FromSchema<typeof entitiesRelationsDtoSchema>;
92
- export type EntityDtoSchema = EntityBaseFileSchema;
103
+ export type EntityDtoSchema = EntityBaseFileSchema & {
104
+ revision?: string;
105
+ };
106
+ export type EntityAttributesDtoSchema = FromSchema<typeof entityAttributesDtoSchema>;
93
107
  //# sourceMappingURL=dto-schemas.d.ts.map
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]},isDeleted:{type:["boolean","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},i={type:"array",items:t};export{i as entitiesRelationsDtoSchema,t as entityRelationDtoSchema};
1
+ import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const n={type:"object",properties:{rbacTeams:{type:"array",items:{type:"string"}}}},t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]},isDeleted:{type:["boolean","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},i={type:"array",items:t};export{i as entitiesRelationsDtoSchema,n as entityAttributesDtoSchema,t as entityRelationDtoSchema};
@@ -177,6 +177,7 @@ export type EntityReadModelSchema = {
177
177
  object: 'catalogEntity';
178
178
  domains?: RelatedEntitySchema[];
179
179
  owners?: RelatedEntitySchema[];
180
+ rbacTeams?: string[] | null;
180
181
  };
181
182
  export type EntityRevisionSummary = Pick<EntityReadModelSchema, 'version' | 'revision' | 'isCurrent' | 'createdAt' | 'updatedAt' | 'isDefaultVersion' | 'isDeleted'>;
182
183
  //# sourceMappingURL=read-model-schemas.d.ts.map
@@ -1,13 +1,13 @@
1
1
  import type { ApiDescriptionMetadataSchema } from '@redocly/config';
2
- import type { ProcessContentActions } from '../../../types/plugins/common';
3
- import type { LifecycleContext } from '../../../types/plugins/common';
2
+ import type { AfterRoutesCreatedActions } from '../../../types/plugins/common';
3
+ import type { AfterRoutesCreatedLifecycleContext } from '../../../types/plugins/common';
4
4
  import type { CatalogEntitiesService } from '../database/catalog-entities-service.js';
5
5
  import type { FileType } from '../../../persistence/file-hashes/types.js';
6
6
  import type { HashManager } from '../utils/hash-manager.js';
7
7
  export type SpecType = Exclude<ApiDescriptionMetadataSchema['specType'], 'jsonschema' | 'avro' | 'zod' | 'protobuf'>;
8
8
  export type BaseApiEntitiesExtractorParams = {
9
- actions: ProcessContentActions;
10
- context: LifecycleContext;
9
+ actions: AfterRoutesCreatedActions;
10
+ context: AfterRoutesCreatedLifecycleContext;
11
11
  catalogEntitiesService: CatalogEntitiesService;
12
12
  fileHashManager: HashManager;
13
13
  fileType: FileType;
@@ -1 +1 @@
1
- import d from"@redocly/ajv";const o=new d({coerceTypes:!0,removeAdditional:!0,discriminator:!0,allErrors:!0});o.addFormat("uri",{type:"string",validate:e=>{try{return new URL(e),!0}catch{return!1}}}),o.addFormat("email",{type:"string",validate:e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)});function f(e,t){const{errorPrefix:n,dataVar:a="data"}=t??{},r=o.compile(e);return function(i){if(!r(i)){const c=r.errors?.length?r.errors.map(s=>{const u=s.instancePath.replaceAll("/",".");return`'${a}${u}' ${s.message}`}).join(", "):"unknown error",l=n?`${n} `:"";throw new Error(`${l}${c}`)}return i}}function h(e,t){const n=o.compile(e),a=n(t);return{success:a,data:a?t:void 0,error:a?void 0:n.errors?.map(r=>`${r.instancePath} ${r.message}`).join(", ")}}export{f as createValidator,h as validateWithResult};
1
+ import u from"@redocly/ajv";const o=new u({coerceTypes:!0,removeAdditional:!0,discriminator:!0,allErrors:!0});o.addKeyword({keyword:"nodeTypeName",schemaType:"string"}),o.addFormat("uri",{type:"string",validate:e=>{try{return new URL(e),!0}catch{return!1}}}),o.addFormat("email",{type:"string",validate:e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)});function f(e,t){const{errorPrefix:a,dataVar:n="data"}=t??{},r=o.compile(e);return function(i){if(!r(i)){const c=r.errors?.length?r.errors.map(s=>{const l=s.instancePath.replaceAll("/",".");return`'${n}${l}' ${s.message}`}).join(", "):"unknown error",d=a?`${a} `:"";throw new Error(`${d}${c}`)}return i}}function h(e,t){const a=o.compile(e),n=a(t);return{success:n,data:n?t:void 0,error:n?void 0:a.errors?.map(r=>`${r.instancePath} ${r.message}`).join(", ")}}export{f as createValidator,h as validateWithResult};
@@ -1 +1 @@
1
- import f from"path";import{combineUrls as p}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as S}from"../../../constants/common.js";import{removeTrailingSlash as d}from"../../../../utils/url/remove-trailing-slash.js";import{slash as b}from"../../../../utils/path/slash.js";import{logger as c}from"../../../tools/notifiers/logger.js";import{getDefaultVersionByPath as v}from"./versions-config-loader.js";import{GithubSlugger as D,slug as E}from"../../../utils/index.js";import{parseBaseName as F}from"../../utils.js";const I=new Set([".jpg",".jpeg",".png",".gif",".webp",".svg",".ico",".avif",".mp3",".wav",".ogg",".m4a",".mp4",".avi",".mov",".webm",".pdf",".doc",".docx",".zip",".rar",".gz",".ttf",".woff",".woff2"]),A=async(i,{fs:e,cache:s})=>{const g=c.startTiming(),o=(await s.load("versions-config","versions-config")).data,t=new Map,n=new Map,r=new Set,l=new D;n.set(".","/"),n.set("/","/");const u=e.scan().sort((a,m)=>m.relativePath.localeCompare(a.relativePath));for(const{relativePath:a}of u){if(I.has(f.posix.extname(a)))continue;const{data:m}=await s.load(a,"is-ignored");if(m)continue;const h=b(a).replace(new RegExp("^(@i18n|@l10n)\\/"),""),w=v(a,o);N(h,{defaultVersion:w,fileSlugs:t,dirSlugs:n,allFileSlugsList:r,githubSlugger:l})}return c.verboseTime(g,"Calculated slugs. Number of file paths processed: "+u.length),{fileSlugs:t,dirSlugs:n}};function N(i,e){const s=e.fileSlugs.get(i);if(s)return s;let g=f.posix.dirname(i);const o=z(g,e)||"",{baseName:t,isIndexFile:n}=F(i),r=e.dirSlugs.has(f.posix.join(g,t));let l;if(!n&&r){const u=E(p(o,t,"/"));e.allFileSlugsList.has(u)||(l=u)}l||(l=n&&e.dirSlugs.get(g)||e.githubSlugger.slug(p(o,t))),l=d(l),e.fileSlugs.set(i,l),e.allFileSlugsList.add(l)}function z(i,e){if(e.dirSlugs.has(i))return e.dirSlugs.get(i);const s=d(f.posix.normalize(i)).split("/");let g="/",o="";for(const t of s){o=f.posix.join(o,t);const n=T(t,e.defaultVersion);let r=e.dirSlugs.get(o)||e.githubSlugger.slug(p("/",g,n));r.endsWith("/")||(r=r+"/"),e.dirSlugs.set(o,r),g=r}return e.dirSlugs.get(i)}function T(i,e){if(!i.startsWith(S))return i;const s=i.substring(S.length);return s===e?"":s}export{I as IGNORED_EXTS,A as contentSlugsLoader};
1
+ import f from"path";import{combineUrls as m}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as p}from"../../../constants/common.js";import{removeTrailingSlash as d}from"../../../../utils/url/remove-trailing-slash.js";import{slash as b}from"../../../../utils/path/slash.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{parsePathVersions as D}from"../../../../utils/path/parse-path-versions.js";import{getDefaultVersionByPath as N}from"./versions-config-loader.js";import{GithubSlugger as E,slug as v}from"../../../utils/index.js";import{parseBaseName as I}from"../../utils.js";const V=new Set([".jpg",".jpeg",".png",".gif",".webp",".svg",".ico",".avif",".mp3",".wav",".ogg",".m4a",".mp4",".avi",".mov",".webm",".pdf",".doc",".docx",".zip",".rar",".gz",".ttf",".woff",".woff2"]),M=async(i,{fs:e,cache:o})=>{const l=h.startTiming(),s=(await o.load("versions-config","versions-config")).data,g=new Map,r=new Map,n=new Set,a=new E;r.set(".","/"),r.set("/","/");const t=e.scan().sort((u,S)=>S.relativePath.localeCompare(u.relativePath));for(const{relativePath:u}of t){if(V.has(f.posix.extname(u)))continue;const{data:S}=await o.load(u,"is-ignored");if(S)continue;const w=b(u).replace(new RegExp("^(@i18n|@l10n)\\/"),""),F=N(u,s);z(w,{defaultVersion:F,fileSlugs:g,dirSlugs:r,allFileSlugsList:n,githubSlugger:a})}return h.verboseTime(l,"Calculated slugs. Number of file paths processed: "+t.length),{fileSlugs:g,dirSlugs:r}};function z(i,e){const o=e.fileSlugs.get(i);if(o)return o;const l=D(i);let s=f.posix.dirname(i);const g=c(s,e)||"",{baseName:r,isIndexFile:n}=I(i),a=e.dirSlugs.has(f.posix.join(s,r));let t;if(!n&&a){const u=v(m(g,r,"/"));e.allFileSlugsList.has(u)||(t=u)}t||(t=L({isIndexFile:n,baseName:r,dirPath:s,fileVersionProps:l,ctx:e})),t=d(t),e.fileSlugs.set(i,t),e.allFileSlugsList.add(t)}function L({isIndexFile:i,baseName:e,dirPath:o,fileVersionProps:l,ctx:s}){const g=s.dirSlugs.get(o),r=c(o,s)||"";if(i&&g)return g;const n=d(v(m(r,e)));if(l&&s.defaultVersion&&l.versionName===s.defaultVersion&&s.allFileSlugsList.has(n)){const a=d(l.versionFolderPath)||"/",t=c(a,s)||"/";return s.githubSlugger.slug(m(t,l.versionName,e))}return n}function c(i,e){if(e.dirSlugs.has(i))return e.dirSlugs.get(i);const o=d(f.posix.normalize(i)).split("/");let l="/",s="";for(const g of o){s=f.posix.join(s,g);const r=T(g,e.defaultVersion);let n=e.dirSlugs.get(s)||e.githubSlugger.slug(m("/",l,r));n.endsWith("/")||(n=n+"/"),e.dirSlugs.set(s,n),l=n}return e.dirSlugs.get(i)}function T(i,e){if(!i.startsWith(p))return i;const o=i.substring(p.length);return o===e?"":o}export{V as IGNORED_EXTS,M as contentSlugsLoader};
@@ -1 +1 @@
1
- import w from"path";import{lintConfig as R,loadConfig as C,createConfigTypes as T}from"@redocly/openapi-core";import{deepMerge as U}from"../../../../../utils/object/deep-merge.js";import{readEnvVariable as A}from"../../../../utils/envs/read-env-variable.js";import{logger as l}from"../../../../tools/notifiers/logger.js";import{safeParsePartial as L}from"../../safe-parse.js";import{formatConfigProblem as $}from"../../format-error.js";import{ExternalResolver as q}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as x}from"../../resolve-mutual-exclusion.js";function f(o,e,t,r){e in o&&o[e]&&typeof o[e]=="string"&&(/^https?:\/\/.*/.test(o[e])||r(new Error(`Invalid ${t} URL: "${o[e]}". ${t} must start with "http://" or "https://".`)))}function j(o,e){if("access"in o&&o.access&&typeof o.access=="object"){const t=o.access;f(t,"logoutReturnUrl","access.logoutReturnUrl",e),f(t,"residency","access.residency",e);const r=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const n of r)n in t&&t[n]!==void 0&&n in o&&o[n]!==void 0&&e(new Error(`Property '${n}' is defined both at root level and in 'access' object. Please use 'access.${n}' to define this configuration.`))}}async function z(o,e,t,r){const m=e.getFileInfo(o)?.realRelativePath||o;async function d(){const c=new q(e),u=w.join(e.cwd,m),i=await C({configPath:u,externalRefResolver:c}),y=await r(i.resolvedConfig);if(y===void 0)return i.resolvedConfig;const v=[...i.document?.source?await R({config:i,externalConfigTypes:T(y,i)}):[],...i.document?.source?x(i.resolvedConfig,i.document?.source):[]];if(v.length>0)for(const b of v)t(new Error($(b,e.cwd)));return i.resolvedConfig}const a=await e.exists(o)?await d():{},P=E(a),g=await r(a);f(a,"residency","Residency",t),f(a,"logoutReturnUrl","Logout return URL",t),j(a,t);let p=g?L(g,a):a;const{env:h}=p;if(h){const c=A("REDOCLY_ENV")||"development",u=h[c]||{};p=U(p,u)}const s=M(p,P);if(s.imports&&s.imports.length>0){l.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const c=new Set([...s.plugins||[],...s.imports.map(u=>w.posix.join(u,"plugin.js"))]);s.plugins=Array.from(c),delete s.imports}if(s.catalog&&(l.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),s.catalogClassic={...s.catalog},delete s.catalog),s.scorecard&&(l.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),s.scorecardClassic=s.scorecard,delete s.scorecard),s.search?.ai){l.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const c={...s.search?.ai,...s.aiAssistant,suggestions:s.aiAssistant?.suggestions?.length?s.aiAssistant.suggestions:s.search?.ai.suggestions||[]};s.aiAssistant=c,delete s.search.ai}return k(s)}function k(o){const e="access"in o?o.access:void 0;if(!e||typeof e!="object")return o;const t={...o},r=[{name:"requiresLogin",type:"boolean"},{name:"logoutReturnUrl",type:"string"},{name:"residency",type:"string"},{name:"sso",type:"string | string[]"},{name:"rbac",type:"object"}],n=[];for(const m of r){const d=m.name;d in t&&t[d]!==void 0&&!(d in e)&&n.push(d)}return n.length>0&&l.warn(`The following properties at root level are deprecated: ${n.join(", ")}. Please move them to the 'access' object.`),"requiresLogin"in e&&e.requiresLogin!==void 0&&(t.requiresLogin=e.requiresLogin),"logoutReturnUrl"in e&&e.logoutReturnUrl!==void 0&&(t.logoutReturnUrl=e.logoutReturnUrl),"residency"in e&&e.residency!==void 0&&(t.residency=e.residency),"sso"in e&&e.sso!==void 0&&(t.sso=e.sso),"rbac"in e&&e.rbac!==void 0&&(t.rbac=e.rbac),delete t.access,t}function E(o){if(!o.theme)return[];l.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const e=[];for(const t of Object.keys(o.theme))o[t]==null?e.push(t):l.warn(`Detected both '${t}' and 'theme.${t}' properties in redocly.yaml. The 'theme.${t}' property will be ignored and needs to be removed or merged into the '${t}'.`);return e}function M(o,e){if(!o.theme||e.length===0)return o;const t={...o};for(const r of e)t[r]=o.theme[r];return delete t.theme,t}export{z as readAndValidateConfig};
1
+ import w from"path";import{lintConfig as T,loadConfig as A,createConfigTypes as U}from"@redocly/openapi-core";import{deepMerge as L}from"../../../../../utils/object/deep-merge.js";import{readEnvVariable as R}from"../../../../utils/envs/read-env-variable.js";import{logger as l}from"../../../../tools/notifiers/logger.js";import{BRANCH_ENV_PREFIX as $}from"../../../../../constants/common.js";import{sanitizeBranchName as E}from"../../../../utils/envs/sanitize-branch-name.js";import{safeParsePartial as q}from"../../safe-parse.js";import{formatConfigProblem as x}from"../../format-error.js";import{ExternalResolver as B}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as j}from"../../resolve-mutual-exclusion.js";function m(o,e,t,i){e in o&&o[e]&&typeof o[e]=="string"&&(/^https?:\/\/.*/.test(o[e])||i(new Error(`Invalid ${t} URL: "${o[e]}". ${t} must start with "http://" or "https://".`)))}function N(o,e){if("access"in o&&o.access&&typeof o.access=="object"){const t=o.access;m(t,"logoutReturnUrl","access.logoutReturnUrl",e),m(t,"residency","access.residency",e);const i=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const n of i)n in t&&t[n]!==void 0&&n in o&&o[n]!==void 0&&e(new Error(`Property '${n}' is defined both at root level and in 'access' object. Please use 'access.${n}' to define this configuration.`))}}async function G(o,e,t,i){const g=e.getFileInfo(o)?.realRelativePath||o;async function d(){const c=new B(e),u=w.join(e.cwd,g),r=await A({configPath:u,externalRefResolver:c}),p=await i(r.resolvedConfig);if(p===void 0)return r.resolvedConfig;const P=[...r.document?.source?await T({config:r,externalConfigTypes:U(p,r)}):[],...r.document?.source?j(r.resolvedConfig,r.document?.source):[]];if(P.length>0)for(const C of P)t(new Error(x(C,e.cwd)));return r.resolvedConfig}const a=await e.exists(o)?await d():{},b=I(a),y=await i(a);m(a,"residency","Residency",t),m(a,"logoutReturnUrl","Logout return URL",t),N(a,t);let f=y?q(y,a):a;const{env:h}=f;if(h){const c=R("REDOCLY_ENV")||"development",u=h[c]||{},r=R("PUBLIC_REDOCLY_BRANCH_NAME")||"",p=r?E(r):"",v=p&&h[`${$}${p}`]||{};f=L(f,v,u)}const s=M(f,b);if(s.imports&&s.imports.length>0){l.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const c=new Set([...s.plugins||[],...s.imports.map(u=>w.posix.join(u,"plugin.js"))]);s.plugins=Array.from(c),delete s.imports}if(s.catalog&&(l.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),s.catalogClassic={...s.catalog},delete s.catalog),s.scorecard&&(l.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),s.scorecardClassic=s.scorecard,delete s.scorecard),s.search?.ai){l.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const c={...s.search?.ai,...s.aiAssistant,suggestions:s.aiAssistant?.suggestions?.length?s.aiAssistant.suggestions:s.search?.ai.suggestions||[]};s.aiAssistant=c,delete s.search.ai}return _(s)}function _(o){const e="access"in o?o.access:void 0;if(!e||typeof e!="object")return o;const t={...o},i=[{name:"requiresLogin",type:"boolean"},{name:"logoutReturnUrl",type:"string"},{name:"residency",type:"string"},{name:"sso",type:"string | string[]"},{name:"rbac",type:"object"}],n=[];for(const g of i){const d=g.name;d in t&&t[d]!==void 0&&!(d in e)&&n.push(d)}return n.length>0&&l.warn(`The following properties at root level are deprecated: ${n.join(", ")}. Please move them to the 'access' object.`),"requiresLogin"in e&&e.requiresLogin!==void 0&&(t.requiresLogin=e.requiresLogin),"logoutReturnUrl"in e&&e.logoutReturnUrl!==void 0&&(t.logoutReturnUrl=e.logoutReturnUrl),"residency"in e&&e.residency!==void 0&&(t.residency=e.residency),"sso"in e&&e.sso!==void 0&&(t.sso=e.sso),"rbac"in e&&e.rbac!==void 0&&(t.rbac=e.rbac),delete t.access,t}function I(o){if(!o.theme)return[];l.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const e=[];for(const t of Object.keys(o.theme))o[t]==null?e.push(t):l.warn(`Detected both '${t}' and 'theme.${t}' properties in redocly.yaml. The 'theme.${t}' property will be ignored and needs to be removed or merged into the '${t}'.`);return e}function M(o,e){if(!o.theme||e.length===0)return o;const t={...o};for(const i of e)t[i]=o.theme[i];return delete t.theme,t}export{G as readAndValidateConfig};
@@ -1 +1 @@
1
- import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEFAULT_SSO_IDP_TITLE as b,DEV_LOGIN_SLUG as g,INVITE_SLUG as T,PUBLIC_RBAC_SCOPE_ITEM as f,UI_ACCESSIBLE_CONFIG_PROPS as D,CONFIG_FILE_NAME as l}from"../../../constants/common.js";import{isDevelopMode as P}from"../../utils/envs/is-develop-mode.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as n}from"../nav-utils.js";import{resolveLogoConfig as F}from"./resolve-logo.js";import{extractTeamNames as _}from"./extract-team-names.js";import{resolveProductsConfig as E}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as O}from"./resolve-catalog-entities.js";import{telemetryTraceStep as A}from"../../../cli/telemetry/helpers/trace-step.js";async function q(i){return{id:"Default Theme",async processContent(e){await A("build.plugin.default_theme",async()=>{const t=v(e),a=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,o=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:T,[c]:f,fsPath:T,templateId:o}),i.devLogin&&a){let r={frontmatter:{},seo:{title:"Login page"},authIdps:t.filter(u=>u.title!=b),rbac:{teams:_(e.getConfig().rbac)}};const p=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:g,[c]:f,fsPath:g,templateId:p,getStaticData:async()=>({props:r})})}else if(t.length>1){let r={frontmatter:{},seo:{title:"Login page"},authIdps:t};const p=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:g,[c]:f,fsPath:g,templateId:p,getStaticData:async()=>({props:r})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),P()&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:a,outdir:o}=e,r=e.getConfig(),{navbar:p,footer:u,userMenu:m,search:I,breadcrumbs:C,products:S}=r,L=Object.keys(r?.ssoDirect||{}).length>0,d=y(r),h={navFile:l,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...j(r),navbar:await n(p,a,e,t,h),footer:await n(u,a,e,t,h),breadcrumbs:{...C,prefixItems:await n(C?.prefixItems||[],a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},userMenu:{...m,hide:m?.hide??!L,menu:await n(m?.items,a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},logo:await F(r.logo,l,o,t.fs),auth:{idpsInfo:v(e),devLogin:i.devLogin&&L},products:await E(S,e,t),search:{...I,suggestedPages:await n(I?.suggestedPages,a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await O(r.entitiesCatalog,l,o,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(i){const e=i.getConfig().ssoDirect;return Object.entries(e||{}).map(([a,o])=>({idpId:a,type:o.type,title:o.title}))}function j(i){const e={};for(const t of D)i[t]&&(e[t]=i[t]);return e}export{q as defaultThemePlugin,j as pickUiAccessibleConfig};
1
+ import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as u,INVITE_SLUG as T,PUBLIC_RBAC_SCOPE_ITEM as m,UI_ACCESSIBLE_CONFIG_PROPS as b,CONFIG_FILE_NAME as n,DEFAULT_SSO_IDP_TITLE as P}from"../../../constants/common.js";import{isDevelopMode as _}from"../../utils/envs/is-develop-mode.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as p}from"../nav-utils.js";import{resolveLogoConfig as F}from"./resolve-logo.js";import{extractTeamNames as E}from"./extract-team-names.js";import{resolveProductsConfig as O}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as A}from"./resolve-catalog-entities.js";import{telemetryTraceStep as j}from"../../../cli/telemetry/helpers/trace-step.js";async function q(r){return{id:"Default Theme",async processContent(e){await j("build.plugin.default_theme",async()=>{const t=v(e),a=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,i=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:T,[c]:m,fsPath:T,templateId:i}),r.devLogin&&a){const o={frontmatter:{},seo:{title:"Login page"},authIdps:f(t),rbac:{teams:E(e.getConfig().rbac)}},l=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:o})})}else if(t.length>1){const o={frontmatter:{},seo:{title:"Login page"},authIdps:f(t)},l=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:o})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),_()&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:a,outdir:i}=e,o=e.getConfig(),{navbar:l,footer:S,userMenu:g,search:I,breadcrumbs:L,products:D}=o,C=Object.keys(o?.ssoDirect||{}).length>0,d=y(o),h={navFile:n,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...k(o),navbar:await p(l,a,e,t,h),footer:await p(S,a,e,t,h),breadcrumbs:{...L,prefixItems:await p(L?.prefixItems||[],a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},userMenu:{...g,hide:g?.hide??!C,menu:await p(g?.items,a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},logo:await F(o.logo,n,i,t.fs),auth:{idpsInfo:f(v(e)),devLogin:r.devLogin&&C},products:await O(D,e,t),search:{...I,suggestedPages:await p(I?.suggestedPages,a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await A(o.entitiesCatalog,n,i,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(r){const e=r.getConfig().ssoDirect;return Object.entries(e||{}).map(([a,i])=>({idpId:a,type:i.type,title:i.title}))}function f(r){return process.env.LOCALHOST_LOGIN==="true"?r:r.filter(t=>t.title!==P)}function k(r){const e={};for(const t of b)r[t]&&(e[t]=r[t]);return e}export{q as defaultThemePlugin,k as pickUiAccessibleConfig};
@@ -0,0 +1,54 @@
1
+ import type { JSONSchemaType } from '@redocly/ajv';
2
+ import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
3
+ import type { OpenAPIDefinition } from '@redocly/openapi-docs';
4
+ import type { AccessInfo, ApiDescriptionInfo, McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
5
+ export type DocsMcpToolRegistrationOptions = {
6
+ server: McpServer;
7
+ baseUrl: string;
8
+ outdir: string;
9
+ apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
10
+ headers?: Record<string, string | string[] | undefined>;
11
+ accessInfo: AccessInfo;
12
+ };
13
+ /** Keys that can be passed to the tool context (excludes 'server' which is not serializable) */
14
+ export type ContextKey = Exclude<keyof DocsMcpToolRegistrationOptions, 'server'>;
15
+ export type ApiDefinitionResult = {
16
+ success: true;
17
+ definition: OpenAPIDefinition;
18
+ } | {
19
+ success: false;
20
+ response: McpToolWorkerResponse;
21
+ };
22
+ export declare abstract class DocsMcpTool<TName extends keyof ToolArgsMap> {
23
+ abstract readonly name: TName;
24
+ abstract readonly description: string;
25
+ readonly schema: JSONSchemaType<ToolArgsMap[TName]>;
26
+ /**
27
+ * Array of context keys that this tool requires.
28
+ * The base class will extract these from DocsMcpToolRegistrationOptions
29
+ * and pass them to executeAction.
30
+ */
31
+ abstract readonly requiredContext: readonly ContextKey[];
32
+ constructor(schema: JSONSchemaType<ToolArgsMap[TName]>);
33
+ /**
34
+ * Builds the context object by picking only the required keys from options.
35
+ */
36
+ protected getContext(options: DocsMcpToolRegistrationOptions): McpToolWorkerParams['context'];
37
+ register(options: DocsMcpToolRegistrationOptions): void;
38
+ /**
39
+ * Wraps the tool execution with telemetry and error handling.
40
+ * Subclasses should call this method and implement executeAction for the actual logic.
41
+ */
42
+ execute(args: ToolArgsMap[TName], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
43
+ /**
44
+ * Implement the actual tool logic here. Called by execute() which handles telemetry.
45
+ */
46
+ protected abstract executeAction(args: ToolArgsMap[TName], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
47
+ /**
48
+ * Helper method for tools that need to load an API definition.
49
+ * Handles finding the API by name and loading the definition from the file system.
50
+ * Requires 'outdir' and 'accessInfo' in requiredContext.
51
+ */
52
+ protected getApiDefinition(name: string, context: McpToolWorkerParams['context']): Promise<ApiDefinitionResult>;
53
+ }
54
+ //# sourceMappingURL=docs-mcp-tool.d.ts.map
@@ -0,0 +1 @@
1
+ import{telemetry as i}from"../../../../telemetry/index.js";import{mcpToolWorkers as n,MCP_TOOL_WORKER_KEY as a}from"../../../../workers/mcp-tool-worker-pool.js";import{findApiDescriptionByName as p}from"../utils.js";import{getApiDescriptionFromFs as u}from"./utils.js";function f(o,t,s){return{toolName:o,args:t,context:s}}class g{schema;constructor(t){this.schema=t}getContext(t){const s={};for(const e of this.requiredContext)s[e]=t[e];return{...s,apiDescriptionsMap:t.apiDescriptionsMap}}register(t){const s=async(e,r)=>{const c=f(this.name,e,this.getContext(t));return await n.exec(a,[c],{timeout:6e4})};t.server.tool(this.name,this.description,this.schema,s)}async execute(t,s){try{const e=await this.executeAction(t,s);return i.sendMcpToolCalledMessage([{object:"mcp_server",server_type:"docs",tool:this.name}]),e}catch(e){throw i.sendMcpErrorMessage([{object:"mcp_server",server_type:"docs",tool:this.name,message:e instanceof Error?e.message:String(e),stack:e instanceof Error&&e.stack||""}]),e}}async getApiDefinition(t,s){if(!s.outdir||!s.accessInfo)throw new Error("Missing required context: outdir and accessInfo");const e=p(s.apiDescriptionsMap,t);if(!e)return{success:!1,response:{content:[{type:"text",text:`No API found matching "${t}".`}]}};const r=await u({relativePath:e.relativePath||"",outdir:s.outdir,accessInfo:s.accessInfo});return r?{success:!0,definition:r}:{success:!1,response:{content:[{type:"text",text:`Spec not found from the file system with "${t}".`}]}}}}export{g as DocsMcpTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetEndpointTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetEndpointInfoTool extends DocsMcpTool<'get-endpoint-info'> {
4
+ readonly name = "get-endpoint-info";
5
+ readonly description = "Get comprehensive information about specific endpoint including parameters, security, and examples";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-endpoint-info'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-endpoint-info.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as P,resolveParameters as v,resolveRequestBody as x,resolveResponses as O}from"../utils.js";import{checkEndpointAndDeleteXMcp as S}from"../../utils/xmcp-utils.js";import{telemetry as c}from"../../../../telemetry/index.js";import{getApiDescriptionFromFs as A}from"./utils.js";const p="get-endpoint-info",d=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],L={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...d,...d.map(n=>n.toLowerCase())],minLength:1}}};function N({server:n,apiDescriptionsMap:m,outdir:l,accessInfo:u}){n.tool(p,"Get comprehensive information about specific endpoint including parameters, security, and examples",L,async({name:s,path:r,method:a})=>{try{const t=P(m,s);if(!t)return{content:[{type:"text",text:`No API found matching "${s}".`}]};const e=await A({relativePath:t?.relativePath||"",outdir:l,accessInfo:u});if(!e)return{content:[{type:"text",text:`Spec not found from the file system with "${s}".`}]};const f=r.startsWith("/")?r:`/${r}`,{title:y=""}=e.info||{},i=e.paths?.[f],h=a.toLowerCase();if(!i)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const o=i[h];if(!o||!S(o,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const E=i?.parameters||[],T=o.parameters||[],g={...o,parameters:v({pathParams:E,opParams:T,definition:e}),requestBody:x(o.requestBody,e),responses:O(o.responses,e)};return c.sendMcpToolCalledMessage({server_type:"docs",tool:p}),{content:[{type:"text",text:JSON.stringify({api:y,version:e.info?.version||"",servers:e.servers||[],endpoint:{path:r,method:a.toUpperCase(),...g},globalSecurity:e.security||[],securitySchemes:e.components?.securitySchemes||[]},null,2)}]}}catch(t){throw c.sendMcpErrorMessage({server_type:"docs",tool:p,message:t?.message||"",stack:t?.stack||""}),t}})}export{N as registerGetEndpointTools};
1
+ import{resolveParameters as T,resolveRequestBody as y,resolveResponses as P}from"../utils.js";import{isMcpEndpoint as g}from"./utils.js";import{DocsMcpTool as x}from"./docs-mcp-tool.js";import{checkEndpointAndDeleteXMcp as v}from"../../utils/xmcp-utils.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],S={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p,...p.map(r=>r.toLowerCase())],minLength:1}}};class D extends x{name="get-endpoint-info";description="Get comprehensive information about specific endpoint including parameters, security, and examples";requiredContext=["outdir","accessInfo"];constructor(){super(S)}async executeAction(a,c){const{name:d,path:o,method:i}=a,n=await this.getApiDefinition(d,c);if(!n.success)return n.response;const{definition:e}=n,m=o.startsWith("/")?o:`/${o}`,{title:u=""}=e.info||{},s=e.paths?.[m],h=i.toLowerCase();if(!s)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const t=s[h];if(!g(t)||!v(t,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const f=s?.parameters||[],l=t.parameters||[],E={...t,parameters:T({pathParams:f,opParams:l,definition:e}),requestBody:y(t.requestBody,e),responses:P(t.responses,e)};return{content:[{type:"text",text:JSON.stringify({api:u,version:e.info?.version||"",servers:e.servers||[],endpoint:{path:o,method:i.toUpperCase(),...E},globalSecurity:e.security||[],securitySchemes:e.components?.securitySchemes||[]},null,2)}]}}}export{D as GetEndpointInfoTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetEndpointsTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetEndpointsTool extends DocsMcpTool<'get-endpoints'> {
4
+ readonly name = "get-endpoints";
5
+ readonly description = "Get all endpoints for a specific API";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-endpoints'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-endpoints.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as f}from"../utils.js";import{getApiDescriptionFromFs as d,getEndpointsFromPaths as l}from"./utils.js";import{telemetry as i}from"../../../../telemetry/index.js";const n="get-endpoints",m={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function u({server:s,apiDescriptionsMap:p,outdir:c,accessInfo:a}){s.tool(n,"Get all endpoints for a specific API",m,async({name:o})=>{try{const t=f(p,o);if(!t)return{content:[{type:"text",text:`No API found matching "${o}".`}]};const e=await d({relativePath:t?.relativePath||"",outdir:c,accessInfo:a});if(!e)return{content:[{type:"text",text:`Spec not found from the file system with "${o}".`}]};const r=l(e);return r.length===0?{content:[{type:"text",text:"No endpoints found"}]}:(i.sendMcpToolCalledMessage({server_type:"docs",tool:n}),{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",servers:e.servers||[],endpoints:r},null,2)}]})}catch(t){throw i.sendMcpErrorMessage({server_type:"docs",tool:n,message:t?.message||"",stack:t?.stack||""}),t}})}export{u as registerGetEndpointsTools};
1
+ import{DocsMcpTool as r}from"./docs-mcp-tool.js";import{getEndpointsFromPaths as p}from"./utils.js";const c={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class u extends r{name="get-endpoints";description="Get all endpoints for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(c)}async executeAction(o,i){const{name:s}=o,e=await this.getApiDefinition(s,i);if(!e.success)return e.response;const{definition:t}=e,n=p(t);return n.length===0?{content:[{type:"text",text:"No endpoints found"}]}:{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",servers:t.servers||[],endpoints:n},null,2)}]}}}export{u as GetEndpointsTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetFullApiDescriptionTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetFullApiDescriptionTool extends DocsMcpTool<'get-full-api-description'> {
4
+ readonly name = "get-full-api-description";
5
+ readonly description = "Get the complete OpenAPI description";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-full-api-description'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-full-api-description.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as a}from"../utils.js";import{telemetry as r}from"../../../../telemetry/index.js";import{getApiDescriptionFromFs as l}from"./utils.js";const i="get-full-api-description",f={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function g({server:n,apiDescriptionsMap:s,outdir:p,accessInfo:c}){n.tool(i,"Get the complete OpenAPI description",f,async({name:o})=>{try{const t=a(s,o);if(!t)return{content:[{type:"text",text:`No API found matching "${o}".`}]};const e=await l({relativePath:t?.relativePath||"",outdir:p,accessInfo:c});return e?(r.sendMcpToolCalledMessage({server_type:"docs",tool:i}),{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",definition:e},null,2)}]}):{content:[{type:"text",text:`Spec not found from the file system with "${o}".`}]}}catch(t){throw r.sendMcpErrorMessage({server_type:"docs",tool:i,message:t?.message||"",stack:t?.stack||""}),t}})}export{g as registerGetFullApiDescriptionTools};
1
+ import{DocsMcpTool as r}from"./docs-mcp-tool.js";const s={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class a extends r{name="get-full-api-description";description="Get the complete OpenAPI description";requiredContext=["outdir","accessInfo"];constructor(){super(s)}async executeAction(i,n){const{name:o}=i,e=await this.getApiDefinition(o,n);if(!e.success)return e.response;const{definition:t}=e;return{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",definition:t},null,2)}]}}}export{a as GetFullApiDescriptionTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetSecuritySchemesTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetSecuritySchemesTool extends DocsMcpTool<'get-security-schemes'> {
4
+ readonly name = "get-security-schemes";
5
+ readonly description = "Get the security schemes for a specific API";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-security-schemes'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-security-schemes.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as a}from"../utils";import{telemetry as i}from"../../../../telemetry/index.js";import{getApiDescriptionFromFs as m}from"./utils.js";const o="get-security-schemes",y={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function h({server:s,apiDescriptionsMap:n,outdir:c,accessInfo:p}){s.tool(o,"Get the security schemes for a specific API",y,async({name:r})=>{try{const e=a(n,r);if(!e)return{content:[{type:"text",text:`No API found matching "${r}".`}]};const t=await m({relativePath:e?.relativePath||"",outdir:c,accessInfo:p});return t?(i.sendMcpToolCalledMessage({server_type:"docs",tool:o}),{content:[{type:"text",text:JSON.stringify({name:t.info?.title,version:t.info?.version,securitySchemes:t.components?.securitySchemes||[],security:t.security||[]},null,2)}]}):{content:[{type:"text",text:`Spec not found from the file system with "${r}".`}]}}catch(e){throw i.sendMcpErrorMessage({server_type:"docs",tool:o,message:e?.message||"",stack:e?.stack||""}),e}})}export{h as registerGetSecuritySchemesTools};
1
+ import{DocsMcpTool as o}from"./docs-mcp-tool.js";const r={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class p extends o{name="get-security-schemes";description="Get the security schemes for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(r)}async executeAction(s,i){const{name:n}=s,t=await this.getApiDefinition(n,i);if(!t.success)return t.response;const{definition:e}=t;return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||[],security:e.security||[]},null,2)}]}}}export{p as GetSecuritySchemesTool};
@@ -1,14 +1,8 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- /**
4
- * Registers all tools with the MCP server
5
- */
6
- export declare function registerDocsTools({ server, baseUrl, outdir, apiDescriptionsMap, headers, accessInfo, }: {
7
- server: McpServer;
8
- baseUrl: string;
9
- outdir: string;
10
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
11
- accessInfo: AccessInfo;
12
- headers?: Record<string, string | string[] | undefined>;
13
- }): void;
1
+ import type { ToolArgsMap } from '../../types.js';
2
+ import type { DocsMcpTool, DocsMcpToolRegistrationOptions } from './docs-mcp-tool.js';
3
+ export declare const docsTools: DocsMcpTool<keyof ToolArgsMap>[];
4
+ export declare function registerDocsTools(options: DocsMcpToolRegistrationOptions): void;
5
+ export declare function getDocsTool<T extends keyof ToolArgsMap>(name: T): DocsMcpTool<T> | undefined;
6
+ export { DocsMcpTool } from './docs-mcp-tool.js';
7
+ export type { DocsMcpToolRegistrationOptions } from './docs-mcp-tool.js';
14
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- import{registerListApisTools as g}from"./list-apis.js";import{registerGetEndpointsTools as T}from"./get-endpoints.js";import{registerGetEndpointTools as e}from"./get-endpoint-info.js";import{registerGetSecuritySchemesTools as f}from"./get-security-schemes.js";import{registerGetFullApiDescriptionTools as h}from"./get-full-api-description.js";import{registerSearchTool as A}from"./search.js";import{registerWhoAmITool as G}from"./whoami.js";import{shouldHandleMcpAuth as p}from"../../auth/auth-handlers.js";function F({server:o,baseUrl:l,outdir:m,apiDescriptionsMap:r,headers:i,accessInfo:t}){p(t.requiresLogin,t.rbac)&&G(o,i),g({server:o,apiDescriptionsMap:r}),T({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),e({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),f({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),h({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),A(o,l,m,i)}export{F as registerDocsTools};
1
+ import{GetEndpointInfoTool as t}from"./get-endpoint-info.js";import{GetEndpointsTool as n}from"./get-endpoints.js";import{GetFullApiDescriptionTool as i}from"./get-full-api-description.js";import{GetSecuritySchemesTool as m}from"./get-security-schemes.js";import{ListApisTool as s}from"./list-apis.js";import{SearchTool as c}from"./search.js";import{WhoAmITool as p}from"./whoami.js";import{shouldHandleMcpAuth as f}from"../../auth/auth-handlers.js";const e=[new s,new n,new t,new m,new i,new c,new p],l=e.reduce((o,r)=>(o[r.name]=r,o),{});function A(o){e.forEach(r=>{r.name==="whoami"&&!f(o.accessInfo.requiresLogin,o.accessInfo.rbac)||r.register(o)})}function D(o){return l[o]}import{DocsMcpTool as E}from"./docs-mcp-tool.js";export{E as DocsMcpTool,e as docsTools,D as getDocsTool,A as registerDocsTools};
@@ -1,7 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerListApisTools({ server, apiDescriptionsMap, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class ListApisTool extends DocsMcpTool<'list-apis'> {
4
+ readonly name = "list-apis";
5
+ readonly description = "Lists available APIs with their context and purpose";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['list-apis'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
7
10
  //# sourceMappingURL=list-apis.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as a}from"../../../../telemetry/index.js";import{filterApiDescriptionsByName as g}from"../utils.js";const r="list-apis",f={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API name (or part of it)",minLength:1},page:{type:"number",description:"Page number",minimum:1,default:1},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300}}};function b({server:p,apiDescriptionsMap:c}){p.tool(r,"Lists available APIs with their context and purpose",f,async({filter:o,page:i=1,limit:t=300})=>{let e=Object.values(c);o&&(e=g(e,o));const n=(i-1)*t,l=n+t,m=Math.ceil(e.length/t),d=e.length;e=e.slice(n,l);try{return e.length===0?{content:[{type:"text",text:"No APIs available"}]}:(a.sendMcpToolCalledMessage({server_type:"docs",tool:r}),{content:[{type:"text",text:JSON.stringify({items:e.map(({relativePath:s,...u})=>u),limit:t,total:d,page:i,totalPages:m})}]})}catch(s){throw a.sendMcpErrorMessage({server_type:"docs",tool:r,message:s?.message||"",stack:s?.stack||""}),s}})}export{b as registerListApisTools};
1
+ import{filterApiDescriptionsByName as u}from"../utils.js";import{DocsMcpTool as m}from"./docs-mcp-tool.js";const 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}}};class y extends m{name="list-apis";description="Lists available APIs with their context and purpose";requiredContext=[];constructor(){super(d)}async executeAction(s,o){const{filter:i,page:n=1,limit:e=300}=s;let t=Object.values(o.apiDescriptionsMap);i&&(t=u(t,i));const r=(n-1)*e,a=r+e,l=Math.ceil(t.length/e),p=t.length;return t=t.slice(r,a),t.length===0?{content:[{type:"text",text:"No APIs available"}]}:{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:b,...c})=>c),limit:e,total:p,page:n,totalPages:l})}]}}}export{y as ListApisTool};
@@ -1,3 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- export declare function registerSearchTool(server: McpServer, baseUrl: string, outdir: string, headers?: Record<string, string | string[] | undefined>): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class SearchTool extends DocsMcpTool<'search'> {
4
+ readonly name = "search";
5
+ readonly description = "Search across the documentation to fetch relevant content for a given query";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['search'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
3
10
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- import{withPathPrefix as u}from"@redocly/theme/core/utils";import{ServerRoutes as m}from"../../../../../constants/common.js";import{telemetry as s}from"../../../../telemetry/index.js";import{processDocuments as y}from"./utils.js";const o="search",f={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}}};function k(n,a,c,i){n.tool(o,"Search across the documentation to fetch relevant content for a given query",f,async({query:p})=>{try{const e=JSON.stringify({query:p}),h=`${a}${u(m.SEARCH)}`.replace("http","https"),d=`authorization=${String(i?.authorization).replace(/^Bearer /,"")}`,t=await fetch(h,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Cookie:d},body:e});if(!t.ok)throw new Error(`Search request failed with status ${t.status}`);const l=await t.json(),r=y(l.documents||{},c);return s.sendMcpToolCalledMessage({server_type:"docs",tool:o}),{content:[{type:"text",text:r.trim().length?r:"No results found."}]}}catch(e){throw s.sendMcpErrorMessage({server_type:"docs",tool:o,message:e?.message||"",stack:e?.stack||""}),e}})}export{k as registerSearchTool};
1
+ import{withPathPrefix as d}from"@redocly/theme/core/utils";import{ServerRoutes as p}from"../../../../../constants/common.js";import{DocsMcpTool as l}from"./docs-mcp-tool.js";import{processDocuments as m}from"./utils.js";const f={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}}};class g extends l{name="search";description="Search across the documentation to fetch relevant content for a given query";requiredContext=["baseUrl","outdir","headers"];constructor(){super(f)}async executeAction(a,e){const{query:i}=a;if(!e.baseUrl||!e.outdir)throw new Error("Missing required context: baseUrl and outdir");const c=JSON.stringify({query:i});let t=`${e.baseUrl}${d(p.SEARCH)}`;t.startsWith("http://")&&(t=t.replace(/^http:\/\//,"https://"));const o=e.headers?.authorization,s=o?`authorization=${String(o).replace(/^Bearer /,"")}`:"",r=await fetch(t,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...s?{Cookie:s}:{}},body:c});if(!r.ok){const u=await r.text().catch(()=>"Unable to read error response");throw new Error(`Search request failed with status ${r.status}: ${u}`)}const h=await r.json(),n=m(h.documents||{},e.outdir);return{content:[{type:"text",text:n.trim().length?n:"No results found."}]}}}export{g as SearchTool};
@@ -1,6 +1,7 @@
1
1
  import type { OpenAPIDefinition, OpenAPIOperation } from '@redocly/openapi-docs';
2
2
  import type { SearchItemData } from '@redocly/theme/core/types';
3
- import type { AccessInfo } from '../../types';
3
+ import type { AccessInfo, McpEndpoint } from '../../types';
4
+ export declare function isMcpEndpoint(value: unknown): value is McpEndpoint;
4
5
  type EndpointInfo = Pick<OpenAPIOperation, 'summary' | 'description' | 'security'> & {
5
6
  method: string;
6
7
  path: string;
@@ -1,11 +1,11 @@
1
- import y from"node:fs";import u from"node:path";import{existsSync as A}from"node:fs";import{readFile as O}from"node:fs/promises";import{replaceFileExtension as g}from"../../../../plugins/openapi-docs/store-definition-bundles";import{PUBLIC_API_DEFINITIONS_FOLDER as j}from"../../../../constants/common";import{filterDataByAccessDeep as F}from"../../../../utils/rbac";import{checkEndpointAndDeleteXMcp as D}from"../../utils/xmcp-utils.js";import{MAX_DOCUMENTS_PER_CATEGORY as C}from"../../constants.js";function T(i){const{paths:o={}}=i,s=[];for(const[c,n]of Object.entries(o)){const a=!D(n,"docs");for(const[f,t]of Object.entries(n))a||!D(t,"docs")||s.push({path:c,method:f.toUpperCase(),summary:t.summary,description:t.description,security:t.security})}return s}function M(i,o){return Object.entries(i).map(([c,n])=>{if(!n||n.length===0)return"";const a=n.slice(0,C).map(f=>{const{document:t,highlight:m}=f,d=m?.title||(Array.isArray(t.title)?t.title[0]:t.title);let r=`Document: ${t.title}`;r+=`### [${d}](${t.url})
1
+ import y from"node:fs";import u from"node:path";import{existsSync as j}from"node:fs";import{readFile as A}from"node:fs/promises";import{replaceFileExtension as O}from"../../../../plugins/openapi-docs/store-definition-bundles";import{PUBLIC_API_DEFINITIONS_FOLDER as b}from"../../../../constants/common";import{filterDataByAccessDeep as g}from"../../../../utils/rbac";import{checkEndpointAndDeleteXMcp as E}from"../../utils/xmcp-utils.js";import{MAX_DOCUMENTS_PER_CATEGORY as F}from"../../constants.js";function N(e){return typeof e=="object"&&e!==null&&"responses"in e&&typeof e.responses=="object"}function T(e){const{paths:i={}}=e,s=[];for(const[c,r]of Object.entries(i)){const p=!E(r,"docs");for(const[a,t]of Object.entries(r))p||!E(t,"docs")||s.push({path:c,method:a.toUpperCase(),summary:t.summary,description:t.description,security:t.security})}return s}function R(e,i){return Object.entries(e).map(([c,r])=>{if(!r||r.length===0)return"";const p=r.slice(0,F).map(a=>{const{document:t,highlight:m}=a,d=m?.title||(Array.isArray(t.title)?t.title[0]:t.title);let o=`Document: ${t.title}`;o+=`### [${d}](${t.url})
2
2
 
3
- `;let p;if(t.url)try{let e=t.url.startsWith("/")?t.url.slice(1):t.url;const l=e.indexOf("#");l!==-1&&(e=e.substring(0,l));const h=u.extname(e);h&&(e=e.slice(0,-h.length));let E=e+".md";const x=u.join(o,E);y.existsSync(x)&&(p=y.readFileSync(x,"utf8"))}catch{}return p||(p=m?.text||(Array.isArray(t.text)?t.text[0]:t.text)),r+=p,t.facets&&(r+=`
3
+ `;let f;if(t.url)try{let n=t.url.startsWith("/")?t.url.slice(1):t.url;const l=n.indexOf("#");l!==-1&&(n=n.substring(0,l));const h=u.extname(n);h&&(n=n.slice(0,-h.length));let D=n+".md";const x=u.join(i,D);y.existsSync(x)&&(f=y.readFileSync(x,"utf8"))}catch{}return f||(f=m?.text||(Array.isArray(t.text)?t.text[0]:t.text)),o+=f,t.facets&&(o+=`
4
4
 
5
5
  **Categories:**
6
- `,Object.entries(t.facets).forEach(([e,l])=>{r+=`- ${e}: ${l}
7
- `})),r});return`## ${c}
6
+ `,Object.entries(t.facets).forEach(([n,l])=>{o+=`- ${n}: ${l}
7
+ `})),o});return`## ${c}
8
8
 
9
- ${a}`}).join(`
9
+ ${p}`}).join(`
10
10
 
11
- `).trim()}async function R({relativePath:i,outdir:o,accessInfo:{isAuthenticated:s,email:c,teams:n,rbac:a={},requiresLogin:f=!1}}){const t=u.join(o||"",j,g(i,".json"));if(!A(t))return;const d=await O(t,"utf-8"),r=JSON.parse(d);return F(r,{isAuthenticated:s,email:c,teams:n},a,f)}export{R as getApiDescriptionFromFs,T as getEndpointsFromPaths,M as processDocuments};
11
+ `).trim()}async function U({relativePath:e,outdir:i,accessInfo:{isAuthenticated:s,email:c,teams:r,rbac:p={},requiresLogin:a=!1}}){const t=u.join(i||"",b,O(e,".json"));if(!j(t))return;const d=await A(t,"utf-8"),o=JSON.parse(d);return g(o,{isAuthenticated:s,email:c,teams:r},p,a)}export{U as getApiDescriptionFromFs,T as getEndpointsFromPaths,N as isMcpEndpoint,R as processDocuments};
@@ -1,3 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- export declare function registerWhoAmITool(server: McpServer, headers?: Record<string, string | string[] | undefined>): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class WhoAmITool extends DocsMcpTool<'whoami'> {
4
+ readonly name = "whoami";
5
+ readonly description = "Get information about the currently authenticated user";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(_args: ToolArgsMap['whoami'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
3
10
  //# sourceMappingURL=whoami.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as r}from"../../../../telemetry/index";import{getUserInfoFromHeaders as s}from"../../utils/jwt";const t="whoami";function c(o,n){o.tool(t,"Get information about the currently authenticated user",()=>{try{const e=s(n||{});return r.sendMcpToolCalledMessage({server_type:"docs",tool:t}),e?{content:[{type:"text",text:JSON.stringify({email:e.email,name:e.name,subject:e.sub,clientId:e.client_id,scope:e.scope,issuedAt:e.iat?new Date(e.iat*1e3).toISOString():void 0,expiresAt:e.exp?new Date(e.exp*1e3).toISOString():void 0})}],isError:!1}:{content:[{type:"text",text:JSON.stringify({error:"Not authenticated",message:"No valid authentication token found. Please authenticate first."})}],isError:!0}}catch(e){return r.sendMcpErrorMessage({server_type:"docs",tool:t,message:e?.message||"Failed to get user info",stack:e?.stack||""}),{content:[{type:"text",text:JSON.stringify({error:"Failed to get user info",details:e instanceof Error?e.message:String(e)})}],isError:!0}}})}export{c as registerWhoAmITool};
1
+ import{getUserInfoFromHeaders as r}from"../../utils/jwt.js";import{DocsMcpTool as o}from"./docs-mcp-tool.js";const n={type:"object",required:[],additionalProperties:!1,properties:{}};class u extends o{name="whoami";description="Get information about the currently authenticated user";requiredContext=["headers"];constructor(){super(n)}async executeAction(s,t){const e=r(t.headers||{});return e?{content:[{type:"text",text:JSON.stringify({email:e.email,name:e.name,subject:e.sub,clientId:e.client_id,scope:e.scope,issuedAt:e.iat?new Date(e.iat*1e3).toISOString():void 0,expiresAt:e.exp?new Date(e.exp*1e3).toISOString():void 0})}],isError:!1}:{content:[{type:"text",text:JSON.stringify({error:"Not authenticated",message:"No valid authentication token found. Please authenticate first."})}],isError:!0}}}export{u as WhoAmITool};
@@ -1 +1 @@
1
- import{createMcpRequestHandler as D}from"./mcp-request-handler.js";import{createDocsMcpServer as v}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as h}from"../utils.js";import{createInternalServerError as y}from"./errors.js";import{McpServerType as m}from"../constants.js";import{telemetry as f}from"../../../telemetry/index.js";import{constructInvalidTokenResponse as A,constructUnauthorizedResponse as L,handleMcpAuth as S,shouldHandleMcpAuth as b}from"../auth/auth-handlers.js";async function I(r,s,i,n){try{f.initialize();const e=s,t=e?.props?.config?.apiDescriptionsMap||{},a=e?.props?.outdir||"",o=e?.props?.config?.mcpDocsServerName||"Docs MCP server",u=new URL(n.url).origin,{user:c,config:{rbac:p={},mcp:l={}}}=r,d=h(t,c,p,r.config.requiresLogin||!1),g=l.docs?.name||o,M={rbac:p,email:c?.email,teams:c?.teams,isAuthenticated:!!c?.isAuthenticated,requiresLogin:r.config.requiresLogin||!1};return await v({name:g,baseUrl:u,headers:i,apiDescriptionsMap:d,outdir:a,accessInfo:M})}catch(e){throw f.sendMcpErrorMessage({server_type:m.Docs,message:e?.message||"",stack:e?.stack||""}),y(e?.message||"Internal server error mcp docs")}}const R=D({createServerInstance:I,serverType:m.Docs}),w=async(r,s,i)=>{const n=!!s?.config?.requiresLogin,e=s?.config?.rbac;if(b(n,e)){const{isAuthenticated:t,isTokenValid:a,currentUser:o}=await S(r,s);if(!t)return L(new URL(r.url).origin);if(!a)return A();o&&(s.user=o)}return R(r,s,i)};var E=w;export{E as default};
1
+ import{createMcpRequestHandler as v}from"./mcp-request-handler.js";import{createDocsMcpServer as D}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as h}from"../utils.js";import{createInternalServerError as y}from"./errors.js";import{McpServerType as m}from"../constants.js";import{telemetry as f}from"../../../telemetry/index.js";import{constructInvalidTokenResponse as b,constructUnauthorizedResponse as A,handleMcpAuth as L,shouldHandleMcpAuth as S}from"../auth/auth-handlers.js";async function I(r,s,i,n){try{f.initialize();const e=s,t=e?.props?.config?.apiDescriptionsMap||{},a=e?.props?.outdir||"",o=e?.props?.config?.mcpDocsServerName||"Docs MCP server",u=new URL(n.url).origin,{user:c,config:{rbac:p={},mcp:l={}}}=r,d=h(t,c,p,r.config.requiresLogin||!1),g=l.docs?.name||o,M={rbac:p,email:c?.email,teams:c?.teams,isAuthenticated:!!c?.isAuthenticated,requiresLogin:r.config.requiresLogin||!1};return await D({name:g,baseUrl:u,headers:i,apiDescriptionsMap:d,outdir:a,accessInfo:M})}catch(e){throw f.sendMcpErrorMessage([{object:"mcp_server",server_type:m.Docs,message:e?.message||"",stack:e?.stack||""}]),y(e?.message||"Internal server error mcp docs")}}const R=v({createServerInstance:I,serverType:m.Docs}),w=async(r,s,i)=>{const n=!!s?.config?.requiresLogin,e=s?.config?.rbac;if(S(n,e)){const{isAuthenticated:t,isTokenValid:a,currentUser:o}=await L(r,s);if(!t)return A(new URL(r.url).origin);if(!a)return b();o&&(s.user=o)}return R(r,s,i)};var E=w;export{E as default};