@redocly/realm 0.136.0-next.5 → 0.136.0-next.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/CHANGELOG.md +60 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  4. package/dist/cli/build/index.js +1 -1
  5. package/dist/cli/eject/resolveEjectParams.js +1 -1
  6. package/dist/cli/stats/collectors/openapi/index.js +1 -1
  7. package/dist/cli/stats/index.js +1 -1
  8. package/dist/client/App.js +1 -1
  9. package/dist/client/TestProvider.js +1 -1
  10. package/dist/client/api-docs-builder-entry.d.ts +3 -0
  11. package/dist/client/api-docs-builder-entry.js +1 -0
  12. package/dist/client/app/Feedback/useSubmitFeedback.js +1 -1
  13. package/dist/client/app/Sidebar/Sidebar.js +3 -3
  14. package/dist/client/app/Sidebar/helpers/hide-empty-separators.d.ts +13 -0
  15. package/dist/client/app/Sidebar/helpers/hide-empty-separators.js +1 -0
  16. package/dist/client/app/Sidebar/useActions.js +1 -1
  17. package/dist/client/app/Sidebar/utils.js +1 -1
  18. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
  19. package/dist/client/app/hooks/index.d.ts +1 -0
  20. package/dist/client/app/hooks/index.js +1 -1
  21. package/dist/client/app/hooks/useAutoScroll.js +1 -1
  22. package/dist/client/app/hooks/useUserClaims.js +1 -1
  23. package/dist/client/app/l10n/hooks/index.d.ts +1 -0
  24. package/dist/client/app/l10n/hooks/index.js +1 -1
  25. package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
  26. package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -0
  27. package/dist/client/app/markdoc/custom-components/openapi/json-schema.d.ts +1 -1
  28. package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
  29. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +1 -5
  30. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  31. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  32. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  33. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.d.ts +8 -24
  34. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  35. package/dist/client/app/markdoc/hooks/use-store.d.ts +8 -6
  36. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.d.ts +20 -0
  37. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.js +1 -0
  38. package/dist/client/app/markdoc/utils/find-api-item.d.ts +15 -0
  39. package/dist/client/app/markdoc/utils/find-api-item.js +1 -0
  40. package/dist/client/app/markdoc/utils/find-code-sample-panel.d.ts +11 -0
  41. package/dist/client/app/markdoc/utils/find-code-sample-panel.js +1 -0
  42. package/dist/client/app/markdoc/utils/find-openapi-response-samples.d.ts +15 -0
  43. package/dist/client/app/markdoc/utils/find-openapi-response-samples.js +1 -0
  44. package/dist/client/app/markdoc/utils/openapi-panel-entry.d.ts +18 -0
  45. package/dist/client/app/markdoc/utils/openapi-panel-entry.js +1 -0
  46. package/dist/client/app/utils/resolveRouteBySlug.js +1 -1
  47. package/dist/client/app/utils/same-resolved-route.d.ts +5 -0
  48. package/dist/client/app/utils/same-resolved-route.js +1 -0
  49. package/dist/client/providers/post-message/PostMessageProvider.js +1 -1
  50. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  51. package/dist/client/runtime/loader.js +1 -1
  52. package/dist/client/templates/api-docs/helpers.d.ts +10 -0
  53. package/dist/client/templates/api-docs/helpers.js +1 -0
  54. package/dist/client/templates/api-docs/template.d.ts +17 -0
  55. package/dist/client/templates/api-docs/template.js +14 -0
  56. package/dist/client/types/sidebar.d.ts +0 -1
  57. package/dist/client/utils/utils.d.ts +0 -2
  58. package/dist/client/utils/utils.js +1 -1
  59. package/dist/constants/common.d.ts +11 -1
  60. package/dist/constants/common.js +1 -1
  61. package/dist/constants/l10n/langs/ar.js +1 -1
  62. package/dist/constants/l10n/langs/de.js +1 -1
  63. package/dist/constants/l10n/langs/en.js +1 -1
  64. package/dist/constants/l10n/langs/es.js +1 -1
  65. package/dist/constants/l10n/langs/fr.js +1 -1
  66. package/dist/constants/l10n/langs/hi.js +1 -1
  67. package/dist/constants/l10n/langs/it.js +1 -1
  68. package/dist/constants/l10n/langs/ja.js +1 -1
  69. package/dist/constants/l10n/langs/ko.js +1 -1
  70. package/dist/constants/l10n/langs/pl.js +1 -1
  71. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  72. package/dist/constants/l10n/langs/pt.js +1 -1
  73. package/dist/constants/l10n/langs/ru.js +1 -1
  74. package/dist/constants/l10n/langs/uk.js +1 -1
  75. package/dist/constants/l10n/langs/zh.js +1 -1
  76. package/dist/server/config/env-schemas/feature-flags.d.ts +1 -1
  77. package/dist/server/constants/entitlements.js +1 -1
  78. package/dist/server/constants/plugins/api-docs.d.ts +3 -0
  79. package/dist/server/constants/plugins/api-docs.js +1 -0
  80. package/dist/server/esbuild/esbuild-logger.js +3 -3
  81. package/dist/server/esbuild/esbuild.js +3 -3
  82. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +9 -0
  83. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +1 -0
  84. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +2 -0
  85. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +1 -0
  86. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +6 -0
  87. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +1 -0
  88. package/dist/server/plugins/api-docs/get-server-props.d.ts +4 -0
  89. package/dist/server/plugins/api-docs/get-server-props.js +1 -0
  90. package/dist/server/plugins/api-docs/get-template-path.d.ts +2 -0
  91. package/dist/server/plugins/api-docs/get-template-path.js +1 -0
  92. package/dist/server/plugins/api-docs/import-api-docs-builder.d.ts +8 -0
  93. package/dist/server/plugins/api-docs/import-api-docs-builder.js +1 -0
  94. package/dist/server/plugins/api-docs/index.d.ts +19 -0
  95. package/dist/server/plugins/api-docs/index.js +1 -0
  96. package/dist/server/plugins/api-docs/loader.d.ts +35 -0
  97. package/dist/server/plugins/api-docs/loader.js +3 -0
  98. package/dist/server/plugins/api-docs/options.d.ts +14 -0
  99. package/dist/server/plugins/api-docs/options.js +1 -0
  100. package/dist/server/plugins/api-docs/search/get-ai-search-documents.d.ts +20 -0
  101. package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +105 -0
  102. package/dist/server/plugins/api-docs/search/search-facets.d.ts +10 -0
  103. package/dist/server/plugins/api-docs/search/search-facets.js +1 -0
  104. package/dist/server/plugins/api-docs/search/search-indexer.d.ts +9 -0
  105. package/dist/server/plugins/api-docs/search/search-indexer.js +1 -0
  106. package/dist/server/plugins/api-docs/search/search-resolver.d.ts +5 -0
  107. package/dist/server/plugins/api-docs/search/search-resolver.js +1 -0
  108. package/dist/server/plugins/api-docs/spec-download.api.d.ts +4 -0
  109. package/dist/server/plugins/api-docs/spec-download.api.js +1 -0
  110. package/dist/server/plugins/api-docs/store-definition-bundles.d.ts +3 -0
  111. package/dist/server/plugins/api-docs/store-definition-bundles.js +1 -0
  112. package/dist/server/plugins/api-docs/utils/build-item-positions.d.ts +17 -0
  113. package/dist/server/plugins/api-docs/utils/build-item-positions.js +1 -0
  114. package/dist/server/plugins/api-docs/utils/build-routes-mapping.d.ts +3 -0
  115. package/dist/server/plugins/api-docs/utils/build-routes-mapping.js +1 -0
  116. package/dist/server/plugins/api-docs/utils/collect-item-routes.d.ts +12 -0
  117. package/dist/server/plugins/api-docs/utils/collect-item-routes.js +1 -0
  118. package/dist/server/plugins/api-docs/utils/decorators.d.ts +26 -0
  119. package/dist/server/plugins/api-docs/utils/decorators.js +1 -0
  120. package/dist/server/plugins/api-docs/utils/format-bundle-error.d.ts +6 -0
  121. package/dist/server/plugins/api-docs/utils/format-bundle-error.js +5 -0
  122. package/dist/server/plugins/api-docs/utils/normalize-api-version.d.ts +2 -0
  123. package/dist/server/plugins/api-docs/utils/normalize-api-version.js +1 -0
  124. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.d.ts +2 -0
  125. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.js +1 -0
  126. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.d.ts +20 -0
  127. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.js +1 -0
  128. package/dist/server/plugins/api-docs/utils/replace-file-extension.d.ts +2 -0
  129. package/dist/server/plugins/api-docs/utils/replace-file-extension.js +1 -0
  130. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.d.ts +3 -0
  131. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.js +1 -0
  132. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.d.ts +10 -0
  133. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.js +1 -0
  134. package/dist/server/plugins/api-docs/utils/to-relative-slug.d.ts +2 -0
  135. package/dist/server/plugins/api-docs/utils/to-relative-slug.js +1 -0
  136. package/dist/server/plugins/api-functions/index.js +1 -1
  137. package/dist/server/plugins/arazzo-docs/index.js +1 -1
  138. package/dist/server/plugins/asyncapi-docs/index.js +1 -1
  139. package/dist/server/plugins/catalog-classic/index.js +1 -1
  140. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  141. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +13 -5
  142. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  143. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  144. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +6 -5
  145. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  146. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +12 -5
  147. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  148. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  149. package/dist/server/plugins/catalog-entities/template/index.js +1 -1
  150. package/dist/server/plugins/catalog-entities/types/openapi.d.ts +1 -1
  151. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.d.ts +3 -3
  152. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
  153. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.d.ts +4 -3
  154. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.js +1 -1
  155. package/dist/server/plugins/config-parser/index.js +1 -1
  156. package/dist/server/plugins/create-slugify.d.ts +17 -0
  157. package/dist/server/plugins/create-slugify.js +1 -0
  158. package/dist/server/plugins/default-theme/index.js +1 -1
  159. package/dist/server/plugins/dev-onboarding/index.js +1 -1
  160. package/dist/server/plugins/entitlements/index.js +1 -1
  161. package/dist/server/plugins/graphql-docs/index.js +1 -1
  162. package/dist/server/plugins/helpers/parse-partials.d.ts +3 -0
  163. package/dist/server/plugins/helpers/parse-partials.js +1 -0
  164. package/dist/server/plugins/l10n/index.js +1 -1
  165. package/dist/server/plugins/lifecycle.js +2 -2
  166. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +5 -3
  167. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.js +1 -1
  168. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -1
  169. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  170. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
  171. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.js +1 -1
  172. package/dist/server/plugins/markdown/index.js +1 -1
  173. package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
  174. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +1 -0
  175. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  176. package/dist/server/plugins/mcp/codemode/constants.js +1 -1
  177. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  178. package/dist/server/plugins/mcp/codemode/tools/execute.d.ts +1 -0
  179. package/dist/server/plugins/mcp/constants.d.ts +1 -0
  180. package/dist/server/plugins/mcp/constants.js +1 -1
  181. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +1 -0
  182. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  183. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.d.ts +11 -0
  184. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -0
  185. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.d.ts +4 -0
  186. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.js +1 -0
  187. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
  188. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type.js +7 -4
  189. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +7 -1
  190. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.js +0 -1
  191. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.d.ts +5 -1
  192. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.js +4 -2
  193. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +4 -0
  194. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  195. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +1 -1
  196. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +1 -1
  197. package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +1 -1
  198. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +4 -2
  199. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +2 -2
  200. package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +1 -2
  201. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +1 -1
  202. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +4 -2
  203. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  204. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.d.ts +11 -0
  205. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.js +1 -0
  206. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.d.ts +13 -0
  207. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.js +1 -0
  208. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.d.ts +4 -0
  209. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.js +1 -0
  210. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.d.ts +12 -0
  211. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.js +1 -1
  212. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -1
  213. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.d.ts +3 -1
  214. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.js +1 -1
  215. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  216. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.d.ts +3 -0
  217. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.js +1 -0
  218. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.d.ts +16 -0
  219. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.js +1 -0
  220. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.d.ts +2 -0
  221. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +1 -0
  222. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.d.ts +7 -0
  223. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.js +1 -0
  224. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.d.ts +15 -0
  225. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.js +1 -0
  226. package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +8 -8
  227. package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -1
  228. package/dist/server/plugins/mcp/gateway-mcp/subject.d.ts +20 -0
  229. package/dist/server/plugins/mcp/gateway-mcp/subject.js +1 -0
  230. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  231. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  232. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  233. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +26 -26
  234. package/dist/server/plugins/mcp/index.js +1 -1
  235. package/dist/server/plugins/mcp/servers/docs-server.d.ts +3 -1
  236. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  237. package/dist/server/plugins/mcp/servers/mcp-server.d.ts +2 -0
  238. package/dist/server/plugins/mcp/servers/mcp-server.js +1 -1
  239. package/dist/server/plugins/mcp/servers/session-manager.js +1 -1
  240. package/dist/server/plugins/mcp/types.d.ts +4 -2
  241. package/dist/server/plugins/mcp/utils/mode.js +1 -1
  242. package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +8 -0
  243. package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -0
  244. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +1 -1
  245. package/dist/server/plugins/mcp/utils.d.ts +17 -5
  246. package/dist/server/plugins/mcp/utils.js +1 -1
  247. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  248. package/dist/server/plugins/openapi-docs/index.js +1 -1
  249. package/dist/server/plugins/openapi-docs/utils.js +1 -1
  250. package/dist/server/plugins/pages/index.js +1 -1
  251. package/dist/server/plugins/scorecard-classic/compute-scorecard.js +4 -4
  252. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  253. package/dist/server/plugins/scorecards/plugin.js +1 -1
  254. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +2 -2
  255. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  256. package/dist/server/plugins/search/index.js +1 -1
  257. package/dist/server/plugins/search/llmstxt/index.js +4 -4
  258. package/dist/server/plugins/sidebars/index.js +1 -1
  259. package/dist/server/plugins/sitemap/index.js +1 -1
  260. package/dist/server/plugins/sso/index.js +1 -1
  261. package/dist/server/ssr/render.js +1 -1
  262. package/dist/server/ssr/utils.d.ts +1 -0
  263. package/dist/server/ssr/utils.js +5 -5
  264. package/dist/server/store.d.ts +2 -6
  265. package/dist/server/store.js +1 -1
  266. package/dist/server/types/plugins/common.d.ts +3 -5
  267. package/dist/server/types/plugins/markdown.d.ts +1 -3
  268. package/dist/server/types/plugins/search.d.ts +1 -0
  269. package/dist/server/utils/catalog-classic/get-route-slug-to-catalog-slug-map.test.js +1 -1
  270. package/dist/server/utils/rbac.d.ts +4 -0
  271. package/dist/server/utils/rbac.js +1 -1
  272. package/dist/server/utils/report-all-errors.js +1 -1
  273. package/dist/server/utils/shared-data.js +1 -1
  274. package/dist/server/web-server/routes/resolve-route.js +1 -1
  275. package/dist/server/workers/worker-pool.js +1 -1
  276. package/dist/types/entitlements.d.ts +3 -0
  277. package/dist/types/markdoc.d.ts +2 -1
  278. package/dist/utils/url/get-shared-data-fetch-url.d.ts +17 -0
  279. package/dist/utils/url/get-shared-data-fetch-url.js +1 -0
  280. package/package.json +9 -8
  281. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.d.ts +0 -4
  282. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.js +0 -1
  283. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.d.ts +0 -4
  284. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.js +0 -1
  285. package/dist/markdoc/helpers/get-operation/get-operation.d.ts +0 -14
  286. package/dist/markdoc/helpers/get-operation/get-operation.js +0 -1
  287. package/dist/markdoc/helpers/get-operation/index.d.ts +0 -4
  288. package/dist/markdoc/helpers/get-operation/index.js +0 -1
  289. package/dist/markdoc/helpers/get-operation/types/index.d.ts +0 -4
  290. package/dist/markdoc/helpers/get-operation/types/index.js +0 -0
  291. package/dist/markdoc/helpers/get-operation/types/operation-identifier.d.ts +0 -5
  292. package/dist/markdoc/helpers/get-operation/types/operation-identifier.js +0 -0
  293. package/dist/markdoc/helpers/get-operation/types/operation-info.d.ts +0 -6
  294. package/dist/markdoc/helpers/get-operation/types/operation-info.js +0 -0
  295. package/dist/markdoc/helpers/get-operation/types/operation-parameters.d.ts +0 -3
  296. package/dist/markdoc/helpers/get-operation/types/operation-parameters.js +0 -0
  297. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.d.ts +0 -4
  298. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.js +0 -1
@@ -0,0 +1,10 @@
1
+ import type { SearchFacet } from '@redocly/theme/core/types';
2
+ export declare function setDocumentSearchFacets(documentSearchFacets: {
3
+ [key: string]: string | Set<string>;
4
+ }, getSearchFacets: () => Map<string, SearchFacet>, setSearchFacets: (searchFacets: Map<string, SearchFacet>) => void): void;
5
+ export declare function extractDocumentSearchFacets(metadata: {
6
+ [key: string]: unknown;
7
+ }, apiTitle: string | undefined, apiVersion: string | undefined, getSearchFacets: () => Map<string, SearchFacet>): {
8
+ [key: string]: string;
9
+ };
10
+ //# sourceMappingURL=search-facets.d.ts.map
@@ -0,0 +1 @@
1
+ import{SEARCH_GROUP_FACET_FIELD as a}from"../../../../constants/common.js";import{SEARCH_GROUP_NAME_API as u}from"../../../constants/plugins/search.js";function F(e,n,s){const f=n();for(const[t,o]of Object.entries(e)){const c=f.get(t);if(c){const r=new Set(c.values??[]);if(o instanceof Set)for(const i of o)r.add(i);else r.add(o);c.values=Array.from(r)}}s(f)}function h(e,n,s,f){const t={[a]:u,...n&&{apiTitle:n},...s&&{apiVersion:s}};if(!e)return t;const o=f();for(const[c,r]of Object.entries(e))o.has(c)&&(t[c]=String(r));return e.title&&(t.apiTitle=String(e.title)),t}export{h as extractDocumentSearchFacets,F as setDocumentSearchFacets};
@@ -0,0 +1,9 @@
1
+ import type { ApiItem, SchemaEntry } from '@redocly/api-docs';
2
+ import type { SearchDocument } from '../../../types';
3
+ export declare class ApiDocsSearchIndexer {
4
+ #private;
5
+ constructor(basePath: string, schemaStore?: Record<string, SchemaEntry>, document?: Record<string, unknown>);
6
+ addItem(item: ApiItem): void;
7
+ getResult(): SearchDocument[];
8
+ }
9
+ //# sourceMappingURL=search-indexer.d.ts.map
@@ -0,0 +1 @@
1
+ import{REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{extractFullText as W,nodeTypes as g,contentType as P,schemaKind as j}from"@redocly/api-docs";import{toMarkdown as H}from"../../markdown/search/to-markdown.js";const L=10,_=200,C="message payload",D="message headers";function E(h){if(typeof h=="string")return h;const e=Array.isArray(h)?h:[h];return H(e).trim()}function N(h){return h.length>_?`${h.slice(0,_)}\u2026`:h}class B{#c=[];#i;#s;#o;#f;constructor(e,t,n){this.#i=e,this.#s=t,this.#o=n}addItem(e){if(!(!e.link||!e.content))try{switch(e.content.contentType){case P.OVERVIEW:this.#a(e,this.#i);break;case P.GROUP:case P.ITEM:this.#a(e,e.link);break}}catch(t){console.error(`Cannot add item to api-docs search indexer [${e.label}, ${e.link}]:`,t.message)}}#a(e,t){if(!e.content)return;const n=t.startsWith(this.#i+"/")?t.slice(this.#i.length+1):t.split("/").slice(-2).join("/"),i=e.content.children,o=this.#p(i),f=this.#y(i,n),r=e,s={id:t,url:t,title:e.label??"",text:o,path:[],deprecated:e.content.meta?.deprecated,..."httpVerb"in e&&e.httpVerb?{httpMethod:e.httpVerb}:{},..."httpPath"in e&&e.httpPath?{httpPath:e.httpPath}:{},..."badges"in e&&Array.isArray(e.badges)&&e.badges.length?{badges:e.badges}:{},..."isAdditionalOperation"in e&&e.isAdditionalOperation?{isAdditionalOperation:!0}:{},[p]:r[p],...f.length&&{parameters:f}};this.#c.push(s)}#p(e){const t=[],n=i=>{for(const o of i)if(o.nodeType===g.MARKDOC){const f=o;if(this.#h(f.content))continue;const r=W(f.content);r&&t.push(r)}else(o.nodeType===g.CONTAINER||o.nodeType===g.OVERVIEW_SECTION_WRAPPER)&&n(o.children)};return n(e),t.join(" ").trim()}#h(e){let t=!1,n=!1;const i=f=>{f.type==="code"&&f.attributes?.content?t=!0:f.type==="text"&&f.attributes?.content&&(n=!0);for(const r of f.children??[])i(r)},o=Array.isArray(e)?e:[e];for(const f of o)i(f);return t&&!n}#y(e,t){const n={},i=new Set,o=f=>{for(const r of f)if(r.nodeType===g.ITEM){const s=r;if(s[p])continue;if(s.parameters?.length)for(const a of s.parameters){if(a[p])continue;const d=this.#O(s.variant),c=this.#$(s.variant),u=a.description?E(a.description):"",l=this.#A(a.schemaId),$={name:a.name,description:u,place:d,mediaType:void 0,type:l,required:a.required??!1,deepLink:this.#d(t,"request",c,void 0,void 0,[a.name]),example:void 0,enum:void 0};n[this.#n($)]=$}this.#g(s,n,i,t)}else if(r.nodeType===g.CONTAINER){const s=r;if(s[p])continue;o(s.children)}else r.nodeType===g.OVERVIEW_SECTION_WRAPPER&&o(r.children)};return o(e),Object.values(n)}#n(e){return[...Array.isArray(e.path)?e.path:[],e.name.toString()].join(".")+e.description+e.place}#d(e,t,n,i,o,f){if(!e)return"";const r=f.join("/"),s=[`t=${t}`];return n&&s.push(`in=${n}`),o&&s.push(`c=${o}`),i&&s.push(`ct=${i}`),r&&s.push(`path=${r}`),`/${e}#${e}/${s.join("&")}`.toLowerCase()}#m(e,t,n,i){if(!e)return"";let o="messages";t&&(o+=`&m=${t}`),o+=`&t=${n}`;const f=i.join("/");return f&&(o+=`&path=${f}`),`/${e}#${e}/${o}`.toLowerCase()}#$(e){switch(e){case"query":return"query";case"path":return"path";case"headers":return"header";case"cookies":return"cookie";default:return}}#O(e){switch(e){case"query":return"query parameters";case"path":return"path parameters";case"headers":return"header parameters";case"cookies":return"cookie parameters";case"parameters":return"channel parameters";default:return e?`${e} parameters`:"parameters"}}#A(e){const t=this.#s?.[e];if(!t||t.kind!==j.JSON_SCHEMA)return"unknown";const n=t.data,i=this.#l(n);return this.#u(i)}#u(e){return Array.isArray(e.type)?e.type.join(" | "):e.type?e.type:e.properties||e.additionalProperties?"object":e.items?"array":e.enum?"string":"any"}#g(e,t,n,i){const o=this.#E(e);if(e.graphqlSchema&&Array.isArray(e.graphqlSchema)){this.#S(e.graphqlSchema,o,t);return}if(!this.#s||!this.#o)return;const f=o.startsWith("response");if(e.mediaTypeSchemas){const r=Object.entries(e.mediaTypeSchemas),s=r.find(([,a])=>!a[p]);if(s){const[a,d]=s;d.schemaId&&this.#r(d.schemaId,o,a,r.length>1,f,t,[],n,i)}}else e.schemaId&&this.#r(e.schemaId,o,void 0,!1,f,t,[],n,i);if(e.responses)for(const r of e.responses){if(r[p])continue;const s=`response ${r.code} fields`,a=new Set;if(r.mediaTypeContent){const d=Object.entries(r.mediaTypeContent),c=d.find(([,u])=>!u[p]);if(c){const[u,l]=c;l.schemaId&&this.#r(l.schemaId,s,u,d.length>1,!0,t,[],a,i)}}else r.schemaId&&this.#r(r.schemaId,s,r.mediaType,!1,!0,t,[],a,i)}if(e.messages)for(const r of e.messages){if(r[p])continue;const s=r.description?E(r.description):"",a=r.summary??"",d={name:r.name,description:(s+a).trim(),place:"message",mediaType:void 0,type:"unknown",required:!1,example:void 0,enum:void 0};t[this.#n(d)]=d,this.#f=r.name;const c=new Set;r.schemaId&&this.#r(r.schemaId,C,r.contentType,!1,!1,t,[],c,i),r.headerSchemaId&&this.#r(r.headerSchemaId,D,void 0,!1,!1,t,[],c,i),this.#f=void 0}}#E(e){switch(e.variant){case"body":return"request fields";case"responses":return"response fields";case"graphql-fields":return"fields";case"graphql-args":return"arguments";case"return-type":return"return type fields";default:return e.variant??"fields"}}#S(e,t,n){for(const i of e){const o=i.description?E(i.description):"",f={name:i.name,description:o,place:t,mediaType:void 0,path:[],type:i.type??"unknown",required:!1,example:void 0,enum:void 0};if(n[this.#n(f)]=f,i.args?.length)for(const r of i.args){const s=r.description?E(r.description):"",a={name:r.name,description:s,place:"arguments",mediaType:void 0,path:[i.name],type:r.type??"unknown",required:!1,example:void 0,enum:void 0};n[this.#n(a)]=a}}}#r(e,t,n,i,o,f,r,s,a=""){const d=this.#s?.[e];if(!d||d.kind!==j.JSON_SCHEMA||d[p])return;const c=d.data,u=i?n:void 0;this.#t(c,t,n,u,o,f,r,s,0,a)}#I(e){const t=e.match(/^response (\d+)/);return t?t[1]:void 0}#l(e){if(e.allOf){const t={};for(const n of e.allOf){const i=n.$ref?this.#e(n.$ref):n;if(i){const o=t.properties,f=t.required;Object.assign(t,i),(o||i.properties)&&(t.properties={...o||{},...i.properties||{}}),(f||i.required)&&(t.required=[...f||[],...i.required||[]])}}return delete t.allOf,e.description&&(t.description=e.description),t}if(e.$ref){const t=this.#e(e.$ref);if(t){const n={...t};return e.description&&(n.description=e.description),n}}return e}#e(e){if(!e.startsWith("#/"))return;const t=e.slice(2).split("/");let n=this.#o;for(const i of t){if(n==null||typeof n!="object")return;n=n[i]}return n!=null&&typeof n=="object"?n:void 0}#t(e,t,n,i,o,f,r,s,a,d=""){if(!(a>L||e[p])){if(e.$ref){if(s.has(e.$ref))return;s.add(e.$ref);const c=this.#e(e.$ref);c&&this.#t(c,t,n,i,o,f,r,s,a,d);return}if(e.allOf){const c={};for(const u of e.allOf){let l=u;if(u.$ref){if(s.has(u.$ref))continue;s.add(u.$ref),l=this.#e(u.$ref)}if(l){const $=c.properties,A=c.required;Object.assign(c,l),($||l.properties)&&(c.properties={...$||{},...l.properties||{}}),(A||l.required)&&(c.required=[...A||[],...l.required||[]])}}delete c.allOf,this.#t(c,t,n,i,o,f,r,s,a,d);return}if(e.discriminator&&e.properties&&e.oneOf){this.#t({...e,oneOf:void 0,discriminator:void 0},t,n,i,o,f,r,s,a,d);return}if(e.oneOf||e.anyOf){for(const c of e.oneOf||e.anyOf||[]){if(c.$ref){if(s.has(c.$ref))continue;s.add(c.$ref)}const u=c.$ref?this.#e(c.$ref):c;u&&this.#t(u,t,n,i,o,f,r,s,a+1,d)}return}if(e.properties){const c=e.required||[],u=this.#I(t),l=o?"response":"request",$=t===C?"payload":t===D?"headers":void 0;for(const[A,O]of Object.entries(e.properties)){if(O[p])continue;if(O.$ref){if(s.has(O.$ref))continue;s.add(O.$ref)}const m=O.$ref?this.#e(O.$ref):O;if(!m)continue;let x=!1;if(m.allOf){let b=!1;for(const q of m.allOf)q.$ref?s.has(q.$ref)||(s.add(q.$ref),b=!0):b=!0;x=!b}const y=this.#l(m);if(m[p]||y[p]||y.readOnly&&!o||y.writeOnly&&o||m.additionalProperties!==void 0&&!m.properties)continue;const T=m.description??y.description,R=T?E(T):"",S=m.example??y.example,V=S!==void 0?N(typeof S=="string"?S:JSON.stringify(S)):void 0,v=Array.isArray(y.enum)&&y.enum.length?y.enum:void 0,I=[...r,A],w={name:A,description:R,place:t,mediaType:n,path:r,type:this.#u(y),required:c.includes(A),deepLink:$?this.#m(d,this.#f,$,I):this.#d(d,l,void 0,i,u,I),example:V,enum:v},k=this.#n(w);f[k]==null&&(f[k]=w,x||this.#t(y,t,n,i,o,f,I,s,a+1,d))}}if(e.items&&typeof e.items=="object"&&!Array.isArray(e.items)){if(e.items.$ref){if(s.has(e.items.$ref))return;s.add(e.items.$ref)}const c=e.items.$ref?this.#e(e.items.$ref):e.items;c&&this.#t(c,t,n,i,o,f,r,s,a+1,d)}}}getResult(){return this.#c}}export{B as ApiDocsSearchIndexer};
@@ -0,0 +1,5 @@
1
+ import type { SearchFacet } from '@redocly/theme/core/types';
2
+ import type { ApiItem, ApiDocsMetadata, ApiStore } from '@redocly/api-docs';
3
+ import type { PageRouteDetails, SearchDocument } from '../../../types';
4
+ export declare function searchResolver(items: ApiItem[], metadata: ApiDocsMetadata, getSearchFacets: () => Map<string, SearchFacet>, setSearchFacets: (searchFacets: Map<string, SearchFacet>) => void, excludeFromSearch?: boolean, store?: ApiStore, document?: Record<string, unknown>): (route: PageRouteDetails) => Promise<SearchDocument[]>;
5
+ //# sourceMappingURL=search-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ import{REDOCLY_ROUTE_RBAC as p,REDOCLY_TEAMS_RBAC as o}from"@redocly/config";import{extractDocumentSearchFacets as A,setDocumentSearchFacets as D}from"./search-facets.js";import{ApiDocsSearchIndexer as d}from"./search-indexer.js";import{normalizeApiVersion as x}from"../utils/normalize-api-version.js";function O(h,i,c,u,R,g,S){return async e=>{if(R)return[];const a=e.baseSlug||e.slug,m=new d(a,g?.schemaStore,S),f=t=>{for(const r of t)m.addItem(r),r.items?.length&&f(r.items)};f(h);const s=typeof i.title=="string"?i.title:void 0,n=x(i.version),l=A(e.metadata||{},s,n,c);return D(l,c,u),m.getResult().map(t=>({...t,...t.url===a&&s&&{title:n?`${s} (${n})`:s},[o]:t[o]??e[o],[p]:e[p]??{slug:e.slug,fsPath:e.fsPath},facets:l}))}}export{O as searchResolver};
@@ -0,0 +1,4 @@
1
+ import type { ApiRoutesHandler } from '@redocly/config';
2
+ declare const specDownloadApi: ApiRoutesHandler;
3
+ export default specDownloadApi;
4
+ //# sourceMappingURL=spec-download.api.d.ts.map
@@ -0,0 +1 @@
1
+ import e from"node:path";import{existsSync as c}from"node:fs";import{readFile as F}from"node:fs/promises";import C from"js-yaml";import{withoutPathPrefix as U}from"@redocly/theme/core/utils";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as I,PUBLIC_API_DEFINITIONS_FOLDER as p}from"../../constants/common.js";import{GRAPHQL_SPEC_SLUG as y}from"../../../constants/common.js";import{canDownloadApiDefinition as O,filterDataByAccessDeep as q}from"../../utils/rbac.js";function A(a,t){const n=e.parse(a);return e.join(n.dir,n.name+t)}const T=async(a,t,n)=>{const{isAuthenticated:i,teams:l,claims:{email:f}}=t.user,S=new URL(a.url),o=U(S.pathname),m=o.startsWith(y),s=decodeURIComponent(m?o.replace(y,""):o.replace(p,"").replace(I,"")),{rbac:u={},requiresLogin:d=!1}=t.config.access||{};if(!O(o,u,d,{isAuthenticated:i,email:f,teams:l}))return new Response("Unauthorized",{status:i?403:401});const r=n.props?.outdir||"";if(m){const E=e.join(r,p,s);if(!c(E))return new Response("Not found",{status:404});const x=await F(E,"utf-8");return new Response(x,{headers:{"Content-Type":"application/graphql"}})}const h=e.join(r,p,A(s,".json")),P=e.join(r,I,A(s,".json")),R=c(h),_=c(P);if(!R&&!_)return new Response("Not found",{status:404});const L=await F(R?h:P,"utf-8"),N=JSON.parse(L),w=q(N,{isAuthenticated:i,email:f,teams:l},u,d),D=e.extname(s),j=D===".yaml"?C.dump(w):JSON.stringify(w,null,2);return new Response(j,{headers:{"Content-Type":D===".yaml"?"application/yaml":"application/json"}})};var k=T;export{k as default};
@@ -0,0 +1,3 @@
1
+ import type { BundledApiDefinition } from './loader.js';
2
+ export declare function storeDefinitionBundles(definitions: BundledApiDefinition[], outDir: string): void;
3
+ //# sourceMappingURL=store-definition-bundles.d.ts.map
@@ -0,0 +1 @@
1
+ import{writeFileSync as m}from"fs";import p from"path";import{print as d}from"graphql";import{PUBLIC_API_DEFINITIONS_FOLDER as h,PUBLIC_STATIC_FOLDER as a}from"../../constants/common.js";import{logger as u}from"../../tools/notifiers/logger.js";import{ensureDir as g}from"../../utils/fs.js";import{replaceFileExtension as S}from"./utils/replace-file-extension.js";const r=new Map;function D(f,t){const n=h.slice(1);try{for(const e of f){const{document:s,relativePath:i,hash:o,type:c}=e;if(r.get(i)!==o){if(c==="graphql"){l({outDir:t,definitionFolder:n,relativePath:i,definitionString:d(s)}),r.set(i,o);continue}if(i.startsWith(a+"/")){l({outDir:t,definitionFolder:".",relativePath:i.replace(a+"/",""),definitionString:JSON.stringify(s,null,2)}),r.set(i,o);continue}l({outDir:t,definitionFolder:n,relativePath:S(i,".json"),definitionString:JSON.stringify(s,null,2)}),r.set(i,o)}}}catch(e){u.error("failed to store definition bundles",e)}}function l({outDir:f,definitionString:t,relativePath:n,definitionFolder:e}){m(g(p.resolve(f,`${e}/${n}`)),t,"utf8")}export{D as storeDefinitionBundles};
@@ -0,0 +1,17 @@
1
+ import type { ApiItem } from '@redocly/api-docs';
2
+ export type ItemPosition = {
3
+ position: {
4
+ start: {
5
+ lineNumber: number;
6
+ column: number;
7
+ };
8
+ end?: {
9
+ lineNumber: number;
10
+ column: number;
11
+ };
12
+ };
13
+ startLine: number;
14
+ endLine: number;
15
+ };
16
+ export declare function buildItemPositions(items: ApiItem[], baseSlug: string, acc?: Record<string, ItemPosition>): Record<string, ItemPosition>;
17
+ //# sourceMappingURL=build-item-positions.d.ts.map
@@ -0,0 +1 @@
1
+ import{toRelativeSlug as s}from"./to-relative-slug.js";function m(r,n,i={}){for(const t of r){const e=t.content?.meta?.position,o=t.routeSlug??t.link;e&&o&&(i[s(o,n)]={position:e,startLine:e.start.lineNumber,endLine:e.end?.lineNumber??e.start.lineNumber}),t.items?.length&&m(t.items,n,i)}return i}export{m as buildItemPositions};
@@ -0,0 +1,3 @@
1
+ import type { ApiItem } from '@redocly/api-docs';
2
+ export declare function buildRoutesMapping(items: ApiItem[], baseSlug: string, acc?: Record<string, string>): Record<string, string>;
3
+ //# sourceMappingURL=build-routes-mapping.d.ts.map
@@ -0,0 +1 @@
1
+ import{toRelativeSlug as u}from"./to-relative-slug.js";function f(r,e,o={}){for(const t of r){const i=t.content?.meta?.pointer,n=t.routeSlug??t.link;i&&n&&(o[`#${i}`]=u(n,e)),t.items?.length&&f(t.items,e,o)}return o}export{f as buildRoutesMapping};
@@ -0,0 +1,12 @@
1
+ import { REDOCLY_TEAMS_RBAC } from '@redocly/config';
2
+ import type { ApiItem } from '@redocly/api-docs';
3
+ import type { RbacScopeItems } from '@redocly/config';
4
+ export type ItemRouteEntry = {
5
+ link: string;
6
+ label?: string;
7
+ httpVerb?: string;
8
+ metadata?: Record<string, unknown>;
9
+ [REDOCLY_TEAMS_RBAC]?: RbacScopeItems;
10
+ };
11
+ export declare function collectItemRoutes(items: ApiItem[], configRbac?: RbacScopeItems, inheritedRbac?: RbacScopeItems): ItemRouteEntry[];
12
+ //# sourceMappingURL=collect-item-routes.d.ts.map
@@ -0,0 +1 @@
1
+ import{REDOCLY_TEAMS_RBAC as n}from"@redocly/config";function i(m,o,l){const e=[];for(const t of m){const s=t[n],a=s??l??o;t.link&&e.push({link:t.link,label:t.label,httpVerb:t.httpVerb,metadata:t.metadata,[n]:a}),t.items&&t.items.length>0&&e.push(...i(t.items,o,s??l))}return e}export{i as collectItemRoutes};
@@ -0,0 +1,26 @@
1
+ import type { RawUniversalConfig } from '@redocly/openapi-core';
2
+ export declare function isPlainNonMarkdownText(markdown: string): boolean;
3
+ export declare const MarkdownParserDecorator: ({ outputRelativePath, cwd, }: {
4
+ outputRelativePath: string;
5
+ cwd: string;
6
+ }) => {
7
+ any: {
8
+ leave(node: Record<string, unknown>, ctx: any): void;
9
+ };
10
+ ref: {
11
+ leave(node: Record<string, unknown>, ctx: any): void;
12
+ };
13
+ };
14
+ export declare const RbacDecorator: () => {
15
+ Tag: {
16
+ enter(node: Record<string, unknown>): void;
17
+ };
18
+ any: {
19
+ leave(node: Record<string, unknown>, ctx: any): void;
20
+ };
21
+ ref: {
22
+ leave(node: Record<string, unknown>): void;
23
+ };
24
+ };
25
+ export declare function injectDecoratorIntoConfig(config: RawUniversalConfig, outputRelativePath: string, cwd: string): RawUniversalConfig;
26
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ import b from"node:path";import{REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{slash as k}from"../../../../utils/path/slash.js";function f(t,r,a){if(!r)throw new Error("Visitor required");if(t){t.description&&r(t,"description",a.location.absolutePointer+"/description",a);for(const o in t["x-enumDescriptions"])r(t["x-enumDescriptions"],o,a.location.absolutePointer+"/x-enumDescriptions/"+o,a)}}const x=/^[a-zA-Z0-9\s\-,.!\?:;'"()/]+$/,d=/^\s*(?:[-+*]\s|\d+[.)]\s)/m;function g(t){return x.test(t)&&!d.test(t)}const s=({outputRelativePath:t,cwd:r})=>{const a=function(e,m,l,u){const{node:n}=u.resolve(e[m]);if(!n||typeof n!="string"||g(n))return;const i=u.getVisitorData();i.markdocChunks=i.markdocChunks||[],i.markdocChunks.push({node:e,pointer:k(b.relative(r,l)),markdown:n,relativePath:t,key:m})};return{any:{leave(o,e){f(o,a,e)}},ref:{leave(o,e){f(o,a,e)}}}},c=()=>{const t={};return{Tag:{enter(r){r?.["x-rbac"]&&(t[String(r.name)]=r["x-rbac"])}},any:{leave(r,a){if((a.type.name==="Operation"||a.type.name==="Webhook")&&"tags"in r&&Array.isArray(r.tags))for(const o of r.tags)t[o]&&(r["x-rbac"]=r["x-rbac"]||t[o]);r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}},ref:{leave(r){r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}}}};function D(t,r,a){const o={id:"markdown",decorators:{oas2:{markdown:s,rbac:c},oas3:{markdown:s,rbac:c},async3:{markdown:s,rbac:c}}};return{...t,decorators:{"markdown/rbac":"on","markdown/markdown":{outputRelativePath:r,cwd:a},...t.decorators||{}},plugins:[...t.plugins||[],o]}}export{s as MarkdownParserDecorator,c as RbacDecorator,D as injectDecoratorIntoConfig,g as isPlainNonMarkdownText};
@@ -0,0 +1,6 @@
1
+ import { type NormalizedProblem } from '@redocly/openapi-core';
2
+ /**
3
+ * Formats a bundle error with file path, line/column, and codeframe for better debugging.
4
+ */
5
+ export declare function formatBundleError(problem: NormalizedProblem, cwd: string): Promise<string>;
6
+ //# sourceMappingURL=format-bundle-error.d.ts.map
@@ -0,0 +1,5 @@
1
+ import f from"node:path";import{getLineColLocation as m,isAbsoluteUrl as g}from"@redocly/openapi-core";import{gray as s}from"../../../tools/notifiers/helpers/colors.js";import{getCodeframe as h}from"../../../utils/codeframes/codeframes.js";async function P(o,c){const e=o.location?.[0];if(!e)return`${o.message} at `;if(!e.source){const t=e.pointer??"";return`${o.message} at ${t}`}const n=g(e.source.absoluteRef)?e.source.absoluteRef:f.relative(c,e.source.absoluteRef);try{const t=m(e),i=e.pointer?s(`at ${e.pointer}`):"",l=`${n}:${t.start.line}:${t.start.col}`;let r="";try{const a=e.source?.getLines()??[],u={start:{line:t.start.line,character:t.start.col},end:{line:t.end?.line??t.start.line,character:t.end?.col??Math.max(t.start.col+1,a[t.start.line-1]?.length??t.start.col)},lines:a},{frame:$}=h(u,!0);r=$}catch{r=""}return`${l} ${i}
2
+ ${o.message}
3
+ ${r?`${r}
4
+ `:""}`}catch{const t=e.pointer?s(`at ${e.pointer}`):"";return`${n} ${t}
5
+ ${o.message}`}}export{P as formatBundleError};
@@ -0,0 +1,2 @@
1
+ export declare function normalizeApiVersion(value: unknown): string | undefined;
2
+ //# sourceMappingURL=normalize-api-version.d.ts.map
@@ -0,0 +1 @@
1
+ function r(n){if(!(n==null||typeof n=="object"))return String(n)}export{r as normalizeApiVersion};
@@ -0,0 +1,2 @@
1
+ export declare function normalizeFeedbackOptions(feedbackOptions: Record<string, any> | null | undefined): Record<string, any> | undefined;
2
+ //# sourceMappingURL=normalize-feedback-options.d.ts.map
@@ -0,0 +1 @@
1
+ import{FEEDBACK_TYPES as t}from"../../../../constants/common.js";function o(s){if(!s)return;let e="";const{type:i,settings:a}=s;switch(i){case t.RATING:e="Rate this section";break;case t.SENTIMENT:e="Was this section helpful?";break;case t.MOOD:e="Was this section helpful?";break;case t.COMMENT:e="Share your feedback about this section";break;case t.SCALE:e="How would you rate this section?";break}return{...s,settings:{...a,label:a?.label||e}}}export{o as normalizeFeedbackOptions};
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Convert a spec file's relative path to its base route slug, applying the same
3
+ * l10n transform the route builder uses (`@l10n/de/foo.yaml` -> `/de/foo`).
4
+ *
5
+ * Index files map to their directory URL (`foo/index.yaml` -> `/foo`). The
6
+ * index decision reuses `parseBaseName` — the exact primitive the core route
7
+ * slugifier uses (`isIndexFile` in server/plugins/lifecycle.ts) — so it can't
8
+ * drift from the core / openapi-docs. Without it, an API mounted at
9
+ * `output: foo/index.yaml` would land at `/foo/index` and break links/sidebar
10
+ * entries that reference it by its `index.yaml` output path.
11
+ *
12
+ * NOTE: this transform does NOT apply the content-slugs normalizations
13
+ * (versioned `@x.y` folders, custom slugs) — route building derives slugs
14
+ * through `createSlugify` instead. It is used by the loader-time mock-server
15
+ * URL (`options.ts`) and by `rebaseAutoMockServerUrl` (`index.ts`), which
16
+ * reconstructs the same value to detect the auto-generated URL and rebase it
17
+ * onto the normalized route slug.
18
+ */
19
+ export declare function relativePathToBaseSlug(relativePath: string): string;
20
+ //# sourceMappingURL=relative-path-to-base-slug.d.ts.map
@@ -0,0 +1 @@
1
+ import i from"node:path";import{isL10nPath as m}from"../../../fs/utils/is-l10n-path.js";import{getLocaleFromRelativePath as n}from"../../../fs/utils/get-locale-from-relative-path.js";import{removeL10nPrefix as s}from"../../../fs/utils/remove-l10n-prefix.js";import{parseBaseName as p}from"../../utils.js";function h(r){const{baseName:t,isIndexFile:a}=p(r),e=i.posix.dirname(r),o=a?e==="."?"":e:e==="."?t:i.posix.join(e,t);return m(o)?("/"+n(o).toLowerCase()+"/"+s(o)).replace(/\/{2,}/g,"/"):("/"+o).replace(/\/{2,}/g,"/")}export{h as relativePathToBaseSlug};
@@ -0,0 +1,2 @@
1
+ export declare function replaceFileExtension(filePath: string, fileExt: string): string;
2
+ //# sourceMappingURL=replace-file-extension.d.ts.map
@@ -0,0 +1 @@
1
+ import n from"node:path";function s(o,e){const i=n.posix.dirname(o),p=n.posix.basename(o,n.posix.extname(o))+e;return n.posix.join(i,p)}export{s as replaceFileExtension};
@@ -0,0 +1,3 @@
1
+ import type { ApiItem } from '@redocly/api-docs';
2
+ export declare function resolveApiDocTitle(info: Record<string, unknown> | undefined, type: string, navItems: ApiItem[]): string | undefined;
3
+ //# sourceMappingURL=resolve-api-doc-title.d.ts.map
@@ -0,0 +1 @@
1
+ function n(e,r,i){if(typeof e?.title=="string")return e.title;if(r==="graphql"){const t=i[0]?.label;if(typeof t=="string")return t}}export{n as resolveApiDocTitle};
@@ -0,0 +1,10 @@
1
+ import type { RbacScopeItems } from '@redocly/config';
2
+ type ConfigWithRbac = {
3
+ access?: {
4
+ rbac?: unknown;
5
+ };
6
+ rbac?: unknown;
7
+ };
8
+ export declare function resolveConfigRbac(config?: ConfigWithRbac): RbacScopeItems | undefined;
9
+ export {};
10
+ //# sourceMappingURL=resolve-config-rbac.d.ts.map
@@ -0,0 +1 @@
1
+ import{isRbacScopeItems as e}from"../../../utils/rbac/is-rbac-scope-items.js";function a(r){if(e(r?.access?.rbac))return r.access.rbac;if(e(r?.rbac))return r.rbac}export{a as resolveConfigRbac};
@@ -0,0 +1,2 @@
1
+ export declare function toRelativeSlug(absoluteSlug: string, baseSlug: string): string;
2
+ //# sourceMappingURL=to-relative-slug.d.ts.map
@@ -0,0 +1 @@
1
+ function i(r,t){return t?r===t?"":r.startsWith(`${t}/`)?r.slice(t.length+1):r:r}export{i as toRelativeSlug};
@@ -1 +1 @@
1
- import{join as c}from"path";import{transformSync as l}from"esbuild";import{REDOCLY_ROUTE_RBAC as p}from"@redocly/config";import{removeTrailingSlash as d}from"../../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as m}from"../../../utils/url/remove-leading-slash.js";import{logger as u}from"../../tools/notifiers/logger.js";import{envConfig as g}from"../../config/env-config.js";import{USER_DEFINED_API_FUNCTIONS_COUNTER_KEY as h}from"../../../server/store.js";import{parseRouteFsPathForHono as F}from"./helpers/parse-route-fs-path-for-hono.js";import{telemetryTraceStep as A}from"../../../cli/telemetry/helpers/trace-step.js";const f="api-functions",P=/\bexport\s+default\b|\bexport\s*\{[^}]*\b(?:default\s*[,}]|\w+\s+as\s+default\b)/;async function E(t,o){let i;try{i=await o.fs.read(t),l(i,{loader:t.endsWith(".js")?"js":"ts"})}catch(e){const a=e instanceof Error?e.message:String(e);return u.warn(`Skipping API function ${t} because it cannot be parsed: ${a}`),!1}if(!P.test(i)){const e=`API function ${t} does not export a default function. Add 'export default function (request, context) { ... }' to define an API function.`;return g.isDevelopMode?(u.warn(e),!0):(u.warn(`Skipping ${e}`),!1)}return!0}function R(t){return m(d(t))}function I(t){return`^${R(t)}`}function _(t){const o=t.map(I);return o.push(".*@api"),new RegExp(`(${o.join("|")})/.*.(ts|js)$`)}async function H(){return{id:"ApiFunctions",requiredEntitlements:["apiFunctions"],async processContent(t,o){await A("build.plugin.api_functions",async i=>{const e=await o.getConfig();i?.setAttribute("config",JSON.stringify(e.apiFunctions||{}));const a=_(e.apiFunctions?.folders||[]),s=[];for(const n of o.fs.scan(a)){if(n.isVirtual)continue;const r=F(n.relativePath);r&&await E(n.relativePath,o)&&s.push({requestHandlerId:`${f}:${r.handler}`,fullPath:c(t.contentDir,r.handler),slug:r.path,httpMethod:r.method,fsPath:n.relativePath})}t.clearRequestHandlersByPrefix(`${f}:`);for(const n of s)t.createRequestHandler(n.requestHandlerId,n.fullPath),t.addApiRoute({requestHandlerId:n.requestHandlerId,slug:n.slug,fsPath:n.fsPath,httpMethod:n.httpMethod,[p]:{fsPath:n.fsPath,slug:n.slug}});i?.setAttribute("definedApiFunctions",String(s.length)),t.setGlobalConfig({[h]:s.length})})}}}export{f as API_FUNCTIONS_REQUEST_HANDLER_ID,H as apiFunctionsPlugin};
1
+ import{join as c}from"path";import{transformSync as l}from"esbuild";import{REDOCLY_ROUTE_RBAC as p}from"@redocly/config";import{removeTrailingSlash as d}from"../../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as m}from"../../../utils/url/remove-leading-slash.js";import{logger as u}from"../../tools/notifiers/logger.js";import{envConfig as g}from"../../config/env-config.js";import{USER_DEFINED_API_FUNCTIONS_COUNTER_KEY as h}from"../../../server/store.js";import{parseRouteFsPathForHono as F}from"./helpers/parse-route-fs-path-for-hono.js";import{telemetryTraceStep as A}from"../../../cli/telemetry/helpers/trace-step.js";const f="api-functions",P=/\bexport\s+default\b|\bexport\s*\{[^}]*\b(?:default\s*[,}]|\w+\s+as\s+default\b)/;async function E(t,o){let r;try{r=await o.fs.read(t),l(r,{loader:t.endsWith(".js")?"js":"ts"})}catch(e){const a=e instanceof Error?e.message:String(e);return u.warn(`Skipping API function ${t} because it cannot be parsed: ${a}`),!1}if(!P.test(r)){const e=`API function ${t} does not export a default function. Add 'export default function (request, context) { ... }' to define an API function.`;return g.isDevelopMode?(u.warn(e),!0):(u.warn(`Skipping ${e}`),!1)}return!0}function R(t){return m(d(t))}function I(t){return`^${R(t)}`}function b(t){const o=t.map(I);return o.push(".*@api"),new RegExp(`(${o.join("|")})/.*.(ts|js)$`)}async function H(){return{id:"ApiFunctions",requiredEntitlements:["apiFunctions"],async processContent(t,o){await A("com.redocly.build.plugin.apiFunctions",async r=>{const e=await o.getConfig();r?.setAttribute("config",JSON.stringify(e.apiFunctions||{}));const a=b(e.apiFunctions?.folders||[]),s=[];for(const n of o.fs.scan(a)){if(n.isVirtual)continue;const i=F(n.relativePath);i&&await E(n.relativePath,o)&&s.push({requestHandlerId:`${f}:${i.handler}`,fullPath:c(t.contentDir,i.handler),slug:i.path,httpMethod:i.method,fsPath:n.relativePath})}t.clearRequestHandlersByPrefix(`${f}:`);for(const n of s)t.createRequestHandler(n.requestHandlerId,n.fullPath),t.addApiRoute({requestHandlerId:n.requestHandlerId,slug:n.slug,fsPath:n.fsPath,httpMethod:n.httpMethod,[p]:{fsPath:n.fsPath,slug:n.slug}});r?.setAttribute("definedApiFunctions",String(s.length)),t.setGlobalConfig({[h]:s.length})})}}}export{f as API_FUNCTIONS_REQUEST_HANDLER_ID,H as apiFunctionsPlugin};
@@ -1 +1 @@
1
- import{simplifyAstStructure as h}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{storeDefinitionBundles as p}from"./store-definition-bundles.js";import{arazzoDocLoader as y,arazzoDocsLoader as P}from"./arazzo-doc-loader.js";import{telemetryTraceStep as k}from"../../../cli/telemetry/helpers/trace-step.js";const u="arazzo-docs-";async function $(w){let l=[];return{id:"arazzo",loaders:{"arazzo-doc":y,"arazzo-docs":P},processContent:async(e,o)=>{await k("build.plugin.arazzo_docs",async()=>{for(const t of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(t.relativePath))try{const{data:a,compoundHash:c}=await o.cache.load(t.realRelativePath,"arazzo-doc");if(!a?.length)continue;l=a.map(({markdocChunks:r,relativePath:n,isVirtual:i,customOutputRelativeFile:s,realRelativePath:d})=>({chunks:r,relativePath:n,realRelativePath:d,isVirtual:s!=null||t.isVirtual||i})),p(a,e.outdir,c);for(const r of a){const n=`${u}${r.relativePath}`;await e.createSharedData(n,{document:r.document})}}catch(a){console.error(a)}})},afterRoutesCreated:async(e,o)=>{for(const{chunks:t,relativePath:a,isVirtual:c,realRelativePath:r}of l)await o.cache.load(a,{loader:async function(){await o.cache.load(r,"arazzo-doc");for(const{node:i,markdown:s,pointer:d,key:z,relativePath:m}of t){const{ast:f}=await e.parseMarkdoc({input:{content:s,relativePath:d,isVirtual:c},context:o,deps:{sharedDataIds:[`${u}${m}`]}});i[`x-parsed-md-${z}`]={result:h(f)}}},name:"arazzo-markdoc-inline-parser"})}}}export{$ as arazzoDocsPlugin};
1
+ import{simplifyAstStructure as h}from"@redocly/api-docs";import{storeDefinitionBundles as p}from"./store-definition-bundles.js";import{arazzoDocLoader as y,arazzoDocsLoader as D}from"./arazzo-doc-loader.js";import{telemetryTraceStep as P}from"../../../cli/telemetry/helpers/trace-step.js";const u="arazzo-docs-";async function $(k){let l=[];return{id:"arazzo",loaders:{"arazzo-doc":y,"arazzo-docs":D},processContent:async(e,o)=>{await P("com.redocly.build.plugin.arazzoDocs",async()=>{for(const t of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(t.relativePath))try{const{data:a,compoundHash:n}=await o.cache.load(t.realRelativePath,"arazzo-doc");if(!a?.length)continue;l=a.map(({markdocChunks:r,relativePath:c,isVirtual:i,customOutputRelativeFile:s,realRelativePath:d})=>({chunks:r,relativePath:c,realRelativePath:d,isVirtual:s!=null||t.isVirtual||i})),p(a,e.outdir,n);for(const r of a){const c=`${u}${r.relativePath}`;await e.createSharedData(c,{document:r.document})}}catch(a){console.error(a)}})},afterRoutesCreated:async(e,o)=>{for(const{chunks:t,relativePath:a,isVirtual:n,realRelativePath:r}of l)await o.cache.load(a,{loader:async function(){await o.cache.load(r,"arazzo-doc");for(const{node:i,markdown:s,pointer:d,key:z,relativePath:m}of t){const{ast:f}=await e.parseMarkdoc({input:{content:s,relativePath:d,isVirtual:n},context:o,deps:{sharedDataIds:[`${u}${m}`]}});i[`x-parsed-md-${z}`]={result:h(f)}}},name:"arazzo-markdoc-inline-parser"})}}}export{$ as arazzoDocsPlugin};
@@ -1 +1 @@
1
- import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as R}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getRouteSlugsForPath as F}from"../utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as N,asyncapiDocsLoader as j}from"./asyncapi-doc-loader.js";import{searchResolver as L}from"./search/search-resolver.js";import{getAiDocumentsStore as G}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as M}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function ot(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":N,"asyncapi-docs":j},processContent:async(e,o)=>{await M("build.plugin.asyncapi_docs",async()=>{if((await o.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,b("../../../client/templates/asyncapi-docs/template.js")),g=e.registerServerPropsGetter(v,b("./get-server-props.js"));for(const l of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(l.relativePath))try{const{data:r,compoundHash:w}=await o.cache.load(l.realRelativePath,"asyncapi-doc");if(!r?.length)continue;p=r.map(({markdocChunks:t,relativePath:s,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:s,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(r,e.outdir,w);for(const t of r){const s=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(R,`${C(t.relativePath,".json")}?download`)},{url:D(R,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(s,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(i=>{const n={fsPath:t.relativePath,slugSuffix:`/${i.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:s}],getStaticData:S(o.withPathPrefix,i.label),serverPropsGetterIds:[g]};e.addRoute(n),i.items&&i.items.forEach(a=>{e.addRoute({...n,slugSuffix:`/${a.link}`,getStaticData:S(o.withPathPrefix,a.label)}),a.items&&a.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(o.withPathPrefix,a.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:i=>{const n=a=>{const h={...a};return a.link&&(h.routeSlug=D(i.slug,a.link),h.link=D(i.slug,a.link)),a.items&&(h.items=a.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:i.slug,link:i.slug},...f.map(n)]},getSearchDocuments:L(e,t.document),getStaticData:S(o.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:G({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:s}]})}}catch(r){console.error(r)}})},afterRoutesCreated:async(e,o)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:r}of p){const w=F(e.getAllRoutes(),g),t=(await o.cache.load(r,"asyncapi-doc")).compoundHash;await o.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:i}of c){const{ast:n}=await e.parseMarkdoc({input:{content:f,relativePath:y,isVirtual:l},context:o,deps:{sharedDataIds:[`${_}${i}`],routeSlugs:w}});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:s}of c)P.add(s)}const k=u.difference(P);for(const c of k)o.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{ot as asyncAPIDocsPlugin};
1
+ import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as R}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getRouteSlugsForPath as F}from"../utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as N,asyncapiDocsLoader as j}from"./asyncapi-doc-loader.js";import{searchResolver as L}from"./search/search-resolver.js";import{getAiDocumentsStore as G}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as M}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function ot(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":N,"asyncapi-docs":j},processContent:async(e,o)=>{await M("com.redocly.build.plugin.asyncapiDocs",async()=>{if((await o.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,b("../../../client/templates/asyncapi-docs/template.js")),g=e.registerServerPropsGetter(v,b("./get-server-props.js"));for(const l of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(l.relativePath))try{const{data:r,compoundHash:w}=await o.cache.load(l.realRelativePath,"asyncapi-doc");if(!r?.length)continue;p=r.map(({markdocChunks:t,relativePath:s,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:s,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(r,e.outdir,w);for(const t of r){const s=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(R,`${C(t.relativePath,".json")}?download`)},{url:D(R,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(s,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(i=>{const n={fsPath:t.relativePath,slugSuffix:`/${i.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:s}],getStaticData:S(o.withPathPrefix,i.label),serverPropsGetterIds:[g]};e.addRoute(n),i.items&&i.items.forEach(a=>{e.addRoute({...n,slugSuffix:`/${a.link}`,getStaticData:S(o.withPathPrefix,a.label)}),a.items&&a.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(o.withPathPrefix,a.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:i=>{const n=a=>{const h={...a};return a.link&&(h.routeSlug=D(i.slug,a.link),h.link=D(i.slug,a.link)),a.items&&(h.items=a.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:i.slug,link:i.slug},...f.map(n)]},getSearchDocuments:L(e,t.document),getStaticData:S(o.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:G({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:s}]})}}catch(r){console.error(r)}})},afterRoutesCreated:async(e,o)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:r}of p){const w=F(e.getAllRoutes(),g),t=(await o.cache.load(r,"asyncapi-doc")).compoundHash;await o.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:i}of c){const{ast:n}=await e.parseMarkdoc({input:{content:f,relativePath:y,isVirtual:l},context:o,deps:{sharedDataIds:[`${_}${i}`],routeSlugs:w}});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:s}of c)P.add(s)}const k=u.difference(P);for(const c of k)o.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{ot as asyncAPIDocsPlugin};
@@ -1 +1 @@
1
- import{isTruthy as n}from"../../../utils/guards/is-truthy.js";import{normalizeRouteSlug as g}from"../../../utils/path/normalize-route-slug.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";async function d(){return{id:"CatalogClassic",requiredEntitlements:["catalogClassic"],async processContent(a,{getConfig:l}){await u("build.plugin.catalog_classic",async o=>{const c=a.createTemplate("catalogClassic","@redocly/theme/components/CatalogClassic/CatalogClassic"),e=await l(),i=e.catalogClassic??{};o?.setAttribute("config",JSON.stringify(e.catalogClassic));for(const[r,t]of Object.entries(i)){const s=g(t.slug);a.addRoute({duplicateInAllLocales:!0,slug:s,fsPath:s,templateId:c,excludeFromSidebar:!0,serverPropsGetterIds:[],getNavText:()=>Promise.resolve(t.title||"API Catalog"),getStaticData:async()=>({props:{catalogId:r,catalogConfig:{...t,filters:t.filters?.filter(n),items:void 0},seo:{title:t.title||"API Catalog"}}})})}})}}}export{d as catalogClassicPlugin};
1
+ import{isTruthy as n}from"../../../utils/guards/is-truthy.js";import{normalizeRouteSlug as g}from"../../../utils/path/normalize-route-slug.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";async function f(){return{id:"CatalogClassic",requiredEntitlements:["catalogClassic"],async processContent(a,{getConfig:o}){await u("com.redocly.build.plugin.catalogClassic",async s=>{const c=a.createTemplate("catalogClassic","@redocly/theme/components/CatalogClassic/CatalogClassic"),e=await o(),i=e.catalogClassic??{};s?.setAttribute("config",JSON.stringify(e.catalogClassic));for(const[r,t]of Object.entries(i)){const l=g(t.slug);a.addRoute({duplicateInAllLocales:!0,slug:l,fsPath:l,templateId:c,excludeFromSidebar:!0,serverPropsGetterIds:[],getNavText:()=>Promise.resolve(t.title||"API Catalog"),getStaticData:async()=>({props:{catalogId:r,catalogConfig:{...t,filters:t.filters?.filter(n),items:void 0},seo:{title:t.title||"API Catalog"}}})})}})}}}export{f as catalogClassicPlugin};
@@ -1 +1 @@
1
- import u from"node:path";import{removeLeadingSlash as w}from"@redocly/theme/core/utils";import{toKebabCase as m}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as f}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as v}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as E}from"./base.js";const g=15;class S extends E{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t,o){const a=w(t.realRelativePath),l=t.document.info.title,e=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:t.document["x-redocly-catalog-key"]});return{type:this.type,key:e,title:l,summary:t.document.info.description?v(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a},version:o}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t,o,a,l){if(!this.#t(t))throw new Error("Arazzo description has no source descriptions");const e=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:{...i},revision:o,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:e,source:"file"}),l.delete(`${i.key}:${a}`),await this.#e(t,i.key,i.version,a,o,l,e);const h=t.document.sourceDescriptions||[];await f(h,g,async r=>{if(!(r.type!=="openapi"||!r.url))try{const s=this.resolveSourceDescriptionUrl(r.url,t.realRelativePath);if(!s){!r.url.startsWith("http://")&&!r.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${r.url}`);return}const c=await this.context.cache.load(s,"load-oas");if(!(c.data&&Array.isArray(c.data)&&c.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${s}`);return}const p=c.data[0],y=this.resolveEntityKey({realRelativePath:p.realRelativePath,customKey:p.definition["x-redocly-catalog-key"]});await this.catalogEntitiesService.createEntityRelation({sourceKey:i.key,type:"relatesTo",targetKey:y,sourceFile:t.realRelativePath,fileHash:t.hash}),await this.#r(t,r.name,p,i.key,y,i.version,o)}catch(s){this.context.logger.warn(`Failed to create relation to OpenAPI source "${r.url}": ${s instanceof Error?s.message:"Unknown error"}`)}})}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,l,e,i,h)=>{try{const r=t.document.components?.inputs,s=r?Object.entries(r):[],c=[];for(const[n,p]of s)c.push(async()=>{const y=`${o}-${m(n)}`,d=await this.#a({schemaName:n,schema:p,description:t,parentKey:o,parentVersion:a,parentRevision:e,rbacTeams:h});i.delete(`${y}:${l}`),d&&await this.catalogEntitiesService.createEntityRelation({sourceKey:o,type:"uses",targetKey:d.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:e,targetRevision:e})});if(c.length===0)return;await f(c,g,n=>n())}catch(r){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${r instanceof Error?r.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:l,parentVersion:e,parentRevision:i,rbacTeams:h})=>{const r={type:"data-schema",key:`${l}-${m(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};try{return await this.catalogEntitiesService.createEntity({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:h,source:"file",revision:i})}catch(s){return this.context.logger.warn(`Failed to create data schema entity for ${t}: ${s instanceof Error?s.message:"Unknown error"}`),null}};#r=async(t,o,a,l,e,i,h)=>{const r=t.document.workflows||[];if(r.length===0)return;const s=new Set;for(const c of r)for(const n of c.steps||[]){if(!n.operationId)continue;const p=n.operationId.startsWith(`${o}.`)?n.operationId.substring(`${o}.`.length):n.operationId;p&&s.add(p)}s.size!==0&&await f(Array.from(s),g,async c=>{try{const n=`${e}-${m(c)}`;await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"uses",targetKey:n,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:i,targetVersion:i,sourceRevision:h,targetRevision:h})}catch(n){this.context.logger.warn(`Failed to create relation to operation "${c}": ${n instanceof Error?n.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),l=a.startsWith("@")?a.slice(1):a,[e]=l.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return w(u.posix.normalize(e));const i=u.posix.dirname(o);return e.startsWith(i+"/")?u.posix.normalize(e):u.posix.normalize(u.posix.join(i,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{S as ArazzoEntitiesExtractor};
1
+ import u from"node:path";import{removeLeadingSlash as w}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as g}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as v}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as E}from"./base.js";const d=15;class K extends E{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t,o){const a=w(t.realRelativePath),c=t.document.info.title,e=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:t.document["x-redocly-catalog-key"]});return{type:this.type,key:e,title:c,summary:t.document.info.description?v(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a},version:o}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t,o,a,c){if(!this.#t(t))throw new Error("Arazzo description has no source descriptions");const e=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:{...i},revision:o,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:e,source:"file"}),c.delete(`${i.key}:${a}`),await this.#e(t,i.key,i.version,a,o,c,e);const l=t.document.sourceDescriptions||[];await g(l,d,async r=>{if(!(r.type!=="openapi"||!r.url))try{const n=this.resolveSourceDescriptionUrl(r.url,t.realRelativePath);if(!n){!r.url.startsWith("http://")&&!r.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${r.url}`);return}const s=((await this.context.cache.load(n,"api-doc")).data??[]).filter(m=>m.type==="openapi");if(s.length===0){this.context.logger.warn(`No OpenAPI definition found at path: ${n}`);return}const p=s[0],y=this.resolveEntityKey({realRelativePath:p.realRelativePath,customKey:p.document["x-redocly-catalog-key"]});await this.catalogEntitiesService.createEntityRelation({sourceKey:i.key,type:"relatesTo",targetKey:y,sourceFile:t.realRelativePath,fileHash:t.hash}),await this.#r(t,r.name,p,i.key,y,i.version,o)}catch(n){this.context.logger.warn(`Failed to create relation to OpenAPI source "${r.url}": ${n instanceof Error?n.message:"Unknown error"}`)}})}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,c,e,i,l)=>{try{const r=t.document.components?.inputs,n=r?Object.entries(r):[],h=[];for(const[s,p]of n)h.push(async()=>{const y=`${o}-${f(s)}`,m=await this.#a({schemaName:s,schema:p,description:t,parentKey:o,parentVersion:a,parentRevision:e,rbacTeams:l});i.delete(`${y}:${c}`),m&&await this.catalogEntitiesService.createEntityRelation({sourceKey:o,type:"uses",targetKey:m.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:e,targetRevision:e})});if(h.length===0)return;await g(h,d,s=>s())}catch(r){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${r instanceof Error?r.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:c,parentVersion:e,parentRevision:i,rbacTeams:l})=>{const r={type:"data-schema",key:`${c}-${f(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};try{return await this.catalogEntitiesService.createEntity({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:l,source:"file",revision:i})}catch(n){return this.context.logger.warn(`Failed to create data schema entity for ${t}: ${n instanceof Error?n.message:"Unknown error"}`),null}};#r=async(t,o,a,c,e,i,l)=>{const r=t.document.workflows||[];if(r.length===0)return;const n=new Set;for(const h of r)for(const s of h.steps||[]){if(!s.operationId)continue;const p=s.operationId.startsWith(`${o}.`)?s.operationId.substring(`${o}.`.length):s.operationId;p&&n.add(p)}n.size!==0&&await g(Array.from(n),d,async h=>{try{const s=`${e}-${f(h)}`;await this.catalogEntitiesService.createEntityRelation({sourceKey:c,type:"uses",targetKey:s,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:i,targetVersion:i,sourceRevision:l,targetRevision:l})}catch(s){this.context.logger.warn(`Failed to create relation to operation "${h}": ${s instanceof Error?s.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),c=a.startsWith("@")?a.slice(1):a,[e]=c.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return w(u.posix.normalize(e));const i=u.posix.dirname(o);return e.startsWith(i+"/")?u.posix.normalize(e):u.posix.normalize(u.posix.join(i,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{K as ArazzoEntitiesExtractor};
@@ -1,14 +1,22 @@
1
- import type { BundledDefinition } from '../../../../asyncapi-docs/asyncapi-doc-loader';
1
+ import type { AsyncApiDefinitionReferenced } from '@redocly/api-docs';
2
+ import type { BundledApiDefinition } from '../../../../api-docs/loader.js';
2
3
  import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
3
4
  import type { EntityDtoSchema } from '../../../schemas/dto-schemas';
4
5
  import { BaseApiEntitiesExtractor } from './base.js';
5
6
  type Params = BaseApiEntitiesExtractorParams;
6
- export declare class AsyncApiEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
7
+ type AsyncApiCatalogBundle = Omit<BundledApiDefinition, 'document' | 'isVirtual'> & {
8
+ type: 'asyncapi';
9
+ document: AsyncApiDefinitionReferenced & {
10
+ 'x-redocly-catalog-key'?: string;
11
+ };
12
+ isVirtual: boolean;
13
+ };
14
+ export declare class AsyncApiEntitiesExtractor extends BaseApiEntitiesExtractor<AsyncApiCatalogBundle> {
7
15
  #private;
8
16
  constructor(params: Params);
9
- mapApiDescriptionToEntity(description: BundledDefinition, version: string): EntityDtoSchema;
10
- loadApiDescriptions(): Promise<BundledDefinition[]>;
11
- processApiDescription(description: BundledDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
17
+ loadApiDescriptions(): Promise<AsyncApiCatalogBundle[]>;
18
+ mapApiDescriptionToEntity(description: AsyncApiCatalogBundle, version: string): EntityDtoSchema;
19
+ processApiDescription(description: AsyncApiCatalogBundle, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
12
20
  }
13
21
  export {};
14
22
  //# sourceMappingURL=asyncapi-entities-extractor.d.ts.map
@@ -1 +1 @@
1
- import{removeLeadingSlash as d}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as E}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{extractPartsFromChannelsMessageRef as S}from"../../../utils/extract-parts-from-channels-message-ref.js";const u=15;class T extends w{constructor(e){super("asyncapi",e)}mapApiDescriptionToEntity(e,t){const a=d(e.realRelativePath),r=e.document.info.title,s=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:s,title:r,summary:E(e.document.info.description),tags:e.document.info.tags?.map(n=>n.name),metadata:{specType:this.specType,descriptionFile:a},version:t}}async loadApiDescriptions(){return(await this.context.cache.load(".","asyncapi-docs")).data}async processApiDescription(e,t,a,r){const s=this.getRbacTeamsForDefinition(e.relativePath),n=this.mapApiDescriptionToEntity(e,a);await this.catalogEntitiesService.createEntity({entity:n,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,rbacTeams:s,source:"file"}),r.delete(`${n.key}:${a}`);const o=this.#a(e),[c,i]=await Promise.allSettled([this.#s(e,n.key,n.version,a,t,r,s),this.#n(o,e,n.key,n.version,a,t,r,s)]);c.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",c.reason),i.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",i.reason)}#a=e=>{const t=e.documentWithReferences.operations;return t?Object.entries(t).map(([a,r])=>({operationName:a,operation:r})):[]};#s=async(e,t,a,r,s,n,o)=>{const c=e.document.components?.schemas;if(!c)return;const i=Object.entries(c);if(i.length===0)return;const l=await $(i,u,async([h,m])=>{const R=`${t}-${f(h)}`,g=await this.#r({schemaName:h,schema:m,description:e,parentKey:t,parentVersion:a,parentRevision:s,rbacTeams:o});n.delete(`${R}:${r}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:g.key,sourceFile:e.realRelativePath,fileHash:e.hash,sourceVersion:a,targetVersion:a,sourceRevision:s,targetRevision:s})},this.context.logger);l.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${l.count.failed} failures out of ${i.length} schemas for ${e.realRelativePath}`)};#r=async({schemaName:e,schema:t,description:a,parentKey:r,parentVersion:s,parentRevision:n,rbacTeams:o})=>{const c=`${r}-${f(e)}`,i="title"in t?t.title??t.description:null,l=JSON.stringify(t),h={type:"data-schema",key:c,title:e,summary:i,tags:[],metadata:{specType:this.specType,schema:l},version:s};try{return await this.catalogEntitiesService.createEntity({entity:h,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:o,source:"file",revision:n})}catch(m){return this.context.logger.warn(`Failed to create data schema entity for ${e}: ${m instanceof Error?m.message:"Unknown error"}`),null}};#n=async(e,t,a,r,s,n,o,c)=>{if(!e.length)return;const i=await $(e,u,async({operationName:l,operation:h})=>{const m=await this.#o(h,l,t,a,r,n,c);o.delete(`${m}:${s}`)},this.context.logger);i.count.failed>0&&this.context.logger.warn(`Operation processing completed with ${i.count.failed} failures out of ${e.length} operations for ${t.realRelativePath}`)};#o=async(e,t,a,r,s,n,o)=>{const c=`${r}-${f(t)}`,i=await this.#c(e.messages??[],a,r),l=await this.#i(t,e,i,a,r,s,n,o);return l&&await this.#l({apiOperationKey:l.key,operation:e,descriptionUniqueKey:r,description:a,descriptionVersion:s,parentRevision:n}),c};#c=async(e,t,a)=>{if(!e||e.length===0)return[];const r=new Set;for(const s of e){let n=null;if("$ref"in s){const o=s.$ref.startsWith("#/channels/")?this.#e(s.$ref,t):s.$ref;if(o){const c=y(o);if(c?.componentName&&c.componentType==="messages"){const i=t.documentWithReferences.components?.messages[c.componentName];i?.payload&&"$ref"in i.payload&&i.payload.$ref&&(n=i.payload.$ref)}}}else s.payload&&"$ref"in s.payload&&s.payload.$ref&&(n=s.payload.$ref);if(n){const o=y(n);o?.componentName&&o.componentType==="schemas"&&r.add(`${a}-${f(o.componentName)}`)}}return Array.from(r)};#i=async(e,t,a,r,s,n,o,c)=>{const i={type:"api-operation",key:`${s}-${f(e)}`,title:t.title||e,summary:t.summary??"",tags:t.tags?.map(l=>l.name)??[],metadata:{method:t.action==="send"?"PUBLISH":"SUBSCRIBE",path:t.channel.address??"",payload:t.action==="receive"?a:[],responses:t.action==="send"?a:[]},version:n};try{return await this.catalogEntitiesService.createEntity({entity:i,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:c,source:"file",revision:o})}catch(l){return this.context.logger.warn(`Failed to create API operation entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}};#l=async({apiOperationKey:e,operation:t,descriptionUniqueKey:a,description:r,descriptionVersion:s,parentRevision:n})=>(await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:a,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),await this.#h(t,e,r,s,n),!Array.isArray(t.messages)||!t.messages?.length?[]:await this.#m(t.messages,e,r,a,s,n));#h=async(e,t,a,r,s)=>{e["x-catalogRelations"]?.length&&await p(e["x-catalogRelations"],u,async n=>{try{this.validateEntityRelationFileSchema(n),await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:n.type,targetKey:n.key,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:r,targetVersion:"",sourceRevision:s,targetRevision:""})}catch(o){this.context.logger.warn(`Error creating entity relation for operation ${t} based on custom property: ${o instanceof Error?o.message:"Unknown error"}`)}})};#m=async(e,t,a,r,s,n)=>e.length===0?[]:(await p(e,u,async c=>await this.#f(c,t,a,r,s,n)??"")).filter(c=>!!c);#f=async(e,t,a,r,s,n)=>"$ref"in e?this.#y(e,t,a,r,s,n):e.payload?this.#u(e,t,a,r,s,n):null;#y=async(e,t,a,r,s,n)=>{const o=e.$ref.startsWith("#/channels/")?this.#e(e.$ref,a):e.$ref;if(!o)return null;const c=y(o);if(!c||!c.componentName||c.componentType!=="messages")return null;const i=a.documentWithReferences.components?.messages[c.componentName];return!i?.payload||!("$ref"in i.payload)||!i.payload.$ref?null:this.#t(i.payload.$ref,t,a,r,s,n)};#e=(e,t)=>{const a=S(e);if(!a||!a.channelName||!a.messageName)return null;const r=t.documentWithReferences.channels?.[a.channelName];if(!r?.messages)return null;const s=r.messages[a.messageName];return!s||!("$ref"in s)||typeof s.$ref!="string"||!s.$ref.startsWith("#/components/messages/")?null:s.$ref};#u=async(e,t,a,r,s,n)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#t(e.payload.$ref,t,a,r,s,n);#t=async(e,t,a,r,s,n)=>{const o=y(e);if(!o||!o.componentName||o.componentType!=="schemas")return null;const c=`${r}-${f(o.componentName)}`;return await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:c,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),c}}export{T as AsyncApiEntitiesExtractor};
1
+ import{removeLeadingSlash as d}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as E}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{extractPartsFromChannelsMessageRef as S}from"../../../utils/extract-parts-from-channels-message-ref.js";const u=15;class T extends w{constructor(e){super("asyncapi",e)}async loadApiDescriptions(){return(await this.actions.loadApiDocuments(this.context)).filter(t=>t.type==="asyncapi").map(t=>({...t,isVirtual:t.isVirtual??!1}))}mapApiDescriptionToEntity(e,t){const a=d(e.realRelativePath),r=e.document.info.title,s=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:s,title:r,summary:E(typeof e.document.info.description=="string"?e.document.info.description:void 0),tags:e.document.info.tags?.map(n=>n.name),metadata:{specType:this.specType,descriptionFile:a},version:t}}async processApiDescription(e,t,a,r){const s=this.getRbacTeamsForDefinition(e.relativePath),n=this.mapApiDescriptionToEntity(e,a);await this.catalogEntitiesService.createEntity({entity:n,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,rbacTeams:s,source:"file"}),r.delete(`${n.key}:${a}`);const o=this.#a(e),[i,c]=await Promise.allSettled([this.#s(e,n.key,n.version,a,t,r,s),this.#n(o,e,n.key,n.version,a,t,r,s)]);i.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",i.reason),c.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",c.reason)}#a=e=>{const t=e.document.operations;return t?Object.entries(t).map(([a,r])=>({operationName:a,operation:r})):[]};#s=async(e,t,a,r,s,n,o)=>{const i=e.document.components?.schemas;if(!i)return;const c=Object.entries(i);if(c.length===0)return;const l=await $(c,u,async([h,m])=>{const R=`${t}-${f(h)}`,g=await this.#r({schemaName:h,schema:m,description:e,parentKey:t,parentVersion:a,parentRevision:s,rbacTeams:o});n.delete(`${R}:${r}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:g.key,sourceFile:e.realRelativePath,fileHash:e.hash,sourceVersion:a,targetVersion:a,sourceRevision:s,targetRevision:s})},this.context.logger);l.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${l.count.failed} failures out of ${c.length} schemas for ${e.realRelativePath}`)};#r=async({schemaName:e,schema:t,description:a,parentKey:r,parentVersion:s,parentRevision:n,rbacTeams:o})=>{const i=`${r}-${f(e)}`,c="title"in t?t.title??t.description:null,l=JSON.stringify(t),h={type:"data-schema",key:i,title:e,summary:c,tags:[],metadata:{specType:this.specType,schema:l},version:s};try{return await this.catalogEntitiesService.createEntity({entity:h,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:o,source:"file",revision:n})}catch(m){return this.context.logger.warn(`Failed to create data schema entity for ${e}: ${m instanceof Error?m.message:"Unknown error"}`),null}};#n=async(e,t,a,r,s,n,o,i)=>{if(!e.length)return;const c=await $(e,u,async({operationName:l,operation:h})=>{const m=await this.#o(h,l,t,a,r,n,i);o.delete(`${m}:${s}`)},this.context.logger);c.count.failed>0&&this.context.logger.warn(`Operation processing completed with ${c.count.failed} failures out of ${e.length} operations for ${t.realRelativePath}`)};#o=async(e,t,a,r,s,n,o)=>{const i=`${r}-${f(t)}`,c=await this.#i(e.messages??[],a,r),l=await this.#c(t,e,c,a,r,s,n,o);return l&&await this.#l({apiOperationKey:l.key,operation:e,descriptionUniqueKey:r,description:a,descriptionVersion:s,parentRevision:n}),i};#i=async(e,t,a)=>{if(!e||e.length===0)return[];const r=new Set;for(const s of e){let n=null;if("$ref"in s){const o=s.$ref.startsWith("#/channels/")?this.#e(s.$ref,t):s.$ref;if(o){const i=y(o);if(i?.componentName&&i.componentType==="messages"){const c=t.document.components?.messages[i.componentName];c?.payload&&"$ref"in c.payload&&c.payload.$ref&&(n=c.payload.$ref)}}}else s.payload&&"$ref"in s.payload&&s.payload.$ref&&(n=s.payload.$ref);if(n){const o=y(n);o?.componentName&&o.componentType==="schemas"&&r.add(`${a}-${f(o.componentName)}`)}}return Array.from(r)};#c=async(e,t,a,r,s,n,o,i)=>{const c={type:"api-operation",key:`${s}-${f(e)}`,title:t.title||e,summary:t.summary??"",tags:t.tags?.map(l=>l.name)??[],metadata:{method:t.action==="send"?"PUBLISH":"SUBSCRIBE",path:t.channel.address??"",payload:t.action==="receive"?a:[],responses:t.action==="send"?a:[]},version:n};try{return await this.catalogEntitiesService.createEntity({entity:c,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:i,source:"file",revision:o})}catch(l){return this.context.logger.warn(`Failed to create API operation entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}};#l=async({apiOperationKey:e,operation:t,descriptionUniqueKey:a,description:r,descriptionVersion:s,parentRevision:n})=>(await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:a,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),await this.#h(t,e,r,s,n),!Array.isArray(t.messages)||!t.messages?.length?[]:await this.#m(t.messages,e,r,a,s,n));#h=async(e,t,a,r,s)=>{e["x-catalogRelations"]?.length&&await p(e["x-catalogRelations"],u,async n=>{try{this.validateEntityRelationFileSchema(n),await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:n.type,targetKey:n.key,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:r,targetVersion:"",sourceRevision:s,targetRevision:""})}catch(o){this.context.logger.warn(`Error creating entity relation for operation ${t} based on custom property: ${o instanceof Error?o.message:"Unknown error"}`)}})};#m=async(e,t,a,r,s,n)=>e.length===0?[]:(await p(e,u,async i=>await this.#f(i,t,a,r,s,n)??"")).filter(i=>!!i);#f=async(e,t,a,r,s,n)=>"$ref"in e?this.#y(e,t,a,r,s,n):e.payload?this.#u(e,t,a,r,s,n):null;#y=async(e,t,a,r,s,n)=>{const o=e.$ref.startsWith("#/channels/")?this.#e(e.$ref,a):e.$ref;if(!o)return null;const i=y(o);if(!i||!i.componentName||i.componentType!=="messages")return null;const c=a.document.components?.messages[i.componentName];return!c?.payload||!("$ref"in c.payload)||!c.payload.$ref?null:this.#t(c.payload.$ref,t,a,r,s,n)};#e=(e,t)=>{const a=S(e);if(!a||!a.channelName||!a.messageName)return null;const r=t.document.channels?.[a.channelName];if(!r?.messages)return null;const s=r.messages[a.messageName];return!s||!("$ref"in s)||typeof s.$ref!="string"||!s.$ref.startsWith("#/components/messages/")?null:s.$ref};#u=async(e,t,a,r,s,n)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#t(e.payload.$ref,t,a,r,s,n);#t=async(e,t,a,r,s,n)=>{const o=y(e);if(!o||!o.componentName||o.componentType!=="schemas")return null;const i=`${r}-${f(o.componentName)}`;return await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:i,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),i}}export{T as AsyncApiEntitiesExtractor};
@@ -1 +1 @@
1
- import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{sha1 as S}from"../../../../../utils/crypto/sha1.js";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as D}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as F}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as H}from"../../../utils/ajv-validator.js";const O=15,C=200,k=500;class Y{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}getDescriptionHash(t){return t.definition===void 0?t.hash:S(JSON.stringify(t.definition))}async extract(){const t=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const a=this.#s(t),i={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},o=[],r=new Set;await w(Array.from(a.values()),O,async c=>{for(const{description:s,version:l}of c)try{const n=this.getDescriptionHash(s);if(!n)continue;r.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),y=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:y});if(!(f!==null)){i.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&i[f]++,f==="fileHashMismatch"&&h&&o.length<3&&o.push({path:s.realRelativePath,stored:h.hash,incoming:n});const d=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(s.realRelativePath);await this.#a(d);const E=new Date().toISOString();await this.processApiDescription(s,E,l,d),(m||y||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#r(d,s.realRelativePath,E,n),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.OUTDATED),p.markFileHashPendingConfirmation({fileType:this.fileType,filePath:s.realRelativePath,hash:n})}catch(n){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${s.realRelativePath}`),this.context.logger.warn(n)}}),await this.#o(r)}#i({fileHashChanged:t,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return t?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async t=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(t).map(e=>e.split(":")[0])}),t.clear())};#t=async t=>{let e=0,a=0;for(;;){const i=await this.catalogEntitiesService.getEntities({paginationParams:{limit:k,filter:t}});if(!i||i.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:i.items.map(({id:o})=>o)}),e+=i.items.length,a+=1}return{total:e,pages:a}};#s(t){const e=new Map;for(const a of t)if(!(a.isVirtual||!a.hash))try{const i=this.#n(a),o=this.mapApiDescriptionToEntity(a,i),r=e.get(o.key)??[];r.push({description:a,version:i}),e.set(o.key,r)}catch(i){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(i)}return e}#o=async t=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!t.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const i=a.map(({filePath:l})=>l),{total:o,pages:r}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:i},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:i});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${i.length} currentRevisionsDeleted=${o} currentPages=${r} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${i.slice(0,3).join(", ")}${i.length>3?`, +${i.length-3} more`:""}`)};#r=async(t,e,a,i)=>{if(t.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const o=Array.from(t).map(r=>{const[c,s]=r.split(":");return{key:c,version:s}});for(let r=0;r<o.length;r+=C){const c=o.slice(r,r+C),s=Array.from(new Set(c.map(({key:n})=>n))),l=c.map(({key:n,version:h})=>({op:A.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:h}]}));await this.catalogEntitiesService.softDeleteEntitiesWithRelations({revision:a,fileHash:i,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:s},{op:A.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e},{field:"is_current",operator:"equal",value:!0}]}})}};#n(t){const e=t.document?.info?.version??t.definition?.info?.version??null,a=F(e,t.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(t){H(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(t)}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(t);return D(a||{fsPath:t},e||{})}resolveEntityKey({realRelativePath:t,customKey:e,extensionPattern:a}){const i=this.#l(t,a);return typeof e=="string"&&e.trim()?R(e.trim()):i}#l(t,e){let i=_(t);for(;/^@[^/]+\//.test(i);)i=i.replace(/^@[^/]+\//,"");i=i.replace(/\/@[^/]+/g,"");const o=e?i.replace(e,""):i.replace(/\.[^.]+$/,"");return R(o.replace(/[\\/]/g,"-"))}}export{Y as BaseApiEntitiesExtractor};
1
+ import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{sha1 as S}from"../../../../../utils/crypto/sha1.js";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as D}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as F}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as H}from"../../../utils/ajv-validator.js";const O=15,C=200,k=500;class Y{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}getDescriptionHash(t){return t.definition===void 0?t.hash:S(JSON.stringify(t.definition))}async extract(){const t=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const a=this.#s(t),i={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},r=[],o=new Set;await w(Array.from(a.values()),O,async c=>{for(const{description:s,version:l}of c)try{const n=this.getDescriptionHash(s);if(!n)continue;o.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),y=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:y});if(!(f!==null)){i.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&i[f]++,f==="fileHashMismatch"&&h&&r.length<3&&r.push({path:s.realRelativePath,stored:h.hash,incoming:n});const d=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(s.realRelativePath);await this.#a(d);const E=new Date().toISOString();await this.processApiDescription(s,E,l,d),(m||y||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#o(d,s.realRelativePath,E,n),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.OUTDATED),p.markFileHashPendingConfirmation({fileType:this.fileType,filePath:s.realRelativePath,hash:n})}catch(n){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${s.realRelativePath}`),this.context.logger.warn(n)}}),await this.#r(o)}#i({fileHashChanged:t,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return t?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async t=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(t).map(e=>e.split(":")[0])}),t.clear())};#t=async t=>{let e=0,a=0;for(;;){const i=await this.catalogEntitiesService.getEntities({paginationParams:{limit:k,filter:t}});if(!i||i.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:i.items.map(({id:r})=>r)}),e+=i.items.length,a+=1}return{total:e,pages:a}};#s(t){const e=new Map;for(const a of t)if(!(a.isVirtual||!a.hash))try{const i=this.#n(a),r=this.mapApiDescriptionToEntity(a,i),o=e.get(r.key)??[];o.push({description:a,version:i}),e.set(r.key,o)}catch(i){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(i)}return e}#r=async t=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!t.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const i=a.map(({filePath:l})=>l),{total:r,pages:o}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:i},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:i});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${i.length} currentRevisionsDeleted=${r} currentPages=${o} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${i.slice(0,3).join(", ")}${i.length>3?`, +${i.length-3} more`:""}`)};#o=async(t,e,a,i)=>{if(t.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const r=Array.from(t).map(o=>{const[c,s]=o.split(":");return{key:c,version:s}});for(let o=0;o<r.length;o+=C){const c=r.slice(o,o+C),s=Array.from(new Set(c.map(({key:n})=>n))),l=c.map(({key:n,version:h})=>({op:A.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:h}]}));await this.catalogEntitiesService.softDeleteEntitiesWithRelations({revision:a,fileHash:i,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:s},{op:A.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e},{field:"is_current",operator:"equal",value:!0}]}})}};#n(t){const e=t.document?.info?.version??null,a=F(e,t.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(t){H(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(t)}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(t);return D(a||{fsPath:t},e||{})}resolveEntityKey({realRelativePath:t,customKey:e,extensionPattern:a}){const i=this.#l(t,a);return typeof e=="string"&&e.trim()?R(e.trim()):i}#l(t,e){let i=_(t);for(;/^@[^/]+\//.test(i);)i=i.replace(/^@[^/]+\//,"");i=i.replace(/\/@[^/]+/g,"");const r=e?i.replace(e,""):i.replace(/\.[^.]+$/,"");return R(r.replace(/[\\/]/g,"-"))}}export{Y as BaseApiEntitiesExtractor};
@@ -1,13 +1,14 @@
1
- import type { GraphQLSchema } from 'graphql';
2
- import type { FileInfo } from '../../../../../types';
1
+ import type { DocumentNode, GraphQLSchema } from 'graphql';
2
+ import type { BundledApiDefinition } from '../../../../api-docs/loader.js';
3
3
  import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
4
4
  import type { EntityDtoSchema } from '../../../schemas/dto-schemas.js';
5
5
  import { BaseApiEntitiesExtractor } from './base.js';
6
- type GraphqlBundledDefinition = Omit<Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'>, 'hash'> & {
7
- hash: string;
6
+ type GraphqlBundledDefinition = Omit<BundledApiDefinition, 'document' | 'isVirtual'> & {
7
+ type: 'graphql';
8
+ document: DocumentNode;
8
9
  schema: GraphQLSchema;
9
- content: string;
10
10
  metadata?: Record<string, unknown>;
11
+ isVirtual: boolean;
11
12
  };
12
13
  export declare class GraphqlEntitiesExtractor extends BaseApiEntitiesExtractor<GraphqlBundledDefinition> {
13
14
  #private;
@@ -1,3 +1,3 @@
1
- import{buildSchema as v,isObjectType as T,isScalarType as I,isEnumType as P,isInterfaceType as E,isUnionType as S,isInputObjectType as $,getNamedType as u,printType as F}from"graphql";import{removeLeadingSlash as A}from"@redocly/theme/core/utils";import{toKebabCase as d}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as k}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as R}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as j}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as D}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as L}from"./base.js";const O=15,b=15,C=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class U extends L{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:i,metadata:n}=a.data,s=v(i),r=j(i);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:r,schema:s,content:i,metadata:n})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t,e){const a=A(t.realRelativePath),i=t.relativePath.replace(/\.(gql|graphql)$/,""),n=this.#s(i.split("/").pop()||"GraphQL Schema"),s=this.#c(t.metadata?.tags),r=t.metadata?.["x-redocly-catalog-key"],h=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:typeof r=="string"?r:void 0,extensionPattern:/\.(gql|graphql)$/});return{type:this.type,key:h,title:n,summary:t.metadata?.description||null,tags:s.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,i){const{schema:n}=t;if(!n)throw new Error("GraphQL definition is missing a parsed schema");const s=this.getRbacTeamsForDefinition(t.relativePath),r=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:r,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:s,source:"file",revision:e}),i.delete(`${r.key}:${a}`),await Promise.all([this.#a(t,r.key,r.version,a,e,i,s),this.#f(t,r.key,r.version,a,e,i,s)])}#a=async(t,e,a,i,n,s,r)=>{const{schema:h}=t,c=h.getTypeMap(),l=this.#n(h),o=Object.entries(c).filter(([f])=>!f.startsWith("__")&&!C.has(f)&&!l.has(f));if(o.length===0)return;const p=await R(o,b,async([f,m])=>{const y=this.#e(f,e),g=await this.#l({typeName:f,type:m,description:t,parentKey:e,parentVersion:a,parentRevision:n,rbacTeams:r});s.delete(`${y}:${i}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"uses",targetKey:g.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:n,targetRevision:n})},this.#t);p.count.failed>0&&this.#t.warn(`Schema processing completed with ${p.count.failed} failures out of ${o.length} types for ${t.realRelativePath}`),await this.#p({description:t,descriptionUniqueKey:e,userTypes:o,parentRevision:n})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&k(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${d(t)}`;#r=t=>T(t)?"object":E(t)?"interface":S(t)?"union":P(t)?"enum":$(t)?"input":I(t)?"scalar":"unknown";#n=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const i=t.getMutationType();i&&e.add(i.name);const n=t.getSubscriptionType();return n&&e.add(n.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"QUERY",rootTypeName:a.name})}const i=t.getMutationType();if(i){const s=i.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"MUTATION",rootTypeName:i.name})}const n=t.getSubscriptionType();if(n){const s=n.getFields();for(const[r,h]of Object.entries(s))e.push({fieldName:r,field:h,operationType:"SUBSCRIBE",rootTypeName:n.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const r=u(s.type);r&&!r.name.startsWith("__")&&a.push(this.#e(r.name,e))}const i=[],n=u(t.type);return n&&!n.name.startsWith("__")&&i.push(this.#e(n.name,e)),{inputTypes:a,returnTypes:i}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:i,parentVersion:n,parentRevision:s,rbacTeams:r})=>{const h=this.#e(t,i),c=e.description??null,l=this.#r(e),o={type:"data-schema",key:h,title:t,summary:c,tags:["graphql"],metadata:{specType:this.specType,typeKind:l,sdl:this.#h(e,a.schema)},version:n};try{return await this.catalogEntitiesService.createEntity({entity:o,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:r,source:"file",revision:s})}catch(p){return this.#t.warn(`Failed to create data schema entity for ${t}: ${p instanceof Error?p.message:"Unknown error"}`),null}};#h=(t,e)=>{const a=new Set,i=[],n=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const l=c.name;if(l.startsWith("__")||n.has(l)||a.has(l))return;const o=e.getType(l);o&&(a.add(l),i.push(o))};for(s(t);i.length>0;){const c=i.pop();if(T(c)){for(const o of c.getInterfaces?.()??[])s(o);const l=c.getFields();for(const o of Object.values(l)){s(u(o.type));for(const p of o.args??[])s(u(p.type))}}else if(E(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}else if(S(c))for(const l of c.getTypes())s(l);else if($(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}}const r=[t.name,...[...a].filter(c=>c!==t.name)],h=[];for(const c of r){const l=e.getType(c);l&&h.push(F(l))}return h.join(`
1
+ import{buildASTSchema as v,isObjectType as T,isScalarType as I,isEnumType as P,isInterfaceType as S,isUnionType as E,isInputObjectType as $,getNamedType as u,printType as A}from"graphql";import{removeLeadingSlash as F}from"@redocly/theme/core/utils";import{toKebabCase as d}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as k}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as R}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as C}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as j}from"./base.js";import{getApiConfigByPath as D}from"../../../../get-api-config.js";const O=15,b=15,L=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class U extends j{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=await this.actions.loadApiDocuments(this.context),e=await this.context.getConfig(),a=[];for(const n of t)if(n.type==="graphql")try{const r=n.document,s=v(r),i=D(e.apis,n.relativePath);a.push({...n,document:r,schema:s,metadata:i?.metadata,isVirtual:n.isVirtual??!1})}catch(r){this.#t.warn(`Failed to load GraphQL schema from ${n.relativePath}: ${r instanceof Error?r.message:"Unknown error"}`)}return a}mapApiDescriptionToEntity(t,e){const a=F(t.realRelativePath),n=t.relativePath.replace(/\.(gql|graphql)$/,""),r=this.#s(n.split("/").pop()||"GraphQL Schema"),s=this.#c(t.metadata?.tags),i=t.metadata?.["x-redocly-catalog-key"],h=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:typeof i=="string"?i:void 0,extensionPattern:/\.(gql|graphql)$/});return{type:this.type,key:h,title:r,summary:t.metadata?.description||null,tags:s.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,n){const{schema:r}=t;if(!r)throw new Error("GraphQL definition is missing a parsed schema");const s=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:i,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:s,source:"file",revision:e}),n.delete(`${i.key}:${a}`),await Promise.all([this.#a(t,i.key,i.version,a,e,n,s),this.#f(t,i.key,i.version,a,e,n,s)])}#a=async(t,e,a,n,r,s,i)=>{const{schema:h}=t,c=h.getTypeMap(),l=this.#i(h),o=Object.entries(c).filter(([f])=>!f.startsWith("__")&&!L.has(f)&&!l.has(f));if(o.length===0)return;const p=await R(o,b,async([f,m])=>{const y=this.#e(f,e),g=await this.#l({typeName:f,type:m,description:t,parentKey:e,parentVersion:a,parentRevision:r,rbacTeams:i});s.delete(`${y}:${n}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"uses",targetKey:g.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:r,targetRevision:r})},this.#t);p.count.failed>0&&this.#t.warn(`Schema processing completed with ${p.count.failed} failures out of ${o.length} types for ${t.realRelativePath}`),await this.#p({description:t,descriptionUniqueKey:e,userTypes:o,parentRevision:r})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&k(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${d(t)}`;#r=t=>T(t)?"object":S(t)?"interface":E(t)?"union":P(t)?"enum":$(t)?"input":I(t)?"scalar":"unknown";#i=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const n=t.getMutationType();n&&e.add(n.name);const r=t.getSubscriptionType();return r&&e.add(r.name),e};#n(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"QUERY",rootTypeName:a.name})}const n=t.getMutationType();if(n){const s=n.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"MUTATION",rootTypeName:n.name})}const r=t.getSubscriptionType();if(r){const s=r.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"SUBSCRIBE",rootTypeName:r.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const i=u(s.type);i&&!i.name.startsWith("__")&&a.push(this.#e(i.name,e))}const n=[],r=u(t.type);return r&&!r.name.startsWith("__")&&n.push(this.#e(r.name,e)),{inputTypes:a,returnTypes:n}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:n,parentVersion:r,parentRevision:s,rbacTeams:i})=>{const h=this.#e(t,n),c=e.description??null,l=this.#r(e),o={type:"data-schema",key:h,title:t,summary:c,tags:["graphql"],metadata:{specType:this.specType,typeKind:l,sdl:this.#h(e,a.schema)},version:r};try{return await this.catalogEntitiesService.createEntity({entity:o,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:i,source:"file",revision:s})}catch(p){return this.#t.warn(`Failed to create data schema entity for ${t}: ${p instanceof Error?p.message:"Unknown error"}`),null}};#h=(t,e)=>{const a=new Set,n=[],r=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const l=c.name;if(l.startsWith("__")||r.has(l)||a.has(l))return;const o=e.getType(l);o&&(a.add(l),n.push(o))};for(s(t);n.length>0;){const c=n.pop();if(T(c)){for(const o of c.getInterfaces?.()??[])s(o);const l=c.getFields();for(const o of Object.values(l)){s(u(o.type));for(const p of o.args??[])s(u(p.type))}}else if(S(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}else if(E(c))for(const l of c.getTypes())s(l);else if($(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}}const i=[t.name,...[...a].filter(c=>c!==t.name)],h=[];for(const c of i){const l=e.getType(c);l&&h.push(A(l))}return h.join(`
2
2
 
3
- `)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:i})=>{const n=a.filter(([,s])=>T(s));n.length!==0&&await w(n,b,async([s,r])=>{const c=r.getInterfaces?.()??[];if(!c.length)return;const l=this.#e(s,e);await w([...c],5,async o=>{const p=this.#e(o.name,e);try{await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"implements",targetKey:p,sourceFile:t.realRelativePath,fileHash:t.hash,sourceRevision:i,targetRevision:i})}catch(f){this.#t.warn(`Failed to create 'implements' relation ${l} -> ${p}: ${f instanceof Error?f.message:"Unknown error"}`)}})})};#f=async(t,e,a,i,n,s,r)=>{const{schema:h}=t,c=this.#i(h);if(c.length===0)return;const o=(await R(c,O,async({fieldName:p,field:f,operationType:m,rootTypeName:y})=>{const g=await this.#y(p,f,m,y,t,e,a,n,r);s.delete(`${g}:${i}`)},this.#t)).count.failed;o>0&&this.#t.warn(`Operation extraction completed with ${o} failures out of ${c.length} operations for ${e}`)};#y=async(t,e,a,i,n,s,r,h,c)=>{const l=`${s}-${d(`${a.toLowerCase()}-${t}`)}`,{inputTypes:o,returnTypes:p}=this.#o(e,s),f=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:o,returnTypes:p,description:n,descriptionUniqueKey:s,descriptionVersion:r,parentRevision:h,rbacTeams:c});return f&&await this.#m({apiOperationKey:f.key,inputTypes:o,returnTypes:p,descriptionUniqueKey:s,description:n,descriptionVersion:r,parentRevision:h}),l};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:n,returnTypes:s,description:r,descriptionUniqueKey:h,descriptionVersion:c,parentRevision:l,rbacTeams:o})=>{const p=t,m={type:"api-operation",key:`${h}-${d(`${a.toLowerCase()}-${t}`)}`,title:p,summary:e.description?D(e.description):null,tags:["graphql"],metadata:{method:a,path:`${i}.${t}`,payload:n,responses:s},version:c};try{return await this.catalogEntitiesService.createEntity({entity:m,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:o,source:"file",revision:l})}catch(y){return this.#t.warn(`Failed to create API operation entity for ${p}: ${y instanceof Error?y.message:"Unknown error"}`),null}};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:i,description:n,descriptionVersion:s,parentRevision:r})=>{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"partOf",targetKey:i,sourceFile:n.realRelativePath,fileHash:n.hash,sourceVersion:s,targetVersion:s,sourceRevision:r,targetRevision:r});const h=[...new Set(e)],c=[...new Set(a)],l=[...h.map(o=>({key:o,relationType:"uses"})),...c.map(o=>({key:o,relationType:"returns"}))];await w(l,O,async({key:o,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:p,targetKey:o,sourceFile:n.realRelativePath,fileHash:n.hash,sourceVersion:s,targetVersion:s,sourceRevision:r,targetRevision:r})}catch(f){this.#t.warn(`Failed to create relation between operation ${t} and type ${o} (${p}): ${f instanceof Error?f.message:"Unknown error"}`)}})}}export{U as GraphqlEntitiesExtractor};
3
+ `)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:n})=>{const r=a.filter(([,s])=>T(s));r.length!==0&&await w(r,b,async([s,i])=>{const c=i.getInterfaces?.()??[];if(!c.length)return;const l=this.#e(s,e);await w([...c],5,async o=>{const p=this.#e(o.name,e);try{await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"implements",targetKey:p,sourceFile:t.realRelativePath,fileHash:t.hash,sourceRevision:n,targetRevision:n})}catch(f){this.#t.warn(`Failed to create 'implements' relation ${l} -> ${p}: ${f instanceof Error?f.message:"Unknown error"}`)}})})};#f=async(t,e,a,n,r,s,i)=>{const{schema:h}=t,c=this.#n(h);if(c.length===0)return;const o=(await R(c,O,async({fieldName:p,field:f,operationType:m,rootTypeName:y})=>{const g=await this.#y(p,f,m,y,t,e,a,r,i);s.delete(`${g}:${n}`)},this.#t)).count.failed;o>0&&this.#t.warn(`Operation extraction completed with ${o} failures out of ${c.length} operations for ${e}`)};#y=async(t,e,a,n,r,s,i,h,c)=>{const l=`${s}-${d(`${a.toLowerCase()}-${t}`)}`,{inputTypes:o,returnTypes:p}=this.#o(e,s),f=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:o,returnTypes:p,description:r,descriptionUniqueKey:s,descriptionVersion:i,parentRevision:h,rbacTeams:c});return f&&await this.#m({apiOperationKey:f.key,inputTypes:o,returnTypes:p,descriptionUniqueKey:s,description:r,descriptionVersion:i,parentRevision:h}),l};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:r,returnTypes:s,description:i,descriptionUniqueKey:h,descriptionVersion:c,parentRevision:l,rbacTeams:o})=>{const p=t,m={type:"api-operation",key:`${h}-${d(`${a.toLowerCase()}-${t}`)}`,title:p,summary:e.description?C(e.description):null,tags:["graphql"],metadata:{method:a,path:`${n}.${t}`,payload:r,responses:s},version:c};try{return await this.catalogEntitiesService.createEntity({entity:m,sourceFile:i.realRelativePath,fileHash:i.hash,rbacTeams:o,source:"file",revision:l})}catch(y){return this.#t.warn(`Failed to create API operation entity for ${p}: ${y instanceof Error?y.message:"Unknown error"}`),null}};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:n,description:r,descriptionVersion:s,parentRevision:i})=>{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"partOf",targetKey:n,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:i,targetRevision:i});const h=[...new Set(e)],c=[...new Set(a)],l=[...h.map(o=>({key:o,relationType:"uses"})),...c.map(o=>({key:o,relationType:"returns"}))];await w(l,O,async({key:o,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:p,targetKey:o,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:i,targetRevision:i})}catch(f){this.#t.warn(`Failed to create relation between operation ${t} and type ${o} (${p}): ${f instanceof Error?f.message:"Unknown error"}`)}})}}export{U as GraphqlEntitiesExtractor};