@redocly/realm 0.136.0-next.0 → 0.136.0-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/CHANGELOG.md +202 -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/ejectComponent.d.ts +1 -1
  6. package/dist/cli/eject/ejectTheme.d.ts +1 -1
  7. package/dist/cli/eject/resolveEjectParams.js +1 -1
  8. package/dist/cli/eject/themeOperations.d.ts +2 -2
  9. package/dist/cli/stats/collectors/openapi/index.js +1 -1
  10. package/dist/cli/stats/index.js +1 -1
  11. package/dist/client/App.js +1 -1
  12. package/dist/client/ErrorBoundary.js +1 -1
  13. package/dist/client/TestProvider.d.ts +1 -1
  14. package/dist/client/TestProvider.js +1 -1
  15. package/dist/client/api-docs-builder-entry.d.ts +3 -0
  16. package/dist/client/api-docs-builder-entry.js +1 -0
  17. package/dist/client/app/ConditionalLink.d.ts +1 -1
  18. package/dist/client/app/Feedback/useSubmitFeedback.js +1 -1
  19. package/dist/client/app/Sidebar/Sidebar.js +3 -3
  20. package/dist/client/app/Sidebar/helpers/hide-empty-separators.d.ts +13 -0
  21. package/dist/client/app/Sidebar/helpers/hide-empty-separators.js +1 -0
  22. package/dist/client/app/Sidebar/useActions.js +1 -1
  23. package/dist/client/app/Sidebar/utils.js +1 -1
  24. package/dist/client/app/hooks/catalog/useCatalogFilter.d.ts +1 -1
  25. package/dist/client/app/hooks/catalog/useCatalogViewMode.js +1 -1
  26. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.d.ts +1 -1
  27. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.js +1 -1
  28. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.d.ts +2 -2
  29. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.js +1 -1
  30. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.d.ts +1 -1
  31. package/dist/client/app/hooks/catalog/useSearchTracker.d.ts +2 -5
  32. package/dist/client/app/hooks/catalog/useSearchTracker.js +1 -1
  33. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.d.ts +1 -6
  34. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
  35. package/dist/client/app/hooks/index.d.ts +1 -0
  36. package/dist/client/app/hooks/index.js +1 -1
  37. package/dist/client/app/hooks/useAutoScroll.js +1 -1
  38. package/dist/client/app/hooks/useUserClaims.js +1 -1
  39. package/dist/client/app/l10n/hooks/index.d.ts +1 -0
  40. package/dist/client/app/l10n/hooks/index.js +1 -1
  41. package/dist/client/app/l10n/hooks/useTranslate.js +1 -1
  42. package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
  43. package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -0
  44. package/dist/client/app/l10n/initL10n.js +1 -1
  45. package/dist/client/app/markdoc/custom-components/openapi/json-schema.d.ts +1 -1
  46. package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
  47. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +1 -5
  48. package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
  49. package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
  50. package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
  51. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.d.ts +8 -24
  52. package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
  53. package/dist/client/app/markdoc/hooks/use-store.d.ts +8 -6
  54. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.d.ts +20 -0
  55. package/dist/client/app/markdoc/utils/build-replay-operation-source-map.js +1 -0
  56. package/dist/client/app/markdoc/utils/find-api-item.d.ts +15 -0
  57. package/dist/client/app/markdoc/utils/find-api-item.js +1 -0
  58. package/dist/client/app/markdoc/utils/find-code-sample-panel.d.ts +11 -0
  59. package/dist/client/app/markdoc/utils/find-code-sample-panel.js +1 -0
  60. package/dist/client/app/markdoc/utils/find-openapi-response-samples.d.ts +15 -0
  61. package/dist/client/app/markdoc/utils/find-openapi-response-samples.js +1 -0
  62. package/dist/client/app/markdoc/utils/openapi-panel-entry.d.ts +18 -0
  63. package/dist/client/app/markdoc/utils/openapi-panel-entry.js +1 -0
  64. package/dist/client/app/pages/DevLogin/DevLoginForm.d.ts +1 -1
  65. package/dist/client/app/useGlobalData.d.ts +1 -1
  66. package/dist/client/app/usePreloadHistory.d.ts +2 -2
  67. package/dist/client/app/usePreloadHistory.js +1 -1
  68. package/dist/client/app/utils/loadAndNavigate.d.ts +1 -1
  69. package/dist/client/app/utils/loadAndNavigate.js +1 -1
  70. package/dist/client/app/utils/resolveRouteBySlug.js +1 -1
  71. package/dist/client/app/utils/same-resolved-route.d.ts +5 -0
  72. package/dist/client/app/utils/same-resolved-route.js +1 -0
  73. package/dist/client/browser-entry.js +2 -2
  74. package/dist/client/providers/page-data/hooks.d.ts +2 -2
  75. package/dist/client/providers/post-message/PostMessageProvider.js +1 -1
  76. package/dist/client/providers/post-message/use-post-message.d.ts +1 -1
  77. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  78. package/dist/client/runtime/loader.js +1 -1
  79. package/dist/client/templates/api-docs/helpers.d.ts +10 -0
  80. package/dist/client/templates/api-docs/helpers.js +1 -0
  81. package/dist/client/templates/api-docs/template.d.ts +17 -0
  82. package/dist/client/templates/api-docs/template.js +14 -0
  83. package/dist/client/templates/openapi-docs/helpers.d.ts +1 -1
  84. package/dist/client/templates/openapi-docs/helpers.js +2 -2
  85. package/dist/client/types/sidebar.d.ts +0 -1
  86. package/dist/client/utils/utils.d.ts +0 -2
  87. package/dist/client/utils/utils.js +1 -1
  88. package/dist/constants/common.d.ts +14 -1
  89. package/dist/constants/common.js +1 -1
  90. package/dist/constants/l10n/langs/ar.js +1 -1
  91. package/dist/constants/l10n/langs/de.js +1 -1
  92. package/dist/constants/l10n/langs/en.js +1 -1
  93. package/dist/constants/l10n/langs/es.js +1 -1
  94. package/dist/constants/l10n/langs/fr.js +1 -1
  95. package/dist/constants/l10n/langs/hi.js +1 -1
  96. package/dist/constants/l10n/langs/it.js +1 -1
  97. package/dist/constants/l10n/langs/ja.js +1 -1
  98. package/dist/constants/l10n/langs/ko.js +1 -1
  99. package/dist/constants/l10n/langs/pl.js +1 -1
  100. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  101. package/dist/constants/l10n/langs/pt.js +1 -1
  102. package/dist/constants/l10n/langs/ru.js +1 -1
  103. package/dist/constants/l10n/langs/uk.js +1 -1
  104. package/dist/constants/l10n/langs/zh.js +1 -1
  105. package/dist/markdoc/tags/index.d.ts +48 -2
  106. package/dist/server/api-routes/execute-api-route.js +1 -1
  107. package/dist/server/api-routes/helpers/enhance-context.d.ts +3 -1
  108. package/dist/server/api-routes/helpers/enhance-context.js +1 -1
  109. package/dist/server/api-routes/helpers/is-mock-server.d.ts +2 -0
  110. package/dist/server/api-routes/helpers/is-mock-server.js +1 -0
  111. package/dist/server/api-routes/helpers/read-stream-with-size-limit.d.ts +1 -1
  112. package/dist/server/api-routes/mock-server/kv-state-store.d.ts +3 -0
  113. package/dist/server/api-routes/mock-server/kv-state-store.js +1 -0
  114. package/dist/server/api-routes/mock-server/mock-js-executor.d.ts +3 -0
  115. package/dist/server/api-routes/mock-server/mock-js-executor.js +13 -0
  116. package/dist/server/api-routes/run-api-routes-worker.d.ts +1 -1
  117. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  118. package/dist/server/config/env-config.d.ts +4 -4
  119. package/dist/server/config/env-schema.d.ts +10 -10
  120. package/dist/server/config/env-schemas/catalog.d.ts +3 -0
  121. package/dist/server/config/env-schemas/catalog.js +1 -1
  122. package/dist/server/config/env-schemas/feature-flags.d.ts +4 -8
  123. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  124. package/dist/server/constants/common.d.ts +2 -0
  125. package/dist/server/constants/common.js +1 -1
  126. package/dist/server/constants/entitlements.js +1 -1
  127. package/dist/server/constants/plugins/api-docs.d.ts +3 -0
  128. package/dist/server/constants/plugins/api-docs.js +1 -0
  129. package/dist/server/esbuild/esbuild-logger.js +3 -3
  130. package/dist/server/esbuild/esbuild.js +3 -3
  131. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +9 -0
  132. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +1 -0
  133. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +2 -0
  134. package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +1 -0
  135. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +6 -0
  136. package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +1 -0
  137. package/dist/server/persistence/cache/mappers/create-cache-db-record.d.ts +1 -1
  138. package/dist/server/persistence/file-hashes/mappers/create-file-hash-db-record.d.ts +1 -1
  139. package/dist/server/persistence/kv/mappers/create-kv-db-record.d.ts +1 -1
  140. package/dist/server/plugins/api-docs/get-server-props.d.ts +4 -0
  141. package/dist/server/plugins/api-docs/get-server-props.js +1 -0
  142. package/dist/server/plugins/api-docs/get-template-path.d.ts +2 -0
  143. package/dist/server/plugins/api-docs/get-template-path.js +1 -0
  144. package/dist/server/plugins/api-docs/import-api-docs-builder.d.ts +8 -0
  145. package/dist/server/plugins/api-docs/import-api-docs-builder.js +1 -0
  146. package/dist/server/plugins/api-docs/index.d.ts +19 -0
  147. package/dist/server/plugins/api-docs/index.js +1 -0
  148. package/dist/server/plugins/api-docs/loader.d.ts +35 -0
  149. package/dist/server/plugins/api-docs/loader.js +3 -0
  150. package/dist/server/plugins/api-docs/options.d.ts +14 -0
  151. package/dist/server/plugins/api-docs/options.js +1 -0
  152. package/dist/server/plugins/api-docs/search/get-ai-search-documents.d.ts +20 -0
  153. package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +105 -0
  154. package/dist/server/plugins/api-docs/search/search-facets.d.ts +10 -0
  155. package/dist/server/plugins/api-docs/search/search-facets.js +1 -0
  156. package/dist/server/plugins/api-docs/search/search-indexer.d.ts +9 -0
  157. package/dist/server/plugins/api-docs/search/search-indexer.js +1 -0
  158. package/dist/server/plugins/api-docs/search/search-resolver.d.ts +5 -0
  159. package/dist/server/plugins/api-docs/search/search-resolver.js +1 -0
  160. package/dist/server/plugins/api-docs/spec-download.api.d.ts +4 -0
  161. package/dist/server/plugins/api-docs/spec-download.api.js +1 -0
  162. package/dist/server/plugins/api-docs/store-definition-bundles.d.ts +3 -0
  163. package/dist/server/plugins/api-docs/store-definition-bundles.js +1 -0
  164. package/dist/server/plugins/api-docs/utils/build-item-positions.d.ts +17 -0
  165. package/dist/server/plugins/api-docs/utils/build-item-positions.js +1 -0
  166. package/dist/server/plugins/api-docs/utils/build-routes-mapping.d.ts +3 -0
  167. package/dist/server/plugins/api-docs/utils/build-routes-mapping.js +1 -0
  168. package/dist/server/plugins/api-docs/utils/collect-item-routes.d.ts +12 -0
  169. package/dist/server/plugins/api-docs/utils/collect-item-routes.js +1 -0
  170. package/dist/server/plugins/api-docs/utils/decorators.d.ts +26 -0
  171. package/dist/server/plugins/api-docs/utils/decorators.js +1 -0
  172. package/dist/server/plugins/api-docs/utils/format-bundle-error.d.ts +6 -0
  173. package/dist/server/plugins/api-docs/utils/format-bundle-error.js +5 -0
  174. package/dist/server/plugins/api-docs/utils/normalize-api-version.d.ts +2 -0
  175. package/dist/server/plugins/api-docs/utils/normalize-api-version.js +1 -0
  176. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.d.ts +2 -0
  177. package/dist/server/plugins/api-docs/utils/normalize-feedback-options.js +1 -0
  178. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.d.ts +20 -0
  179. package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.js +1 -0
  180. package/dist/server/plugins/api-docs/utils/replace-file-extension.d.ts +2 -0
  181. package/dist/server/plugins/api-docs/utils/replace-file-extension.js +1 -0
  182. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.d.ts +3 -0
  183. package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.js +1 -0
  184. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.d.ts +10 -0
  185. package/dist/server/plugins/api-docs/utils/resolve-config-rbac.js +1 -0
  186. package/dist/server/plugins/api-docs/utils/to-relative-slug.d.ts +2 -0
  187. package/dist/server/plugins/api-docs/utils/to-relative-slug.js +1 -0
  188. package/dist/server/plugins/api-functions/index.js +1 -1
  189. package/dist/server/plugins/arazzo-docs/index.js +1 -1
  190. package/dist/server/plugins/asyncapi-docs/index.js +1 -1
  191. package/dist/server/plugins/catalog-classic/index.js +1 -1
  192. package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +27 -0
  193. package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.js +12 -0
  194. package/dist/server/plugins/catalog-entities/database/catalog-entities-publisher.js +1 -12
  195. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +22 -0
  196. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +62 -0
  197. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +5 -5
  198. package/dist/server/plugins/catalog-entities/database/consts.d.ts +5 -0
  199. package/dist/server/plugins/catalog-entities/database/consts.js +1 -1
  200. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +1 -1
  201. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.d.ts +1 -1
  202. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-file-schema.d.ts +1 -1
  203. package/dist/server/plugins/catalog-entities/database/remote-publish-lock-service.d.ts +3 -3
  204. package/dist/server/plugins/catalog-entities/database/repositories/bffEntities/bff-entities-read-repository.d.ts +2 -2
  205. package/dist/server/plugins/catalog-entities/database/repositories/catalog-entities-repository.js +1 -1
  206. package/dist/server/plugins/catalog-entities/database/repositories/common/filters-repository.d.ts +1 -1
  207. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +1 -1
  208. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-read-repository.d.ts +1 -1
  209. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.d.ts +2 -2
  210. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
  211. package/dist/server/plugins/catalog-entities/database/repositories/entityAttributes/entity-attributes-write-repository.d.ts +1 -1
  212. package/dist/server/plugins/catalog-entities/database/repositories/relations/relations-read-repository.d.ts +1 -1
  213. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  214. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +13 -5
  215. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  216. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +5 -2
  217. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  218. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +6 -5
  219. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  220. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +12 -5
  221. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  222. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.d.ts +1 -1
  223. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  224. package/dist/server/plugins/catalog-entities/template/index.js +1 -1
  225. package/dist/server/plugins/catalog-entities/types/openapi.d.ts +1 -1
  226. package/dist/server/plugins/catalog-entities/utils/get-not-accessible-catalog-resources.d.ts +1 -1
  227. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.d.ts +4 -4
  228. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
  229. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.d.ts +4 -3
  230. package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.js +1 -1
  231. package/dist/server/plugins/config-parser/index.js +1 -1
  232. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  233. package/dist/server/plugins/create-slugify.d.ts +17 -0
  234. package/dist/server/plugins/create-slugify.js +1 -0
  235. package/dist/server/plugins/default-theme/index.js +1 -1
  236. package/dist/server/plugins/dev-onboarding/index.d.ts +1 -1
  237. package/dist/server/plugins/dev-onboarding/index.js +1 -1
  238. package/dist/server/plugins/dev-onboarding/template/components/RevokeAPIKey.d.ts +1 -1
  239. package/dist/server/plugins/dev-onboarding/template/components/RollAPIKey.d.ts +1 -1
  240. package/dist/server/plugins/entitlements/index.js +1 -1
  241. package/dist/server/plugins/graphql-docs/index.js +1 -1
  242. package/dist/server/plugins/graphql-docs/search/ai/utils.d.ts +1 -1
  243. package/dist/server/plugins/helpers/parse-partials.d.ts +3 -0
  244. package/dist/server/plugins/helpers/parse-partials.js +1 -0
  245. package/dist/server/plugins/l10n/index.js +1 -1
  246. package/dist/server/plugins/lifecycle.js +2 -2
  247. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +5 -3
  248. package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.js +1 -1
  249. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -1
  250. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  251. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
  252. package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.js +1 -1
  253. package/dist/server/plugins/markdown/index.js +1 -1
  254. package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +9 -9
  255. package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +5 -0
  256. package/dist/server/plugins/markdown/markdoc/plugins/utils.js +1 -1
  257. package/dist/server/plugins/markdown/runtime-transform.js +1 -1
  258. package/dist/server/plugins/markdown/search/create-render-tag-fn.d.ts +2 -1
  259. package/dist/server/plugins/markdown/search/create-render-tag-fn.js +1 -1
  260. package/dist/server/plugins/markdown/search/get-ai-search-documents.js +9 -9
  261. package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
  262. package/dist/server/plugins/markdown/utils/resolve-markdown-template.d.ts +1 -1
  263. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +3 -0
  264. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  265. package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +1 -1
  266. package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +1 -1
  267. package/dist/server/plugins/mcp/codemode/code-audit.d.ts +12 -0
  268. package/dist/server/plugins/mcp/codemode/code-audit.js +1 -0
  269. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +11 -0
  270. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -0
  271. package/dist/server/plugins/mcp/codemode/constants.d.ts +3 -0
  272. package/dist/server/plugins/mcp/codemode/constants.js +1 -1
  273. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  274. package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.d.ts +10 -0
  275. package/dist/server/plugins/mcp/codemode/sandbox/create-sandbox-setup.js +11 -0
  276. package/dist/server/plugins/mcp/codemode/sandbox/polyfills.d.ts +2 -0
  277. package/dist/server/plugins/mcp/codemode/sandbox/{sandbox-polyfills.js → polyfills.js} +7 -8
  278. package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +2 -3
  279. package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +1 -1
  280. package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
  281. package/dist/server/plugins/mcp/codemode/tools/execute.d.ts +1 -0
  282. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  283. package/dist/server/plugins/mcp/codemode/types.d.ts +0 -8
  284. package/dist/server/plugins/mcp/constants.d.ts +2 -1
  285. package/dist/server/plugins/mcp/constants.js +1 -1
  286. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +1 -0
  287. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  288. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.d.ts +11 -0
  289. package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -0
  290. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.d.ts +4 -0
  291. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.js +1 -0
  292. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
  293. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type.js +7 -4
  294. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +7 -1
  295. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.js +0 -1
  296. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.d.ts +5 -1
  297. package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.js +4 -2
  298. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +4 -0
  299. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  300. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.d.ts +2 -0
  301. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.js +1 -0
  302. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
  303. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoints.js +1 -1
  304. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-full-api-description.js +1 -1
  305. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
  306. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/list-apis.js +1 -1
  307. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +6 -2
  308. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.js +1 -1
  309. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/types.d.ts +2 -0
  310. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +2 -2
  311. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  312. package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +3 -3
  313. package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
  314. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +28 -0
  315. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +2 -0
  316. package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +5 -17
  317. package/dist/server/plugins/mcp/gateway-mcp/eligibility.js +1 -1
  318. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +9 -9
  319. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -1
  320. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +17 -1
  321. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
  322. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.d.ts +11 -0
  323. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-errors.js +1 -0
  324. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.d.ts +14 -0
  325. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.js +1 -0
  326. package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.d.ts +6 -0
  327. package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.js +1 -0
  328. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.d.ts +4 -0
  329. package/dist/server/plugins/mcp/gateway-mcp/fetch/redact.js +1 -0
  330. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.d.ts +22 -0
  331. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-blocklist.js +1 -0
  332. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.d.ts +1 -1
  333. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -1
  334. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.d.ts +13 -0
  335. package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-safe-lookup.js +1 -0
  336. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.d.ts +8 -1
  337. package/dist/server/plugins/mcp/gateway-mcp/fetch-capability.js +1 -1
  338. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.d.ts +3 -0
  339. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.js +1 -0
  340. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.d.ts +16 -0
  341. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/edge-limiter.js +1 -0
  342. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.d.ts +2 -0
  343. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +1 -0
  344. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.d.ts +7 -0
  345. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/limits.js +1 -0
  346. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.d.ts +8 -0
  347. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.js +1 -0
  348. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.d.ts +15 -0
  349. package/dist/server/plugins/mcp/gateway-mcp/rate-limit/window-counter.js +1 -0
  350. package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +24 -0
  351. package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -0
  352. package/dist/server/plugins/mcp/gateway-mcp/subject.d.ts +20 -0
  353. package/dist/server/plugins/mcp/gateway-mcp/subject.js +1 -0
  354. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +18 -0
  355. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +1 -0
  356. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +10 -0
  357. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.js +1 -0
  358. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  359. package/dist/server/plugins/mcp/handlers/errors.d.ts +3 -3
  360. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  361. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
  362. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.d.ts +5 -0
  363. package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +101 -0
  364. package/dist/server/plugins/mcp/index.d.ts +1 -0
  365. package/dist/server/plugins/mcp/index.js +1 -1
  366. package/dist/server/plugins/mcp/servers/docs-server.d.ts +3 -1
  367. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  368. package/dist/server/plugins/mcp/servers/mcp-server.d.ts +15 -8
  369. package/dist/server/plugins/mcp/servers/mcp-server.js +1 -1
  370. package/dist/server/plugins/mcp/types.d.ts +16 -20
  371. package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +9 -0
  372. package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -0
  373. package/dist/server/plugins/mcp/utils/jwt.d.ts +0 -9
  374. package/dist/server/plugins/mcp/utils/jwt.js +1 -1
  375. package/dist/server/plugins/mcp/utils/mode.d.ts +12 -2
  376. package/dist/server/plugins/mcp/utils/mode.js +1 -1
  377. package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +8 -0
  378. package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -0
  379. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +1 -1
  380. package/dist/server/plugins/mcp/utils.d.ts +17 -5
  381. package/dist/server/plugins/mcp/utils.js +1 -1
  382. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  383. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +10 -2
  384. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  385. package/dist/server/plugins/openapi-docs/index.js +1 -1
  386. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +16 -16
  387. package/dist/server/plugins/openapi-docs/utils.js +1 -1
  388. package/dist/server/plugins/pages/index.js +1 -1
  389. package/dist/server/plugins/scorecard-classic/compute-scorecard.d.ts +1 -1
  390. package/dist/server/plugins/scorecard-classic/compute-scorecard.js +4 -4
  391. package/dist/server/plugins/scorecard-classic/index.d.ts +1 -1
  392. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  393. package/dist/server/plugins/scorecard-classic/template/components.d.ts +1 -1
  394. package/dist/server/plugins/scorecard-classic/template/useData.d.ts +1 -1
  395. package/dist/server/plugins/scorecards/plugin.js +1 -1
  396. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.d.ts +1 -1
  397. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +2 -2
  398. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  399. package/dist/server/plugins/search/engines/flexsearch/index.js +1 -1
  400. package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
  401. package/dist/server/plugins/search/engines/search-engine.d.ts +1 -1
  402. package/dist/server/plugins/search/engines/typesense/index.js +1 -1
  403. package/dist/server/plugins/search/index.js +1 -1
  404. package/dist/server/plugins/search/llmstxt/index.d.ts +1 -1
  405. package/dist/server/plugins/search/llmstxt/index.js +4 -4
  406. package/dist/server/plugins/sidebars/index.d.ts +1 -1
  407. package/dist/server/plugins/sidebars/index.js +1 -1
  408. package/dist/server/plugins/sitemap/index.js +1 -1
  409. package/dist/server/plugins/sso/index.js +1 -1
  410. package/dist/server/providers/database/database-path-generator.d.ts +2 -2
  411. package/dist/server/providers/database/utils/storage-limit-validator.d.ts +1 -1
  412. package/dist/server/sandbox/constants/host-functions.d.ts +3 -0
  413. package/dist/server/sandbox/constants/host-functions.js +1 -0
  414. package/dist/server/sandbox/constants/sandbox.d.ts +6 -0
  415. package/dist/server/sandbox/constants/sandbox.js +1 -0
  416. package/dist/server/sandbox/sandbox.d.ts +8 -0
  417. package/dist/server/sandbox/sandbox.js +3 -0
  418. package/dist/server/sandbox/types.d.ts +25 -0
  419. package/dist/server/sandbox/utils/eval-guest-code.d.ts +15 -0
  420. package/dist/server/sandbox/utils/eval-guest-code.js +1 -0
  421. package/dist/server/sandbox/utils/execution-budget.d.ts +12 -0
  422. package/dist/server/sandbox/utils/execution-budget.js +1 -0
  423. package/dist/server/sandbox/utils/setup-host-functions.d.ts +18 -0
  424. package/dist/server/sandbox/utils/setup-host-functions.js +5 -0
  425. package/dist/server/ssr/render.js +1 -1
  426. package/dist/server/ssr/server-side-props/get-default-static-props.d.ts +1 -1
  427. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.d.ts +1 -1
  428. package/dist/server/ssr/template.d.ts +1 -1
  429. package/dist/server/ssr/utils.d.ts +1 -0
  430. package/dist/server/ssr/utils.js +5 -5
  431. package/dist/server/store.d.ts +2 -6
  432. package/dist/server/store.js +1 -1
  433. package/dist/server/tools/notifiers/logger.js +1 -1
  434. package/dist/server/tools/notifiers/reporter.js +6 -6
  435. package/dist/server/types/plugins/common.d.ts +4 -6
  436. package/dist/server/types/plugins/markdown.d.ts +1 -3
  437. package/dist/server/types/plugins/search.d.ts +1 -0
  438. package/dist/server/utils/catalog-classic/get-route-slug-to-catalog-slug-map.test.js +1 -1
  439. package/dist/server/utils/crypto/constants.d.ts +5 -0
  440. package/dist/server/utils/crypto/constants.js +1 -0
  441. package/dist/server/utils/crypto/decrypt-aes-gcm.d.ts +6 -0
  442. package/dist/server/utils/crypto/decrypt-aes-gcm.js +1 -0
  443. package/dist/server/utils/crypto/decrypt-claim-value.d.ts +6 -0
  444. package/dist/server/utils/crypto/decrypt-claim-value.js +1 -0
  445. package/dist/server/utils/crypto/derive-key.d.ts +5 -0
  446. package/dist/server/utils/crypto/derive-key.js +1 -0
  447. package/dist/server/utils/crypto/encrypt-aes-gcm.d.ts +6 -0
  448. package/dist/server/utils/crypto/encrypt-aes-gcm.js +1 -0
  449. package/dist/server/utils/crypto/encrypt-claim-value.d.ts +6 -0
  450. package/dist/server/utils/crypto/encrypt-claim-value.js +1 -0
  451. package/dist/server/utils/fetch-with-client.d.ts +10 -0
  452. package/dist/server/utils/fetch-with-client.js +1 -0
  453. package/dist/server/utils/l10n/get-build-translate-context.d.ts +7 -0
  454. package/dist/server/utils/l10n/get-build-translate-context.js +1 -0
  455. package/dist/server/utils/llmstxt/agent-feedback-llms-footer.js +1 -1
  456. package/dist/server/utils/rbac.d.ts +4 -0
  457. package/dist/server/utils/rbac.js +1 -1
  458. package/dist/server/utils/report-all-errors.js +1 -1
  459. package/dist/server/utils/sandbox-context.d.ts +18 -0
  460. package/dist/server/utils/sandbox-context.js +1 -0
  461. package/dist/server/utils/shared-data.js +1 -1
  462. package/dist/server/web-server/auth.d.ts +34 -4
  463. package/dist/server/web-server/auth.js +3 -3
  464. package/dist/server/web-server/handle-api-route-request.js +1 -1
  465. package/dist/server/web-server/middleware/apiKeyMiddleware.js +1 -1
  466. package/dist/server/web-server/middleware/catalogAuthMiddleware.d.ts +1 -1
  467. package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
  468. package/dist/server/web-server/middleware/telemetry-middleware.js +1 -1
  469. package/dist/server/web-server/routes/api-routes/api-routes.js +1 -1
  470. package/dist/server/web-server/routes/ask-ai.js +1 -1
  471. package/dist/server/web-server/routes/auth.js +1 -1
  472. package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
  473. package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -1
  474. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  475. package/dist/server/web-server/routes/catalog/catalog-relations.js +1 -1
  476. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  477. package/dist/server/web-server/routes/catalog/helpers/has-access-to-entity.d.ts +1 -1
  478. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.d.ts +1 -1
  479. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.js +1 -1
  480. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  481. package/dist/server/web-server/routes/feedback.d.ts +1 -1
  482. package/dist/server/web-server/routes/feedback.js +1 -1
  483. package/dist/server/web-server/routes/helpers/process-redirects.d.ts +1 -1
  484. package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -1
  485. package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -1
  486. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.d.ts +10 -6
  487. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  488. package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
  489. package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
  490. package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +1 -1
  491. package/dist/server/web-server/routes/page-data.js +1 -1
  492. package/dist/server/web-server/routes/resolve-route.js +1 -1
  493. package/dist/server/web-server/routes/search.js +1 -1
  494. package/dist/server/web-server/routes/semantic-search.js +1 -1
  495. package/dist/server/web-server/routes/skills/skill-markdown.js +1 -1
  496. package/dist/server/web-server/routes/skills/skills-index.js +1 -1
  497. package/dist/server/web-server/utils/prepare-list-response.d.ts +1 -1
  498. package/dist/server/workers/api-routes-worker-pool.js +1 -1
  499. package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
  500. package/dist/server/workers/worker-pool.d.ts +1 -0
  501. package/dist/server/workers/worker-pool.js +1 -1
  502. package/dist/types/entitlements.d.ts +6 -1
  503. package/dist/types/markdoc.d.ts +2 -1
  504. package/dist/utils/l10n/build-i18n-config.d.ts +24 -0
  505. package/dist/utils/l10n/build-i18n-config.js +1 -0
  506. package/dist/utils/l10n/create-translate.d.ts +19 -0
  507. package/dist/utils/l10n/create-translate.js +1 -0
  508. package/dist/utils/url/get-shared-data-fetch-url.d.ts +17 -0
  509. package/dist/utils/url/get-shared-data-fetch-url.js +1 -0
  510. package/dist/utils/url/parse-preview-url.d.ts +22 -0
  511. package/dist/utils/url/parse-preview-url.js +1 -0
  512. package/package.json +16 -15
  513. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.d.ts +0 -4
  514. package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.js +0 -1
  515. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.d.ts +0 -4
  516. package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.js +0 -1
  517. package/dist/markdoc/helpers/get-operation/get-operation.d.ts +0 -14
  518. package/dist/markdoc/helpers/get-operation/get-operation.js +0 -1
  519. package/dist/markdoc/helpers/get-operation/index.d.ts +0 -4
  520. package/dist/markdoc/helpers/get-operation/index.js +0 -1
  521. package/dist/markdoc/helpers/get-operation/types/index.d.ts +0 -4
  522. package/dist/markdoc/helpers/get-operation/types/operation-identifier.d.ts +0 -5
  523. package/dist/markdoc/helpers/get-operation/types/operation-identifier.js +0 -0
  524. package/dist/markdoc/helpers/get-operation/types/operation-info.d.ts +0 -6
  525. package/dist/markdoc/helpers/get-operation/types/operation-info.js +0 -0
  526. package/dist/markdoc/helpers/get-operation/types/operation-parameters.d.ts +0 -3
  527. package/dist/markdoc/helpers/get-operation/types/operation-parameters.js +0 -0
  528. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.d.ts +0 -4
  529. package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.js +0 -1
  530. package/dist/server/plugins/mcp/codemode/sandbox/sandbox-polyfills.d.ts +0 -3
  531. package/dist/server/plugins/mcp/codemode/sandbox/sandbox.d.ts +0 -3
  532. package/dist/server/plugins/mcp/codemode/sandbox/sandbox.js +0 -15
  533. package/dist/server/plugins/mcp/handlers/sse-keepalive.d.ts +0 -15
  534. package/dist/server/plugins/mcp/handlers/sse-keepalive.js +0 -3
  535. /package/dist/{markdoc/helpers/get-operation/types/index.js → server/sandbox/types.js} +0 -0
@@ -0,0 +1,62 @@
1
+ import{and as U,eq as F,inArray as E,isNull as v,sql as a}from"drizzle-orm";import{entitiesRelationsTable as d}from"../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{entitiesTable as w}from"../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{fileHashesTable as l}from"../../../providers/database/databases/sqlite-db/schemas/file-hashes-table.js";import{FileHashStatus as A}from"../../../persistence/file-hashes/types.js";import{DELETE_IDS_CHUNK_SIZE as _,VACUUM_AFTER_PRUNED_ROWS as g}from"./consts.js";const y={prunedEntities:0,prunedRelations:0,legacyRelationsHealed:0,legacyRelationsDeleted:0,affectedSourceFiles:[],vacuumed:!1};class c{static async pruneLocalRevisions({localConnection:n,maxRevisions:r,vacuumThreshold:s=g}){if(!Number.isFinite(r)||r<=0)return y;const t=n.client.client,S=await t.transaction(async i=>{const C=await i.all(a`
2
+ SELECT DISTINCT e.source_file
3
+ FROM entities_relations r
4
+ JOIN entities e ON e.key = r.source_key AND e.source_file IS NOT NULL
5
+ WHERE r.source_file IS NULL
6
+ `),h=await i.run(a`
7
+ UPDATE entities_relations
8
+ SET source_file = (
9
+ SELECT e.source_file FROM entities e
10
+ WHERE e.key = entities_relations.source_key
11
+ AND e.source_file IS NOT NULL
12
+ ORDER BY e.is_current DESC, e.revision DESC
13
+ LIMIT 1
14
+ )
15
+ WHERE source_file IS NULL
16
+ AND EXISTS (
17
+ SELECT 1 FROM entities e
18
+ WHERE e.key = entities_relations.source_key
19
+ AND e.source_file IS NOT NULL
20
+ )
21
+ `),N=Number(h.rowsAffected??0),k=await i.delete(d).where(v(d.sourceFile)).run(),T=Number(k.rowsAffected??0),u=await i.all(a`
22
+ SELECT id, source_file
23
+ FROM (
24
+ SELECT id,
25
+ source_file,
26
+ is_current,
27
+ is_default_version,
28
+ ROW_NUMBER() OVER (
29
+ PARTITION BY key, version
30
+ ORDER BY revision DESC, id DESC
31
+ ) AS revision_rank
32
+ FROM entities
33
+ WHERE source = 'file' AND source_file IS NOT NULL
34
+ )
35
+ WHERE revision_rank > ${r}
36
+ AND COALESCE(is_current, 1) = 0
37
+ AND COALESCE(is_default_version, 0) = 0
38
+ `),f=new Set(C.map(e=>e.source_file));for(const e of u)e.source_file&&f.add(e.source_file);if(u.length===0&&N===0&&T===0)return{legacyRelationsHealed:N,legacyRelationsDeleted:T,prune:null};for(const e of c.#e(u.map(O=>O.id),_))await i.delete(w).where(E(w.id,e)).run();const D=await i.all(a`
39
+ SELECT id, source_file
40
+ FROM entities_relations r
41
+ WHERE r.source_file IS NOT NULL
42
+ AND (
43
+ (
44
+ r.source_revision != ''
45
+ AND NOT EXISTS (
46
+ SELECT 1 FROM entities e
47
+ WHERE e.key = r.source_key
48
+ AND e.revision = r.source_revision
49
+ AND (r.source_version = '' OR e.version = r.source_version)
50
+ )
51
+ )
52
+ OR (
53
+ r.target_revision != ''
54
+ AND NOT EXISTS (
55
+ SELECT 1 FROM entities e
56
+ WHERE e.key = r.target_key
57
+ AND e.revision = r.target_revision
58
+ AND (r.target_version = '' OR e.version = r.target_version)
59
+ )
60
+ )
61
+ )
62
+ `);for(const e of D)e.source_file&&f.add(e.source_file);for(const e of c.#e(D.map(O=>O.id),_))await i.delete(d).where(E(d.id,e)).run();const I=new Date().toISOString();for(const e of c.#e(Array.from(f),_))await i.update(l).set({status:A.OUTDATED,updatedAt:I}).where(E(l.filePath,e)).run();return{legacyRelationsHealed:N,legacyRelationsDeleted:T,prune:{prunedEntities:u.length,prunedRelations:D.length,affectedSourceFiles:Array.from(f)}}}),{legacyRelationsHealed:p,legacyRelationsDeleted:R,prune:o}=S;if(!o&&p===0&&R===0)return y;const m=(o?.prunedEntities??0)+(o?.prunedRelations??0)+R;let L=!1;return m>=s&&(await t.run(a`VACUUM`),L=!0),{prunedEntities:o?.prunedEntities??0,prunedRelations:o?.prunedRelations??0,legacyRelationsHealed:p,legacyRelationsDeleted:R,affectedSourceFiles:o?.affectedSourceFiles??[],vacuumed:L}}static async confirmPrunedFiles({localConnection:n,sourceFiles:r}){if(r.length===0)return;const s=n.client.client,t=new Date().toISOString();for(const S of c.#e(r,_))await s.update(l).set({status:A.UP_TO_DATE,updatedAt:t}).where(U(E(l.filePath,S),F(l.status,A.OUTDATED))).run()}static#e(n,r){const s=[];for(let t=0;t<n.length;t+=r)s.push(n.slice(t,t+r));return s}}export{c as CatalogEntitiesRevisionsPruner};
@@ -18,7 +18,7 @@ export declare class CatalogEntitiesService extends BaseService<CatalogEntitiesR
18
18
  static getInstance(options: ServiceInstanceOptions): Promise<CatalogEntitiesService>;
19
19
  sync(): Promise<void>;
20
20
  transaction<T>(...args: Parameters<TransactionsManager['transaction']>): Promise<T>;
21
- getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
21
+ getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
22
22
  paginationParams: PaginationParams;
23
23
  rbacTeams?: string[];
24
24
  excludedTypes?: string[];
@@ -33,13 +33,13 @@ export declare class CatalogEntitiesService extends BaseService<CatalogEntitiesR
33
33
  getCatalogFilters(params: CatalogFiltersParams): Promise<Record<string, import("./repositories/types.js").FilterOption[]>>;
34
34
  getEntityRelationById(id: string): Promise<EntityRelationReadModelSchema | null>;
35
35
  getEntitiesRelations(paginationParams?: PaginationParams): Promise<ListResponseResult<EntityRelationReadModelSchema>>;
36
- getEntitiesWithRelations({ paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
36
+ getEntitiesWithRelations({ paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
37
37
  paginationParams: PaginationParams;
38
38
  rbacTeams?: string[];
39
39
  excludedTypes?: string[];
40
40
  excludedEntities?: string[];
41
41
  }): Promise<BffCatalogEntityList>;
42
- getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities }: {
42
+ getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities, }: {
43
43
  entityKey: string;
44
44
  filter?: {
45
45
  revision?: string | null;
@@ -49,7 +49,7 @@ export declare class CatalogEntitiesService extends BaseService<CatalogEntitiesR
49
49
  excludedTypes?: string[];
50
50
  excludedEntities?: string[];
51
51
  }): Promise<BffCatalogEntity | null>;
52
- getRelatedEntities({ entityKey, paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
52
+ getRelatedEntities({ entityKey, paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
53
53
  entityKey: string;
54
54
  paginationParams: PaginationParams;
55
55
  rbacTeams?: string[];
@@ -76,7 +76,7 @@ export declare class CatalogEntitiesService extends BaseService<CatalogEntitiesR
76
76
  createEntitiesRelations(entities: EntityRelationDtoSchema[]): Promise<BulkSyncResult<EntityRelationReadModelSchema>>;
77
77
  updateEntityRelation(incomingRelationData: Partial<EntityRelationDtoSchema>, relationToBeUpdated: EntityRelationReadModelSchema): Promise<EntityRelationReadModelSchema | null>;
78
78
  deleteEntityRelation(id: string): Promise<string | null>;
79
- softDeleteEntitiesWithRelations({ filter, revision, fileHash }: {
79
+ softDeleteEntitiesWithRelations({ filter, revision, fileHash, }: {
80
80
  filter: Filter;
81
81
  revision: string;
82
82
  fileHash: string;
@@ -2,6 +2,11 @@ export declare const DEFAULT_CHUNK_SIZE = 20;
2
2
  export declare const MAX_LOGGED_DB_ERROR_LENGTH = 1000;
3
3
  export declare const MIN_RETRYABLE_BATCH_SIZE = 2;
4
4
  export declare const MAX_BATCH_PAYLOAD_BYTES = 500000;
5
+ export declare const SCOPE_FILES_BATCH_SIZE = 50;
6
+ export declare const SYNC_SCAN_PAGE_SIZE = 1000;
7
+ export declare const DELETE_IDS_CHUNK_SIZE = 500;
8
+ export declare const DEFAULT_MAX_ENTITY_REVISIONS = 20;
9
+ export declare const VACUUM_AFTER_PRUNED_ROWS = 5000;
5
10
  export declare const ENTITIES_UPSERT_SET: {
6
11
  organizationId: import("drizzle-orm").SQL<unknown>;
7
12
  projectId: import("drizzle-orm").SQL<unknown>;
@@ -1 +1 @@
1
- import{sql as e}from"drizzle-orm";const t=20,c=1e3,a=2,l=5e5,u={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,type:e`excluded.type`,title:e`excluded.title`,summary:e`excluded.summary`,tags:e`excluded.tags`,metadata:e`excluded.metadata`,git:e`excluded.git`,contact:e`excluded.contact`,links:e`excluded.links`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,hash:e`excluded.hash`,isCurrent:e`excluded.is_current`,isDefaultVersion:e`excluded.is_default_version`,isDeleted:e`excluded.is_deleted`,scorecardsStatus:e`excluded.scorecards_status`,lastSeenRunId:e`excluded.last_seen_run_id`},r={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,targetToSourceRelation:e`excluded.target_to_source_relation`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,isDeleted:e`excluded.is_deleted`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,lastSeenRunId:e`excluded.last_seen_run_id`},_={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,rbacTeams:e`excluded.rbac_teams`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`};export{_ as ATTRIBUTES_UPSERT_SET,t as DEFAULT_CHUNK_SIZE,u as ENTITIES_UPSERT_SET,l as MAX_BATCH_PAYLOAD_BYTES,c as MAX_LOGGED_DB_ERROR_LENGTH,a as MIN_RETRYABLE_BATCH_SIZE,r as RELATIONS_UPSERT_SET};
1
+ import{sql as e}from"drizzle-orm";const t=20,c=1e3,_=2,a=5e5,o=50,l=1e3,u=500,r=20,s=5e3,i={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,type:e`excluded.type`,title:e`excluded.title`,summary:e`excluded.summary`,tags:e`excluded.tags`,metadata:e`excluded.metadata`,git:e`excluded.git`,contact:e`excluded.contact`,links:e`excluded.links`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,hash:e`excluded.hash`,isCurrent:e`excluded.is_current`,isDefaultVersion:e`excluded.is_default_version`,isDeleted:e`excluded.is_deleted`,scorecardsStatus:e`excluded.scorecards_status`,lastSeenRunId:e`excluded.last_seen_run_id`},x={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,targetToSourceRelation:e`excluded.target_to_source_relation`,sourceFile:e`excluded.source_file`,fileHash:e`excluded.file_hash`,isDeleted:e`excluded.is_deleted`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`,lastSeenRunId:e`excluded.last_seen_run_id`},n={organizationId:e`excluded.organization_id`,projectId:e`excluded.project_id`,rbacTeams:e`excluded.rbac_teams`,createdAt:e`excluded.created_at`,updatedAt:e`excluded.updated_at`};export{n as ATTRIBUTES_UPSERT_SET,t as DEFAULT_CHUNK_SIZE,r as DEFAULT_MAX_ENTITY_REVISIONS,u as DELETE_IDS_CHUNK_SIZE,i as ENTITIES_UPSERT_SET,a as MAX_BATCH_PAYLOAD_BYTES,c as MAX_LOGGED_DB_ERROR_LENGTH,_ as MIN_RETRYABLE_BATCH_SIZE,x as RELATIONS_UPSERT_SET,o as SCOPE_FILES_BATCH_SIZE,l as SYNC_SCAN_PAGE_SIZE,s as VACUUM_AFTER_PRUNED_ROWS};
@@ -1,5 +1,5 @@
1
1
  import type { DatabaseEntityAttributesDto } from '../../../../providers/database/databases/sqlite-db/schemas/entities-attributes-table.js';
2
- export declare function createEntityAttributesDbRecord({ rbacTeams, entityKey, organizationId, projectId }: {
2
+ export declare function createEntityAttributesDbRecord({ rbacTeams, entityKey, organizationId, projectId, }: {
3
3
  rbacTeams: string[];
4
4
  entityKey: string;
5
5
  organizationId: string;
@@ -1,6 +1,6 @@
1
1
  import type { EntityBaseFileSchema } from '@redocly/config';
2
2
  import type { DatabaseEntityDto } from '../../../../providers/database/databases/sqlite-db/schemas/entities-table.js';
3
- export declare function createEntityDbRecord({ entity, organizationId, projectId, source, sourceFile, fileHash }: {
3
+ export declare function createEntityDbRecord({ entity, organizationId, projectId, source, sourceFile, fileHash, }: {
4
4
  entity: EntityBaseFileSchema & {
5
5
  id?: string;
6
6
  createdAt?: string;
@@ -10,6 +10,6 @@ type CreateEntityRelationDbRecordFromFileSchemaParams = {
10
10
  organizationId: string;
11
11
  projectId: string;
12
12
  };
13
- export declare function createEntityRelationDbRecordFromFileSchema({ relation, sourceFile, fileHash, sourceKey, sourceVersion, sourceRevision, organizationId, projectId }: CreateEntityRelationDbRecordFromFileSchemaParams): DatabaseEntityRelationDto;
13
+ export declare function createEntityRelationDbRecordFromFileSchema({ relation, sourceFile, fileHash, sourceKey, sourceVersion, sourceRevision, organizationId, projectId, }: CreateEntityRelationDbRecordFromFileSchemaParams): DatabaseEntityRelationDto;
14
14
  export {};
15
15
  //# sourceMappingURL=create-entity-relation-db-record-from-file-schema.d.ts.map
@@ -3,17 +3,17 @@ export declare const INTERNAL_CATALOG_PUBLISH_CACHE_NAMESPACE = "catalog-publish
3
3
  export declare const INTERNAL_CATALOG_PUBLISH_KEY_PREFIX = "catalog-entities::publisher";
4
4
  export declare class RemotePublishLockService {
5
5
  #private;
6
- static getInternalCacheValue({ remoteConnection, key }: {
6
+ static getInternalCacheValue({ remoteConnection, key, }: {
7
7
  remoteConnection: DatabaseConnection;
8
8
  key: string;
9
9
  }): Promise<string | null>;
10
- static upsertInternalCacheValue({ remoteConnection, key, value, ttl }: {
10
+ static upsertInternalCacheValue({ remoteConnection, key, value, ttl, }: {
11
11
  remoteConnection: DatabaseConnection;
12
12
  key: string;
13
13
  value: string;
14
14
  ttl?: number | null;
15
15
  }): Promise<void>;
16
- static runUnderRemotePublishLock<T>({ runId, remoteConnection, run }: {
16
+ static runUnderRemotePublishLock<T>({ runId, remoteConnection, run, }: {
17
17
  runId: string;
18
18
  remoteConnection: DatabaseConnection;
19
19
  run: () => Promise<T>;
@@ -5,13 +5,13 @@ import type { ListResult } from '../types.js';
5
5
  export declare class BffEntitiesReadRepository {
6
6
  #private;
7
7
  constructor(db: DatabaseClient);
8
- getEntitiesWithRelations({ paginationParams, rbacTeams, excludedEntities, excludedTypes }: {
8
+ getEntitiesWithRelations({ paginationParams, rbacTeams, excludedEntities, excludedTypes, }: {
9
9
  paginationParams: PaginationParams;
10
10
  rbacTeams?: string[];
11
11
  excludedEntities?: string[];
12
12
  excludedTypes?: string[];
13
13
  }): Promise<ListResult<BffCatalogEntity>>;
14
- getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities }: {
14
+ getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities, }: {
15
15
  entityKey: string;
16
16
  filter?: {
17
17
  revision?: string | null;
@@ -1 +1 @@
1
- import{logger as o}from"../../../../tools/notifiers/logger.js";import{telemetryTraceStep as i}from"../../../../telemetry/helpers/trace-step.js";import{BaseRepository as a}from"../../../../providers/database/base-repository.js";import{createDatabaseRepositoryInstance as n}from"../../../../providers/database/instance-cache-resolver.js";import{RelationsReadRepository as c}from"./relations/relations-read-repository.js";import{RevisionRepository as p}from"./common/revision-repository.js";import{BffEntitiesReadRepository as l}from"./bffEntities/bff-entities-read-repository.js";import{EntitiesReadRepository as m}from"./entities/entities-read-repository.js";import{EntitiesWriteRepository as y}from"./entities/entities-write-repository.js";import{RelationsWriteRepository as R}from"./relations/relations-write-repository.js";import{FiltersRepository as f}from"./common/filters-repository.js";class r extends a{entitiesRead;entitiesWrite;relationsRead;relationsWrite;bffEntitiesRead;filters;revisions;get transactionsManager(){return this.databaseClient.transactionsManager}constructor(t){super(t),this.revisions=new p(t.client),this.bffEntitiesRead=new l(t.client),this.relationsRead=new c(t.client),this.entitiesRead=new m(t.client),this.entitiesWrite=new y(t.client,this.organizationId,this.projectId),this.relationsWrite=new R(t.client,this.organizationId,this.projectId),this.filters=new f(t.client)}async sync(){return i("catalog_entities.repository.sync",async()=>{await this.databaseClient.sync()})}static async create(t){return await i("catalog_entities.repository.get_instance",async s=>{try{return await n(t,"catalog entities",r)}catch(e){throw o.error("Error creating db connection for catalog entities repository",e),s?.error(e),e}})}}export{r as CatalogEntitiesRepository};
1
+ import{logger as s}from"../../../../tools/notifiers/logger.js";import{telemetryTraceStep as r}from"../../../../telemetry/helpers/trace-step.js";import{BaseRepository as a}from"../../../../providers/database/base-repository.js";import{createDatabaseRepositoryInstance as n}from"../../../../providers/database/instance-cache-resolver.js";import{RelationsReadRepository as c}from"./relations/relations-read-repository.js";import{RevisionRepository as l}from"./common/revision-repository.js";import{BffEntitiesReadRepository as p}from"./bffEntities/bff-entities-read-repository.js";import{EntitiesReadRepository as y}from"./entities/entities-read-repository.js";import{EntitiesWriteRepository as R}from"./entities/entities-write-repository.js";import{RelationsWriteRepository as m}from"./relations/relations-write-repository.js";import{FiltersRepository as g}from"./common/filters-repository.js";class o extends a{entitiesRead;entitiesWrite;relationsRead;relationsWrite;bffEntitiesRead;filters;revisions;get transactionsManager(){return this.databaseClient.transactionsManager}constructor(t){super(t),this.revisions=new l(t.client),this.bffEntitiesRead=new p(t.client),this.relationsRead=new c(t.client),this.entitiesRead=new y(t.client),this.entitiesWrite=new R(t.client,this.organizationId,this.projectId),this.relationsWrite=new m(t.client,this.organizationId,this.projectId),this.filters=new g(t.client)}async sync(){return r("com.redocly.catalogEntities.repository.sync",async t=>{t?.setAttribute("id","catalogEntitiesRepositoryId"),t?.setAttribute("object","catalogEntitiesRepository"),t?.setAttribute("uri","urn:redocly:realm:api:catalogEntitiesRepository:catalogEntitiesRepositoryId"),await this.databaseClient.sync()})}static async create(t){return await r("com.redocly.catalogEntities.repository.getInstance",async i=>{i?.setAttribute("id","catalogEntitiesRepositoryId"),i?.setAttribute("object","catalogEntitiesRepository"),i?.setAttribute("uri","urn:redocly:realm:api:catalogEntitiesRepository:catalogEntitiesRepositoryId");try{return await n(t,"catalog entities",o)}catch(e){throw s.error("Error creating db connection for catalog entities repository",e),i?.error(e),e}})}}export{o as CatalogEntitiesRepository};
@@ -3,6 +3,6 @@ import type { CatalogFiltersParams, FilterOption } from '../types.js';
3
3
  export declare class FiltersRepository {
4
4
  #private;
5
5
  constructor(db: DatabaseClient);
6
- getCatalogFilters({ entitiesTypes, emptyFilters, rbacTeams, excludedTypes, excludedEntities }: CatalogFiltersParams): Promise<Record<string, FilterOption[]>>;
6
+ getCatalogFilters({ entitiesTypes, emptyFilters, rbacTeams, excludedTypes, excludedEntities, }: CatalogFiltersParams): Promise<Record<string, FilterOption[]>>;
7
7
  }
8
8
  //# sourceMappingURL=filters-repository.d.ts.map
@@ -3,7 +3,7 @@ import type { EntityRevisionSummary } from '../../../schemas/read-model-schemas.
3
3
  export declare class RevisionRepository {
4
4
  #private;
5
5
  constructor(db: DatabaseClient);
6
- getCurrentRevisionInfo({ key, version, revision }: {
6
+ getCurrentRevisionInfo({ key, version, revision, }: {
7
7
  key: string;
8
8
  version: string | null;
9
9
  revision: string | null;
@@ -7,7 +7,7 @@ import type { GetEntityByIdParams } from '../../../types/params';
7
7
  export declare class EntitiesReadRepository {
8
8
  #private;
9
9
  constructor(db: DatabaseClient);
10
- getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
10
+ getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
11
11
  paginationParams: PaginationParams;
12
12
  rbacTeams?: string[];
13
13
  excludedTypes?: string[];
@@ -7,10 +7,10 @@ import type { ScorecardsStatus } from '../../../entities/types';
7
7
  export declare class EntitiesWriteRepository {
8
8
  #private;
9
9
  constructor(db: DatabaseClient, organizationId: string, projectId: string);
10
- createEntity({ entity, source, fileHash, sourceFile, isRootEntity, isDeleted, rbacTeams, errorOnSkip, revision }: CreateEntityParams): Promise<EntityReadModelSchema | null>;
10
+ createEntity({ entity, source, fileHash, sourceFile, isRootEntity, isDeleted, rbacTeams, errorOnSkip, revision, }: CreateEntityParams): Promise<EntityReadModelSchema | null>;
11
11
  updateEntity(incomingEntity: Partial<EntityDtoSchema>, entityToBeUpdated: EntityReadModelSchema): Promise<EntityReadModelSchema | null>;
12
12
  setEntitiesAsOutdated(filter: Filter): Promise<void>;
13
- softDeleteEntitiesWithRelations({ filter, revision, fileHash }: {
13
+ softDeleteEntitiesWithRelations({ filter, revision, fileHash, }: {
14
14
  filter: Filter;
15
15
  revision: string;
16
16
  fileHash: string;
@@ -1 +1 @@
1
- import{and as v,eq as c,isNull as E,or as T,sql as N}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as I}from"@redocly/theme/core/constants";import{sha1 as V}from"../../../../../utils/crypto/sha1.js";import{envConfig as F}from"../../../../../config/env-config.js";import{entitiesTable as i}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{convertFilterToWhereCondition as K}from"../../../../../providers/database/pagination/filter.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{RevisionRepository as x}from"../common/revision-repository.js";import{VersionRepository as z}from"../common/version-repository.js";import{EntityAttributesWriteRepository as H}from"../entityAttributes/entity-attributes-write-repository.js";import{createEntityDbRecord as O}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as k}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromFileSchema as P}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{createEntityRelationDbRecordFromDto as j}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{EntitiesReadRepository as G}from"./entities-read-repository.js";import{RelationsReadRepository as M}from"../relations/relations-read-repository.js";import{RelationsWriteRepository as $}from"../relations/relations-write-repository.js";const m=15;class ce{#e;#t;#n;#o;#i;#s;#a;#u;#r;constructor(e,s,r){this.#e=e,this.#i=s,this.#s=r,this.#t=new x(e),this.#n=new z(e),this.#o=new H(e),this.#a=new G(e),this.#u=new M(e),this.#r=new $(e,s,r)}async createEntity({entity:e,source:s,fileHash:r,sourceFile:o,isRootEntity:t,isDeleted:n,rbacTeams:l,errorOnSkip:d=!1,revision:h}){const{relations:u=[],...f}=e,y=V(JSON.stringify(f)),R=e.version??I,C=h??new Date().toISOString(),W=await this.#t.shouldSkipRevisionCreation(e.key,R,y,t,n);if(Array.isArray(l)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:l,organizationId:this.#i,projectId:this.#s}),W){if(d)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:g,hasCurrentRevision:L}=await this.#t.getCurrentRevisionInfo({key:e.key,version:R,revision:C}),w=O({entity:{...e,revision:C,hash:y,isCurrent:g,isDefaultVersion:g,isDeleted:n,version:R},organizationId:this.#i,projectId:this.#s,source:s,sourceFile:o??null,fileHash:r??null}),{key:D,..._}=w;if(g&&L&&(await this.#t.markAllRevisionsAsNotCurrent(D),await this.#n.markAllVersionsAsNotDefault(D)),F.isDevelopMode&&!F.REDOCLY_INTERNAL_DEV)return await this.#l(w,u);const A=await this.#e.client.insert(i).values(w).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:_}).returning();return A.length?(u&&await this.#r.createEntityRelations(u.map(S=>({...S,sourceKey:e.key,targetKey:S.key}))),k(A[0])):null}async updateEntity(e,s){const{shouldSetNewCurrentRevision:r,hasCurrentRevision:o}=await this.#t.getCurrentRevisionInfo({key:s.key,version:e.version??s.version??I,revision:s.revision});r&&o&&(await this.#t.markAllRevisionsAsNotCurrent(s.key),await this.#n.markAllVersionsAsNotDefault(s.key));const t=O({entity:{...s,...e,hash:V(JSON.stringify({...s,...e})),isCurrent:r,isDefaultVersion:r,createdAt:s.createdAt??void 0},organizationId:this.#i,projectId:this.#s,source:"remote",sourceFile:null,fileHash:null}),{key:n,source:l,scorecardsStatus:d,...h}=t,u=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...h,scorecardsStatus:N`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return u.length?k(u[0]):null}async setEntitiesAsOutdated(e){const s=K(e);await this.#e.client.update(i).set({scorecardsStatus:"OUTDATED"}).where(s)}async#l(e,s){const{key:r,source:o,version:t,...n}=e,h=await this.#e.client.select({id:i.id}).from(i).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(n).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:n}).returning(),u=s?.map(f=>{const y=P({relation:f,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#i,projectId:this.#s});return this.#e.client.insert(a).values(y).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:y}).run()})??[];return await p(u,m,async f=>f),k(h[0])}async softDeleteEntitiesWithRelations({filter:e,revision:s,fileHash:r}){const t={op:"AND",conditions:[e,{field:"is_deleted",operator:"equal",value:!1}]};for(;;){const n=await this.#a.getEntities({paginationParams:{filter:t,limit:500}});if(n.items.length===0)break;const l=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(l,s)}}async deleteEntity(e){return await this.#r.deleteEntityRelationsOnEntityRemoval(e),await this.#e.client.delete(i).where(c(i.id,e.id)),await this.#t.ensureDefaultAndCurrentRevisionForKey(e.key),e.id}async deleteEntities(e){const s=K(e);if(!s)return!1;const r=await this.#e.client.delete(i).where(s).returning({key:i.key,source:i.source,isCurrent:i.isCurrent,isDefaultVersion:i.isDefaultVersion,version:i.version});if(r.length===0)return!0;const o=r.reduce((t,n)=>((n.isCurrent||n.isDefaultVersion)&&t.add(n.key),t),new Set);if(o.size===0)return!0;await p(Array.from(o),m,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(T(v(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[E(a.sourceVersion)]),v(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[E(a.targetVersion)])));return!0}async updateEntityScorecardsStatus(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(c(i.id,e)).returning()).length>0}async updateEntityScorecardsStatusIfCalculating(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(N`${i.id} = ${e} AND ${i.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}async#c({entities:e,revision:s,fileHash:r}){return(await p(e,m,async t=>{const n={type:t.type,key:t.key,title:t.title,summary:t.summary??void 0,tags:t.tags??void 0,metadata:t.metadata??void 0,git:t.git??void 0,contact:t.contact??void 0,links:t.links??void 0,version:t.version??void 0};return this.createEntity({entity:n,sourceFile:t.sourceFile??"",fileHash:r,isDeleted:!0,errorOnSkip:!1,source:t.source,revision:s})})).filter(t=>t!==null)}async#d(e,s){if(e.length===0)return!0;const r=await p(e,m,async o=>(await this.#u.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const l=n.direction,d=n.sourceToTargetRelation,h=n.targetKey,u=l==="outgoing"?o.key:h,f=l==="outgoing"?h:o.key,y=l==="outgoing"?d:d.startsWith("reverse:")?d.slice(8):d;return!y||!u||!f?null:j({type:y,sourceKey:u,targetKey:f,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await p(r.flat(),m,async o=>this.#r.upsertEntityRelation(o)),!0}}export{ce as EntitiesWriteRepository};
1
+ import{and as v,eq as c,isNull as E,or as x,sql as I}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as V}from"@redocly/theme/core/constants";import{sha1 as F}from"../../../../../utils/crypto/sha1.js";import{envConfig as K}from"../../../../../config/env-config.js";import{entitiesTable as i}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{convertFilterToWhereCondition as O}from"../../../../../providers/database/pagination/filter.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{RevisionRepository as z}from"../common/revision-repository.js";import{VersionRepository as H}from"../common/version-repository.js";import{EntityAttributesWriteRepository as P}from"../entityAttributes/entity-attributes-write-repository.js";import{createEntityDbRecord as W}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as k}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromFileSchema as j}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{createEntityRelationDbRecordFromDto as G}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{EntitiesReadRepository as M}from"./entities-read-repository.js";import{RelationsReadRepository as U}from"../relations/relations-read-repository.js";import{RelationsWriteRepository as $}from"../relations/relations-write-repository.js";const m=15;class de{#e;#t;#n;#o;#i;#s;#a;#l;#r;constructor(e,s,r){this.#e=e,this.#i=s,this.#s=r,this.#t=new z(e),this.#n=new H(e),this.#o=new P(e),this.#a=new M(e),this.#l=new U(e),this.#r=new $(e,s,r)}async createEntity({entity:e,source:s,fileHash:r,sourceFile:o,isRootEntity:t,isDeleted:n,rbacTeams:u,errorOnSkip:d=!1,revision:h}){const{relations:l=[],...f}=e,y=F(JSON.stringify(f)),g=e.version??V,C=h??new Date().toISOString(),L=await this.#t.shouldSkipRevisionCreation(e.key,g,y,t,n);Array.isArray(u)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:u,organizationId:this.#i,projectId:this.#s});const D=K.isDevelopMode&&!K.REDOCLY_INTERNAL_DEV;if(l?.length&&!D&&await this.#r.createEntityRelations(l.map(N=>({...N,sourceKey:e.key,targetKey:N.key,sourceFile:o??null,fileHash:r??null}))),L){if(d)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:R,hasCurrentRevision:_}=await this.#t.getCurrentRevisionInfo({key:e.key,version:g,revision:C}),w=W({entity:{...e,revision:C,hash:y,isCurrent:R,isDefaultVersion:R,isDeleted:n,version:g},organizationId:this.#i,projectId:this.#s,source:s,sourceFile:o??null,fileHash:r??null}),{key:A,...T}=w;if(R&&_&&(await this.#t.markAllRevisionsAsNotCurrent(A),await this.#n.markAllVersionsAsNotDefault(A)),D)return await this.#u(w,l);const S=await this.#e.client.insert(i).values(w).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:T}).returning();return S.length?k(S[0]):null}async updateEntity(e,s){const{shouldSetNewCurrentRevision:r,hasCurrentRevision:o}=await this.#t.getCurrentRevisionInfo({key:s.key,version:e.version??s.version??V,revision:s.revision});r&&o&&(await this.#t.markAllRevisionsAsNotCurrent(s.key),await this.#n.markAllVersionsAsNotDefault(s.key));const t=W({entity:{...s,...e,hash:F(JSON.stringify({...s,...e})),isCurrent:r,isDefaultVersion:r,createdAt:s.createdAt??void 0},organizationId:this.#i,projectId:this.#s,source:"remote",sourceFile:null,fileHash:null}),{key:n,source:u,scorecardsStatus:d,...h}=t,l=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...h,scorecardsStatus:I`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return l.length?k(l[0]):null}async setEntitiesAsOutdated(e){const s=O(e);await this.#e.client.update(i).set({scorecardsStatus:"OUTDATED"}).where(s)}async#u(e,s){const{key:r,source:o,version:t,...n}=e,h=await this.#e.client.select({id:i.id}).from(i).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(n).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:n}).returning(),l=s?.map(f=>{const y=j({relation:f,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#i,projectId:this.#s});return this.#e.client.insert(a).values(y).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:y}).run()})??[];return await p(l,m,async f=>f),k(h[0])}async softDeleteEntitiesWithRelations({filter:e,revision:s,fileHash:r}){const t={op:"AND",conditions:[e,{field:"is_deleted",operator:"equal",value:!1}]};for(;;){const n=await this.#a.getEntities({paginationParams:{filter:t,limit:500}});if(n.items.length===0)break;const u=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(u,s)}}async deleteEntity(e){return await this.#r.deleteEntityRelationsOnEntityRemoval(e),await this.#e.client.delete(i).where(c(i.id,e.id)),await this.#t.ensureDefaultAndCurrentRevisionForKey(e.key),e.id}async deleteEntities(e){const s=O(e);if(!s)return!1;const r=await this.#e.client.delete(i).where(s).returning({key:i.key,source:i.source,isCurrent:i.isCurrent,isDefaultVersion:i.isDefaultVersion,version:i.version});if(r.length===0)return!0;const o=r.reduce((t,n)=>((n.isCurrent||n.isDefaultVersion)&&t.add(n.key),t),new Set);if(o.size===0)return!0;await p(Array.from(o),m,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(x(v(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[E(a.sourceVersion)]),v(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[E(a.targetVersion)])));return!0}async updateEntityScorecardsStatus(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(c(i.id,e)).returning()).length>0}async updateEntityScorecardsStatusIfCalculating(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(I`${i.id} = ${e} AND ${i.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}async#c({entities:e,revision:s,fileHash:r}){return(await p(e,m,async t=>{const n={type:t.type,key:t.key,title:t.title,summary:t.summary??void 0,tags:t.tags??void 0,metadata:t.metadata??void 0,git:t.git??void 0,contact:t.contact??void 0,links:t.links??void 0,version:t.version??void 0};return this.createEntity({entity:n,sourceFile:t.sourceFile??"",fileHash:r,isDeleted:!0,errorOnSkip:!1,source:t.source,revision:s})})).filter(t=>t!==null)}async#d(e,s){if(e.length===0)return!0;const r=await p(e,m,async o=>(await this.#l.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const u=n.direction,d=n.sourceToTargetRelation,h=n.targetKey,l=u==="outgoing"?o.key:h,f=u==="outgoing"?h:o.key,y=u==="outgoing"?d:d.startsWith("reverse:")?d.slice(8):d;return!y||!l||!f?null:G({type:y,sourceKey:l,targetKey:f,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await p(r.flat(),m,async o=>this.#r.upsertEntityRelation(o)),!0}}export{de as EntitiesWriteRepository};
@@ -2,7 +2,7 @@ import type { DatabaseClient } from '../../../../../providers/database/client.js
2
2
  export declare class EntityAttributesWriteRepository {
3
3
  #private;
4
4
  constructor(db: DatabaseClient);
5
- upsertEntityAttributes({ entityKey, rbacTeams, organizationId, projectId }: {
5
+ upsertEntityAttributes({ entityKey, rbacTeams, organizationId, projectId, }: {
6
6
  entityKey: string;
7
7
  rbacTeams: string[];
8
8
  organizationId: string;
@@ -13,7 +13,7 @@ export declare class RelationsReadRepository {
13
13
  direction: 'outgoing' | 'incoming';
14
14
  priority: number;
15
15
  }[]>;
16
- getRelatedEntities({ key, paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
16
+ getRelatedEntities({ key, paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
17
17
  key: string;
18
18
  paginationParams: PaginationParams;
19
19
  rbacTeams?: string[];
@@ -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};
@@ -5,7 +5,9 @@ import type { FileType } from '../../../../../persistence/file-hashes/types.js';
5
5
  import type { HashManager } from '../../../utils/hash-manager.js';
6
6
  import type { BaseApiEntitiesExtractorParams, SpecType } from '../../../types/extractors.js';
7
7
  import type { EntityDtoSchema } from '../../../schemas/dto-schemas.js';
8
- export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition extends Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'>> implements BaseEntitiesExtractor {
8
+ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition extends Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'> & {
9
+ definition?: unknown;
10
+ }> implements BaseEntitiesExtractor {
9
11
  #private;
10
12
  protected type: 'api-description';
11
13
  protected specType: SpecType;
@@ -16,6 +18,7 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
16
18
  protected fileHashManager: HashManager;
17
19
  protected entitySources: Record<string, string>;
18
20
  constructor(specType: SpecType, params: BaseApiEntitiesExtractorParams);
21
+ protected getDescriptionHash(description: BundledApiDefinition): string | undefined;
19
22
  extract(): Promise<void>;
20
23
  protected validateEntityRelationFileSchema(relation: unknown): void;
21
24
  protected getRbacTeamsForDefinition(relativePath: string): string[];
@@ -26,7 +29,7 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
26
29
  * @param customKey - Optional custom key from x-redocly-catalog-key
27
30
  * @param extensionPattern - Optional regex to strip file extension (default: any extension)
28
31
  */
29
- protected resolveEntityKey({ realRelativePath, customKey, extensionPattern }: {
32
+ protected resolveEntityKey({ realRelativePath, customKey, extensionPattern, }: {
30
33
  realRelativePath: string;
31
34
  customKey?: string | null;
32
35
  extensionPattern?: RegExp;
@@ -1 +1 @@
1
- import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";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 F}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as S}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as D}from"../../../utils/ajv-validator.js";const H=15,C=200,O=500;class z{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(i,e){this.specType=i,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}async extract(){const i=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),i.length&&p.addExtractor(this.specType);const a=this.#s(i),t={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},o=[],r=new Set;await w(Array.from(a.values()),H,async c=>{for(const{description:s,version:l}of c)try{const n=s.hash;if(!n)continue;r.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),E=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:E});if(!(f!==null)){t.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&t[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 y=new Date().toISOString();await this.processApiDescription(s,y,l,d),(m||E||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#r(d,s.realRelativePath,y,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:i,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return i?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async i=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(i).map(e=>e.split(":")[0])}),i.clear())};#t=async i=>{let e=0,a=0;for(;;){const t=await this.catalogEntitiesService.getEntities({paginationParams:{limit:O,filter:i}});if(!t||t.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:t.items.map(({id:o})=>o)}),e+=t.items.length,a+=1}return{total:e,pages:a}};#s(i){const e=new Map;for(const a of i)if(!(a.isVirtual||!a.hash))try{const t=this.#n(a),o=this.mapApiDescriptionToEntity(a,t),r=e.get(o.key)??[];r.push({description:a,version:t}),e.set(o.key,r)}catch(t){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(t)}return e}#o=async i=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!i.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const t=a.map(({filePath:l})=>l),{total:o,pages:r}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:t},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:t});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${t.length} currentRevisionsDeleted=${o} currentPages=${r} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${t.slice(0,3).join(", ")}${t.length>3?`, +${t.length-3} more`:""}`)};#r=async(i,e,a,t)=>{if(i.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const o=Array.from(i).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:t,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(i){const e=i.document?.info?.version??i.definition?.info?.version??null,a=S(e,i.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(i){D(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(i)}getRbacTeamsForDefinition(i){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(i);return F(a||{fsPath:i},e||{})}resolveEntityKey({realRelativePath:i,customKey:e,extensionPattern:a}){const t=this.#l(i,a);return typeof e=="string"&&e.trim()?R(e.trim()):t}#l(i,e){let t=_(i);for(;/^@[^/]+\//.test(t);)t=t.replace(/^@[^/]+\//,"");t=t.replace(/\/@[^/]+/g,"");const o=e?t.replace(e,""):t.replace(/\.[^.]+$/,"");return R(o.replace(/[\\/]/g,"-"))}}export{z 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};