@redocly/realm 0.129.0-next.1 → 0.129.0-next.3

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 (303) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/develop.d.ts +1 -1
  4. package/dist/cli/develop.js +1 -1
  5. package/dist/cli/prepare/analytics/collectors/get-file-extensions-usage.js +1 -1
  6. package/dist/cli/prepare/analytics/collectors/get-frontmatter-usage.js +1 -1
  7. package/dist/cli/prepare/analytics/collectors/get-markdoc-usage.js +1 -1
  8. package/dist/cli/prepare/analytics/collectors/get-nested-configs-usage.js +1 -1
  9. package/dist/cli/prepare/analytics/collectors/get-refs-usage.js +1 -1
  10. package/dist/cli/prepare/index.d.ts +1 -1
  11. package/dist/cli/translations/collect-config-translations.js +1 -1
  12. package/dist/cli/translations/update-translations.js +1 -1
  13. package/dist/client/TestProvider.js +1 -1
  14. package/dist/client/app/Sidebar/RequestAccessButton.js +2 -2
  15. package/dist/client/app/Sidebar/Sidebar.js +7 -2
  16. package/dist/client/app/Sidebar/useSidebarItems.d.ts +1 -0
  17. package/dist/client/app/Sidebar/useSidebarItems.js +1 -1
  18. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.js +1 -1
  19. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.js +1 -1
  20. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.d.ts +10 -0
  21. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.js +1 -0
  22. package/dist/client/app/hooks/index.d.ts +1 -0
  23. package/dist/client/app/hooks/index.js +1 -1
  24. package/dist/client/app/hooks/useBanner.d.ts +4 -0
  25. package/dist/client/app/hooks/useBanner.js +1 -1
  26. package/dist/client/app/hooks/useLoginUrl.js +1 -1
  27. package/dist/client/app/pages/DevLogin/DevLogin.js +1 -1
  28. package/dist/client/app/pages/Login/Login.js +1 -1
  29. package/dist/client/app/utils/loadAndNavigate.js +1 -1
  30. package/dist/client/browser-entry.js +2 -2
  31. package/dist/client/providers/page-data/hooks.d.ts +2 -1
  32. package/dist/client/providers/page-data/hooks.js +1 -1
  33. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  34. package/dist/client/runtime/loader.js +1 -1
  35. package/dist/client/types/post-message.d.ts +2 -1
  36. package/dist/client/utils/catalog/inject-catalog-items.d.ts +1 -1
  37. package/dist/client/utils/catalog/inject-catalog-items.js +1 -1
  38. package/dist/constants/common.d.ts +0 -4
  39. package/dist/constants/common.js +1 -1
  40. package/dist/constants/l10n/langs/ar.js +1 -1
  41. package/dist/constants/l10n/langs/de.js +1 -1
  42. package/dist/constants/l10n/langs/en.js +1 -1
  43. package/dist/constants/l10n/langs/es.js +1 -1
  44. package/dist/constants/l10n/langs/fr.js +1 -1
  45. package/dist/constants/l10n/langs/hi.js +1 -1
  46. package/dist/constants/l10n/langs/it.js +1 -1
  47. package/dist/constants/l10n/langs/ja.js +1 -1
  48. package/dist/constants/l10n/langs/ko.js +1 -1
  49. package/dist/constants/l10n/langs/pl.js +1 -1
  50. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  51. package/dist/constants/l10n/langs/pt.js +1 -1
  52. package/dist/constants/l10n/langs/ru.js +1 -1
  53. package/dist/constants/l10n/langs/uk.js +1 -1
  54. package/dist/constants/l10n/langs/zh.js +1 -1
  55. package/dist/server/api-routes/execute-api-route.d.ts +0 -7
  56. package/dist/server/api-routes/execute-api-route.js +1 -1
  57. package/dist/server/api-routes/helpers/setup-logger.d.ts +2 -2
  58. package/dist/server/api-routes/helpers/setup-logger.js +1 -1
  59. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  60. package/dist/server/fs/cache.d.ts +1 -2
  61. package/dist/server/fs/cache.js +1 -1
  62. package/dist/server/fs/content-fs.d.ts +9 -4
  63. package/dist/server/fs/content-fs.js +1 -1
  64. package/dist/server/fs/fs.d.ts +6 -6
  65. package/dist/server/fs/fs.js +1 -3
  66. package/dist/server/fs/load-error.d.ts +2 -2
  67. package/dist/server/fs/load-error.js +1 -1
  68. package/dist/server/fs/utils/async-storage.d.ts +0 -8
  69. package/dist/server/fs/utils/async-storage.js +1 -1
  70. package/dist/server/fs/utils/isVirtualFile.d.ts +1 -1
  71. package/dist/server/fs/utils/isVirtualFile.js +1 -1
  72. package/dist/server/persistence/kv/helpers/decode-cursor.d.ts +2 -0
  73. package/dist/server/persistence/kv/helpers/decode-cursor.js +1 -0
  74. package/dist/server/persistence/kv/helpers/encode-cursor.d.ts +2 -0
  75. package/dist/server/persistence/kv/helpers/encode-cursor.js +1 -0
  76. package/dist/server/persistence/kv/mappers/create-kv-list-entry.d.ts +5 -0
  77. package/dist/server/persistence/kv/mappers/create-kv-list-entry.js +1 -0
  78. package/dist/server/persistence/kv/mappers/create-kv-value.d.ts +4 -0
  79. package/dist/server/persistence/kv/mappers/create-kv-value.js +1 -0
  80. package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +5 -5
  81. package/dist/server/persistence/kv/repositories/kv-remote-repository.js +1 -1
  82. package/dist/server/persistence/kv/schemas/kv-schemas.d.ts +10 -0
  83. package/dist/server/persistence/kv/schemas/kv-schemas.js +1 -0
  84. package/dist/server/persistence/kv/services/kv-service.d.ts +6 -6
  85. package/dist/server/persistence/kv/services/kv-service.js +1 -1
  86. package/dist/server/plugins/api-functions/index.js +1 -1
  87. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.d.ts +1 -1
  88. package/dist/server/plugins/arazzo-docs/arazzo-doc-loader.js +2 -2
  89. package/dist/server/plugins/arazzo-docs/index.d.ts +1 -1
  90. package/dist/server/plugins/arazzo-docs/index.js +1 -1
  91. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.d.ts +1 -1
  92. package/dist/server/plugins/asyncapi-docs/asyncapi-doc-loader.js +2 -2
  93. package/dist/server/plugins/asyncapi-docs/index.d.ts +1 -1
  94. package/dist/server/plugins/asyncapi-docs/index.js +1 -1
  95. package/dist/server/plugins/asyncapi-docs/is-asyncapi-doc.js +1 -1
  96. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +23 -18
  97. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  98. package/dist/server/plugins/catalog-entities/database/mappers/create-bff-entity.js +1 -1
  99. package/dist/server/plugins/catalog-entities/database/mappers/create-bff-related-entity.d.ts +9 -0
  100. package/dist/server/plugins/catalog-entities/database/mappers/create-bff-related-entity.js +1 -1
  101. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.d.ts +1 -0
  102. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.js +1 -1
  103. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-read-model.js +1 -1
  104. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-dto.js +1 -1
  105. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-file-schema.js +1 -1
  106. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation.js +1 -1
  107. package/dist/server/plugins/catalog-entities/database/mappers/map-entity-relation-row.d.ts +12 -0
  108. package/dist/server/plugins/catalog-entities/database/mappers/map-entity-relation-row.js +1 -0
  109. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +15 -4
  110. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +67 -55
  111. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +21 -15
  112. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  113. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.d.ts +16 -3
  114. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  115. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.d.ts +17 -0
  116. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -0
  117. package/dist/server/plugins/catalog-entities/database/repositories/utils.d.ts +4 -4
  118. package/dist/server/plugins/catalog-entities/database/repositories/utils.js +1 -1
  119. package/dist/server/plugins/catalog-entities/entities/{extract-entities-content.d.ts → extract-file-content.d.ts} +1 -1
  120. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.d.ts +2 -2
  121. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  122. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +2 -2
  123. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  124. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +2 -2
  125. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  126. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +2 -2
  127. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  128. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +2 -2
  129. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  130. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
  131. package/dist/server/plugins/catalog-entities/get-server-props.d.ts +1 -2
  132. package/dist/server/plugins/catalog-entities/get-server-props.js +1 -1
  133. package/dist/server/plugins/catalog-entities/schemas/database-schemas.d.ts +64 -0
  134. package/dist/server/plugins/catalog-entities/schemas/database-schemas.js +1 -1
  135. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.d.ts +6 -12
  136. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.js +1 -1
  137. package/dist/server/plugins/catalog-entities/schemas/read-model-schemas.d.ts +4 -8
  138. package/dist/server/plugins/catalog-entities/schemas/read-model-schemas.js +1 -1
  139. package/dist/server/plugins/catalog-entities/utils/catalog-data-collector.js +1 -1
  140. package/dist/server/plugins/catalog-entities/utils/read-string.d.ts +7 -0
  141. package/dist/server/plugins/catalog-entities/utils/read-string.js +1 -0
  142. package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
  143. package/dist/server/plugins/config-parser/loaders/nearest-redocly-config-loader.js +1 -1
  144. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  145. package/dist/server/plugins/config-parser/loaders/yaml-parser.js +1 -1
  146. package/dist/server/plugins/default-theme/resolve-products-config.js +1 -1
  147. package/dist/server/plugins/ensure-frontmatter-theme-compatibility.js +1 -1
  148. package/dist/server/plugins/entitlements/index.js +1 -1
  149. package/dist/server/plugins/graphql-docs/index.js +1 -1
  150. package/dist/server/plugins/l10n/index.js +1 -1
  151. package/dist/server/plugins/lifecycle.js +2 -2
  152. package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/filesets-resolver.js +1 -1
  153. package/dist/server/plugins/markdown/attribute-resolvers/helpers/dereference-json-schema-refs.d.ts +14 -0
  154. package/dist/server/plugins/markdown/attribute-resolvers/helpers/dereference-json-schema-refs.js +1 -0
  155. package/dist/server/plugins/markdown/attribute-resolvers/helpers/generate-sample-from-schema.d.ts +62 -0
  156. package/dist/server/plugins/markdown/attribute-resolvers/helpers/generate-sample-from-schema.js +2 -0
  157. package/dist/server/plugins/markdown/attribute-resolvers/index.js +1 -1
  158. package/dist/server/plugins/markdown/attribute-resolvers/resolve-code-snippet-from-file.js +1 -1
  159. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.d.ts +4 -0
  160. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -0
  161. package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-schema-ref.js +1 -1
  162. package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.d.ts +1 -1
  163. package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
  164. package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
  165. package/dist/server/plugins/markdown/attribute-resolvers/resolve-parsed-yaml.js +1 -1
  166. package/dist/server/plugins/markdown/attribute-resolvers/resolve-raw-content.js +1 -1
  167. package/dist/server/plugins/markdown/attribute-resolvers/resolve-sample-from-json-schema.d.ts +4 -0
  168. package/dist/server/plugins/markdown/attribute-resolvers/resolve-sample-from-json-schema.js +1 -0
  169. package/dist/server/plugins/markdown/attribute-resolvers/resolve-svg-content.js +1 -1
  170. package/dist/server/plugins/markdown/compiler.js +1 -1
  171. package/dist/server/plugins/markdown/get-server-props.js +1 -1
  172. package/dist/server/plugins/markdown/index.js +1 -1
  173. package/dist/server/plugins/markdown/markdoc/attributes/index.d.ts +2 -0
  174. package/dist/server/plugins/markdown/markdoc/attributes/index.js +1 -1
  175. package/dist/server/plugins/markdown/markdoc/attributes/json-example-ref.d.ts +6 -0
  176. package/dist/server/plugins/markdown/markdoc/attributes/json-example-ref.js +1 -0
  177. package/dist/server/plugins/markdown/markdoc/attributes/sample-from-json-schema.d.ts +6 -0
  178. package/dist/server/plugins/markdown/markdoc/attributes/sample-from-json-schema.js +1 -0
  179. package/dist/server/plugins/markdown/markdoc/custom-components/openapi/index.d.ts +1 -0
  180. package/dist/server/plugins/markdown/markdoc/custom-components/openapi/index.js +1 -1
  181. package/dist/server/plugins/markdown/markdoc/custom-components/openapi/json-example.d.ts +8 -0
  182. package/dist/server/plugins/markdown/markdoc/custom-components/openapi/json-example.js +7 -0
  183. package/dist/server/plugins/markdown/markdoc/partials.js +1 -1
  184. package/dist/server/plugins/markdown/markdoc/resolve-raw-partials.js +1 -1
  185. package/dist/server/plugins/markdown/markdoc/tags/index.d.ts +4 -0
  186. package/dist/server/plugins/markdown/markdoc/tags/index.js +1 -1
  187. package/dist/server/plugins/markdown/markdoc/tags/json-example.d.ts +3 -0
  188. package/dist/server/plugins/markdown/markdoc/tags/json-example.js +1 -0
  189. package/dist/server/plugins/markdown/markdown-static-data-loader.js +1 -1
  190. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +1 -1
  191. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  192. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +7 -2
  193. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
  194. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.d.ts +7 -2
  195. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
  196. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.d.ts +7 -2
  197. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
  198. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.d.ts +7 -2
  199. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
  200. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +4 -3
  201. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  202. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +5 -2
  203. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.js +1 -1
  204. package/dist/server/plugins/mcp/docs-mcp/tools/utils.d.ts +6 -0
  205. package/dist/server/plugins/mcp/docs-mcp/tools/utils.js +6 -6
  206. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.js +1 -1
  207. package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +3 -3
  208. package/dist/server/plugins/mcp/docs-mcp/utils.js +1 -1
  209. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  210. package/dist/server/plugins/mcp/index.js +1 -1
  211. package/dist/server/plugins/mcp/servers/docs-server.d.ts +10 -3
  212. package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
  213. package/dist/server/plugins/mcp/types.d.ts +26 -2
  214. package/dist/server/plugins/mcp/utils.d.ts +9 -8
  215. package/dist/server/plugins/mcp/utils.js +1 -1
  216. package/dist/server/plugins/mcp/workers/run-api-routes-worker.js +1 -1
  217. package/dist/server/plugins/nav-utils.js +1 -1
  218. package/dist/server/plugins/openapi-docs/decorators.d.ts +3 -2
  219. package/dist/server/plugins/openapi-docs/decorators.js +1 -1
  220. package/dist/server/plugins/openapi-docs/index.d.ts +2 -2
  221. package/dist/server/plugins/openapi-docs/index.js +1 -1
  222. package/dist/server/plugins/openapi-docs/is-openapi-doc.js +1 -1
  223. package/dist/server/plugins/openapi-docs/load-definition.d.ts +1 -1
  224. package/dist/server/plugins/openapi-docs/load-definition.js +3 -3
  225. package/dist/server/plugins/pages/index.js +1 -1
  226. package/dist/server/plugins/scorecard-classic/get-scorecard-config.d.ts +11 -0
  227. package/dist/server/plugins/scorecard-classic/loaders/scorecard.js +1 -1
  228. package/dist/server/plugins/search/llmstxt/index.js +5 -5
  229. package/dist/server/plugins/sidebars/index.js +3 -3
  230. package/dist/server/plugins/utils.js +1 -1
  231. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0003_catalog_versions_and_revisions_relations.sql +40 -0
  232. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0003_snapshot.json +392 -0
  233. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/_journal.json +7 -0
  234. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-relations-table.d.ts +25 -46
  235. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js +1 -1
  236. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-table.d.ts +20 -3
  237. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-table.js +1 -1
  238. package/dist/server/providers/database/databases/main-sqlite/migrations/meta/0005_snapshot.json +263 -0
  239. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0006_catalog-versions-and-revisions-relations.sql +40 -0
  240. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0005_snapshot.json +825 -0
  241. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0006_snapshot.json +832 -0
  242. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/_journal.json +7 -0
  243. package/dist/server/providers/database/pagination/combined-filters.d.ts +4 -1
  244. package/dist/server/providers/database/pagination/combined-filters.js +1 -1
  245. package/dist/server/providers/database/pagination/filter.d.ts +1 -0
  246. package/dist/server/providers/database/pagination/filter.js +1 -1
  247. package/dist/server/providers/database/pagination/index.d.ts +4 -1
  248. package/dist/server/providers/database/pagination/utils/decode-cursor.js +1 -1
  249. package/dist/server/ssr/index.js +1 -1
  250. package/dist/server/ssr/render.js +1 -1
  251. package/dist/server/ssr/template.d.ts +1 -1
  252. package/dist/server/ssr/template.js +13 -13
  253. package/dist/server/ssr/utils.js +27 -13
  254. package/dist/server/store.js +1 -1
  255. package/dist/server/tools/notifiers/formatter.d.ts +2 -0
  256. package/dist/server/tools/notifiers/formatter.js +3 -3
  257. package/dist/server/tools/notifiers/logger.d.ts +18 -39
  258. package/dist/server/tools/notifiers/logger.js +2 -6
  259. package/dist/server/tools/notifiers/reporter.js +9 -9
  260. package/dist/server/tools/notifiers/terminal-manager.d.ts +8 -0
  261. package/dist/server/tools/notifiers/terminal-manager.js +5 -0
  262. package/dist/server/types/fs.d.ts +5 -10
  263. package/dist/server/types/plugins/api-routes.d.ts +0 -3
  264. package/dist/server/types/plugins/common.d.ts +0 -1
  265. package/dist/server/utils/is-valid-iso-date.d.ts +5 -0
  266. package/dist/server/utils/is-valid-iso-date.js +1 -0
  267. package/dist/server/utils/lifecycle-hooks.js +1 -1
  268. package/dist/server/utils/queue.js +1 -1
  269. package/dist/server/utils/redirects/find-redirect.d.ts +4 -2
  270. package/dist/server/utils/redirects/find-redirect.js +1 -1
  271. package/dist/server/utils/resolve-asset-path.js +1 -1
  272. package/dist/server/utils/safe-parse.d.ts +6 -0
  273. package/dist/server/utils/safe-parse.js +1 -0
  274. package/dist/server/utils/validate-and-sanitize-string.d.ts +29 -0
  275. package/dist/server/utils/validate-and-sanitize-string.js +1 -0
  276. package/dist/server/web-server/auth.d.ts +5 -0
  277. package/dist/server/web-server/auth.js +3 -3
  278. package/dist/server/web-server/http.js +2 -2
  279. package/dist/server/web-server/middleware/loggerMiddleware.js +1 -1
  280. package/dist/server/web-server/routes/auth.js +1 -1
  281. package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
  282. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  283. package/dist/server/web-server/routes/catalog/catalog-relations.js +1 -1
  284. package/dist/server/web-server/routes/mcp-oauth.js +1 -1
  285. package/dist/server/web-server/routes/search.js +1 -1
  286. package/dist/server/web-server/utils/get-redirect-login-url.js +1 -1
  287. package/dist/types/ssr.d.ts +3 -1
  288. package/dist/utils/auth/build-login-url.d.ts +1 -3
  289. package/dist/utils/auth/build-login-url.js +1 -1
  290. package/dist/utils/env/is-local-development.d.ts +13 -0
  291. package/dist/utils/env/is-local-development.js +1 -0
  292. package/dist/utils/env/is-production.d.ts +13 -0
  293. package/dist/utils/env/is-production.js +1 -0
  294. package/dist/utils/env/is-web-view.d.ts +14 -0
  295. package/dist/utils/env/is-web-view.js +1 -0
  296. package/dist/utils/path/remove-fragment.d.ts +16 -0
  297. package/dist/utils/path/remove-fragment.js +1 -0
  298. package/package.json +12 -11
  299. package/dist/server/persistence/kv/mappers/create-kv-read-record.d.ts +0 -4
  300. package/dist/server/persistence/kv/mappers/create-kv-read-record.js +0 -1
  301. package/dist/server/web-server/routes/otel/types.d.ts +0 -61
  302. package/dist/server/web-server/routes/otel/types.js +0 -1
  303. /package/dist/server/plugins/catalog-entities/entities/{extract-entities-content.js → extract-file-content.js} +0 -0
@@ -1 +1 @@
1
- import{sql as a}from"drizzle-orm";const i=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),key:a.raw(t+"key"),type:a.raw(t+"type"),title:a.raw(t+"title"),summary:a.raw(t+"summary"),tags:a.raw(t+"tags"),metadata:a.raw(t+"metadata"),git:a.raw(t+"git"),contact:a.raw(t+"contact"),links:a.raw(t+"links"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at"),source:a.raw(t+"source"),sourceFile:a.raw(t+"source_file"),fileHash:a.raw(t+"file_hash"),version:a.raw(t+"version"),revision:a.raw(t+"revision"),hash:a.raw(t+"hash"),isCurrent:a.raw(t+"is_current"),scorecardsStatus:a.raw(t+"scorecards_status")}},s=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),sourceKey:a.raw(t+"source_key"),sourceId:a.raw(t+"source_id"),sourceVersion:a.raw(t+"source_version"),sourceRevision:a.raw(t+"source_revision"),sourceToTargetRelation:a.raw(t+"source_to_target_relation"),targetKey:a.raw(t+"target_key"),targetId:a.raw(t+"target_id"),targetVersion:a.raw(t+"target_version"),targetRevision:a.raw(t+"target_revision"),targetToSourceRelation:a.raw(t+"target_to_source_relation"),fileHash:a.raw(t+"file_hash"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at")}},n=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id"),organizationId:a.raw(r+"organization_id"),projectId:a.raw(r+"project_id"),key:a.raw(r+"key"),type:a.raw(r+"type"),title:a.raw(r+"title"),summary:a.raw(r+"summary"),tags:a.raw(r+"tags"),metadata:a.raw(r+"metadata"),git:a.raw(r+"git"),contact:a.raw(r+"contact"),links:a.raw(r+"links"),createdAt:a.raw(r+"created_at"),updatedAt:a.raw(r+"updated_at"),source:a.raw(r+"source"),sourceFile:a.raw(r+"source_file"),fileHash:a.raw(r+"file_hash"),version:a.raw(r+"version"),revision:a.raw(r+"revision"),hash:a.raw(r+"hash"),isCurrent:a.raw(r+"is_current")}},c=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id").as("id"),organizationId:a.raw(r+"organization_id").as("organization_id"),projectId:a.raw(r+"project_id").as("project_id"),key:a.raw(r+"key").as("key"),type:a.raw(r+"type").as("type"),title:a.raw(r+"title").as("title"),summary:a.raw(r+"summary").as("summary"),tags:a.raw(r+"tags").as("tags"),metadata:a.raw(r+"metadata").as("metadata"),git:a.raw(r+"git").as("git"),contact:a.raw(r+"contact").as("contact"),links:a.raw(r+"links").as("links"),createdAt:a.raw(r+"created_at").as("created_at"),updatedAt:a.raw(r+"updated_at").as("updated_at"),source:a.raw(r+"source").as("source"),sourceFile:a.raw(r+"source_file").as("source_file"),fileHash:a.raw(r+"file_hash").as("file_hash"),version:a.raw(r+"version").as("version"),revision:a.raw(r+"revision").as("revision"),hash:a.raw(r+"hash").as("hash"),isCurrent:a.raw(r+"is_current").as("is_current")}},w=i(),d=s();export{w as FIELDS_TO_SELECT_FOR_ENTITY,d as FIELDS_TO_SELECT_FOR_ENTITY_RELATION,i as createEntityFieldsForSelect,s as createEntityRelationFieldsForSelect,n as createQualifiedEntityFieldsForSelect,c as createQualifiedEntityFieldsForSelectWithAliases};
1
+ import{sql as a}from"drizzle-orm";const i=(t="",r)=>{const e=t?`${t}.`:"";return{id:r?a.raw(e+"id").as(r):a.raw(e+"id"),organizationId:a.raw(e+"organization_id"),projectId:a.raw(e+"project_id"),key:a.raw(e+"key"),type:a.raw(e+"type"),title:a.raw(e+"title"),summary:a.raw(e+"summary"),tags:a.raw(e+"tags"),metadata:a.raw(e+"metadata"),git:a.raw(e+"git"),contact:a.raw(e+"contact"),links:a.raw(e+"links"),createdAt:a.raw(e+"created_at"),updatedAt:a.raw(e+"updated_at"),source:a.raw(e+"source"),sourceFile:a.raw(e+"source_file"),fileHash:a.raw(e+"file_hash"),version:a.raw(e+"version"),revision:a.raw(e+"revision"),hash:a.raw(e+"hash"),isCurrent:a.raw(e+"is_current"),isDeleted:a.raw(e+"is_deleted"),scorecardsStatus:a.raw(e+"scorecards_status")}},s=(t="",r)=>{const e=t?`${t}.`:"";return{id:r?a.raw(e+"id").as(r):a.raw(e+"id"),organizationId:a.raw(e+"organization_id"),projectId:a.raw(e+"project_id"),sourceKey:a.raw(e+"source_key"),sourceVersion:a.raw(e+"source_version"),sourceRevision:a.raw(e+"source_revision"),sourceToTargetRelation:a.raw(e+"source_to_target_relation"),targetKey:a.raw(e+"target_key"),targetVersion:a.raw(e+"target_version"),targetRevision:a.raw(e+"target_revision"),targetToSourceRelation:a.raw(e+"target_to_source_relation"),fileHash:a.raw(e+"file_hash"),createdAt:a.raw(e+"created_at"),updatedAt:a.raw(e+"updated_at")}},n=(t="")=>{const r=t?`${t}.`:"";return{id:a.raw(r+"entity_id"),organizationId:a.raw(r+"organization_id"),projectId:a.raw(r+"project_id"),key:a.raw(r+"key"),type:a.raw(r+"type"),title:a.raw(r+"title"),summary:a.raw(r+"summary"),tags:a.raw(r+"tags"),metadata:a.raw(r+"metadata"),git:a.raw(r+"git"),contact:a.raw(r+"contact"),links:a.raw(r+"links"),createdAt:a.raw(r+"created_at"),updatedAt:a.raw(r+"updated_at"),source:a.raw(r+"source"),sourceFile:a.raw(r+"source_file"),fileHash:a.raw(r+"file_hash"),version:a.raw(r+"version"),revision:a.raw(r+"revision"),hash:a.raw(r+"hash"),isCurrent:a.raw(r+"is_current"),isDeleted:a.raw(r+"is_deleted")}},w=(t="")=>{const r=t?`${t}.`:"";return{id:a.raw(r+"entity_id").as("id"),organizationId:a.raw(r+"organization_id").as("organization_id"),projectId:a.raw(r+"project_id").as("project_id"),key:a.raw(r+"key").as("key"),type:a.raw(r+"type").as("type"),title:a.raw(r+"title").as("title"),summary:a.raw(r+"summary").as("summary"),tags:a.raw(r+"tags").as("tags"),metadata:a.raw(r+"metadata").as("metadata"),git:a.raw(r+"git").as("git"),contact:a.raw(r+"contact").as("contact"),links:a.raw(r+"links").as("links"),createdAt:a.raw(r+"created_at").as("created_at"),updatedAt:a.raw(r+"updated_at").as("updated_at"),source:a.raw(r+"source").as("source"),sourceFile:a.raw(r+"source_file").as("source_file"),fileHash:a.raw(r+"file_hash").as("file_hash"),version:a.raw(r+"version").as("version"),revision:a.raw(r+"revision").as("revision"),hash:a.raw(r+"hash").as("hash"),isCurrent:a.raw(r+"is_current").as("is_current"),isDeleted:a.raw(r+"is_deleted").as("is_deleted")}},c=i(),d=s();export{c as FIELDS_TO_SELECT_FOR_ENTITY,d as FIELDS_TO_SELECT_FOR_ENTITY_RELATION,i as createEntityFieldsForSelect,s as createEntityRelationFieldsForSelect,n as createQualifiedEntityFieldsForSelect,w as createQualifiedEntityFieldsForSelectWithAliases};
@@ -1,4 +1,4 @@
1
1
  import type { LifecycleContext } from '../../../types';
2
2
  import type { EntitiesFileSchema } from './types.js';
3
3
  export declare const extractFileContent: (filePath: string, context: LifecycleContext) => Promise<EntitiesFileSchema | null>;
4
- //# sourceMappingURL=extract-entities-content.d.ts.map
4
+ //# sourceMappingURL=extract-file-content.d.ts.map
@@ -6,9 +6,9 @@ type Params = BaseApiEntitiesExtractorParams;
6
6
  export declare class ArazzoEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
7
7
  #private;
8
8
  constructor(params: Params);
9
- mapApiDescriptionToEntity(description: BundledDefinition): EntityFileSchema;
9
+ mapApiDescriptionToEntity(description: BundledDefinition, version: string): EntityFileSchema;
10
10
  loadApiDescriptions(): Promise<BundledDefinition[]>;
11
- processApiDescription(description: BundledDefinition): Promise<Set<string>>;
11
+ processApiDescription(description: BundledDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
12
12
  resolveSourceDescriptionUrl(url: string, baseRelativePath: string): string | null;
13
13
  }
14
14
  export {};
@@ -1 +1 @@
1
- import h from"node:path";import{removeLeadingSlash as u}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as y}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as d}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{resolveEntityVersion as g}from"../../../utils/resolve-entity-version.js";import{BaseApiEntitiesExtractor as w}from"./base.js";const m=15;class A extends w{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t){const o=u(t.realRelativePath),a=t.document.info.title,c=o.replace(/\.[^.]+$/,""),e=p(c.replace(/[\\/]/g,"-")),r=t.document["x-redocly-catalog-key"],n=typeof r=="string"&&r.trim()?p(r.trim()):e,l=t.document.info.version,s=g(l,t.realRelativePath);if(!s.success)throw new Error(`Arazzo "${a}" in file "${t.realRelativePath}" has conflicting versions: spec version "${s.fileVersion}" differs from folder version "${s.folderVersion}". Entity will not be created.`);return{type:this.type,key:n,title:a,summary:t.document.info.description?d(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:o},version:s.version}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t){const o=new Set;if(!this.#t(t))return this.context.logger.warn(`Skipping Arazzo description without source descriptions: ${t.realRelativePath}`),o;const a=this.mapApiDescriptionToEntity(t);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),o.add(a.key),await this.#e(t,a.key,a.version,o);const c=t.document.sourceDescriptions||[];return await y(c,m,async e=>{if(!(e.type!=="openapi"||!e.url))try{const r=this.resolveSourceDescriptionUrl(e.url,t.realRelativePath);if(!r){!e.url.startsWith("http://")&&!e.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${e.url}`);return}const n=await this.context.cache.load(r,"load-oas");if(!(n.data&&Array.isArray(n.data)&&n.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${r}`);return}const s=n.data[0],i=p(u(s.realRelativePath).replace(/\.[^.]+$/,"").replace(/[\\/]/g,"-"));await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a.key,type:"relatesTo",targetKey:i,fileHash:t.hash}),await this.#r(t,e.name,s,a.key,i,a.version)}catch(r){this.context.logger.warn(`Failed to create relation to OpenAPI source "${e.url}": ${r instanceof Error?r.message:"Unknown error"}`)}}),o}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,c)=>{try{const e=t.document.components?.inputs,r=e?Object.entries(e):[],n=[];for(const[l,s]of r)n.push(async()=>{const i=await this.#a({schemaName:l,schema:s,description:t,parentKey:o,parentVersion:a});c.add(i),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:a,targetVersion:a})});if(n.length===0)return;await y(n,m,l=>l())}catch(e){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${e instanceof Error?e.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:c,parentVersion:e})=>{const r={type:"data-schema",key:`${c}-${p(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash}),r.key};#r=async(t,o,a,c,e,r)=>{const n=t.document.workflows||[];if(n.length===0)return;const l=new Set;for(const s of n)for(const i of s.steps||[]){if(!i.operationId)continue;const f=i.operationId.startsWith(`${o}.`)?i.operationId.substring(`${o}.`.length):i.operationId;f&&l.add(f)}l.size!==0&&await y(Array.from(l),m,async s=>{try{const i=`${e}-${p(s)}`;await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:c,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:r,targetVersion:r})}catch(i){this.context.logger.warn(`Failed to create relation to operation "${s}": ${i instanceof Error?i.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 u(h.posix.normalize(e));const r=h.posix.dirname(o);return e.startsWith(r+"/")?h.posix.normalize(e):h.posix.normalize(h.posix.join(r,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{A as ArazzoEntitiesExtractor};
1
+ import u from"node:path";import{removeLeadingSlash as m}from"@redocly/theme/core/utils";import{toKebabCase as y}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as f}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as d}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";const g=15;class k extends w{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t,o){const r=m(t.realRelativePath),c=t.document.info.title,e=r.replace(/\.[^.]+$/,""),n=y(e.replace(/[\\/]/g,"-")),a=t.document["x-redocly-catalog-key"],i=typeof a=="string"&&a.trim()?y(a.trim()):n;return{type:this.type,key:i,title:c,summary:t.document.info.description?d(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:r},version:o}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t,o,r,c){if(!this.#t(t)){this.context.logger.warn(`Skipping Arazzo description without source descriptions: ${t.realRelativePath}`);return}const e=this.mapApiDescriptionToEntity(t,r);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:e,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,revision:o}),c.delete(`${e.key}:${r}`),await this.#e(t,e.key,e.version,r,o,c);const n=t.document.sourceDescriptions||[];await f(n,g,async a=>{if(!(a.type!=="openapi"||!a.url))try{const i=this.resolveSourceDescriptionUrl(a.url,t.realRelativePath);if(!i){!a.url.startsWith("http://")&&!a.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${a.url}`);return}const l=await this.context.cache.load(i,"load-oas");if(!(l.data&&Array.isArray(l.data)&&l.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${i}`);return}const s=l.data[0],p=y(m(s.realRelativePath).replace(/\.[^.]+$/,"").replace(/[\\/]/g,"-"));await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e.key,type:"relatesTo",targetKey:p,fileHash:t.hash}),await this.#r(t,a.name,s,e.key,p,e.version,o)}catch(i){this.context.logger.warn(`Failed to create relation to OpenAPI source "${a.url}": ${i instanceof Error?i.message:"Unknown error"}`)}})}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,r,c,e,n)=>{try{const a=t.document.components?.inputs,i=a?Object.entries(a):[],l=[];for(const[h,s]of i)l.push(async()=>{const p=await this.#a({schemaName:h,schema:s,description:t,parentKey:o,parentVersion:r,parentRevision:e});n.delete(`${p.entityKey}:${c}`),p.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,type:"uses",targetKey:p.entityKey,fileHash:t.hash,sourceVersion:r,targetVersion:r,sourceRevision:e,targetRevision:e})});if(l.length===0)return;await f(l,g,h=>h())}catch(a){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${a instanceof Error?a.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:r,parentKey:c,parentVersion:e,parentRevision:n})=>{const a={type:"data-schema",key:`${c}-${y(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:r.realRelativePath,schema:"{}"},version:e};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:r.realRelativePath,fileHash:r.hash,revision:n})};#r=async(t,o,r,c,e,n,a)=>{const i=t.document.workflows||[];if(i.length===0)return;const l=new Set;for(const h of i)for(const s of h.steps||[]){if(!s.operationId)continue;const p=s.operationId.startsWith(`${o}.`)?s.operationId.substring(`${o}.`.length):s.operationId;p&&l.add(p)}l.size!==0&&await f(Array.from(l),g,async h=>{try{const s=`${e}-${y(h)}`;await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:c,type:"uses",targetKey:s,fileHash:t.hash,sourceVersion:n,targetVersion:n,sourceRevision:a,targetRevision:a})}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 r=t.trim(),c=r.startsWith("@")?r.slice(1):r,[e]=c.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return m(u.posix.normalize(e));const n=u.posix.dirname(o);return e.startsWith(n+"/")?u.posix.normalize(e):u.posix.normalize(u.posix.join(n,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{k as ArazzoEntitiesExtractor};
@@ -6,9 +6,9 @@ type Params = BaseApiEntitiesExtractorParams;
6
6
  export declare class AsyncApiEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
7
7
  #private;
8
8
  constructor(params: Params);
9
- mapApiDescriptionToEntity(description: BundledDefinition): EntityFileSchema;
9
+ mapApiDescriptionToEntity(description: BundledDefinition, version: string): EntityFileSchema;
10
10
  loadApiDescriptions(): Promise<BundledDefinition[]>;
11
- processApiDescription(description: BundledDefinition): Promise<Set<string>>;
11
+ processApiDescription(description: BundledDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
12
12
  }
13
13
  export {};
14
14
  //# sourceMappingURL=asyncapi-entities-extractor.d.ts.map
@@ -1 +1 @@
1
- import{removeLeadingSlash as p}from"@redocly/theme/core/utils";import{toKebabCase as l}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as y}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as f}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as g}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as d}from"./base.js";import{extractPartsFromComponentsRef as u}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as R}from"../../../entities/validate-entity.js";import{extractPartsFromChannelsMessageRef as E}from"../../../utils/extract-parts-from-channels-message-ref.js";import{resolveEntityVersion as $}from"../../../utils/resolve-entity-version.js";const m=15;class I extends d{constructor(e){super("asyncapi",e)}mapApiDescriptionToEntity(e){const t=p(e.realRelativePath),a=e.document.info.title,n=t.replace(/\.[^.]+$/,""),s=l(n.replace(/[\\/]/g,"-")),r=e.document["x-redocly-catalog-key"],i=typeof r=="string"&&r.trim()?l(r.trim()):s,o=e.document.info.version,c=$(o,e.realRelativePath);if(!c.success)throw new Error(`AsyncAPI "${a}" in file "${e.realRelativePath}" has conflicting versions: spec version "${c.fileVersion}" differs from folder version "${c.folderVersion}". Entity will not be created.`);return{type:this.type,key:i,title:a,summary:g(e.document.info.description),tags:e.document.info.tags?.map(h=>h.name),metadata:{specType:this.specType,descriptionFile:t},version:c.version}}async loadApiDescriptions(){return(await this.context.cache.load(".","asyncapi-docs")).data}async processApiDescription(e){const t=new Set,a=this.mapApiDescriptionToEntity(e);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0}),t.add(a.key);const n=this.#t(e),[s,r]=await Promise.allSettled([this.#a(e,a.key,a.version,t),this.#n(n,e,a.key,a.version,t)]);return s.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",s.reason),r.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",r.reason),t}#t=e=>{const t=e.documentWithReferences.operations;return t?Object.entries(t).map(([a,n])=>({operationName:a,operation:n})):[]};#a=async(e,t,a,n)=>{const s=e.document.components?.schemas;if(!s)return;const r=Object.entries(s);if(r.length===0)return;const i=await f(r,m,async([o,c])=>{const h=await this.#s({schemaName:o,schema:c,description:e,parentKey:t,parentVersion:a});n.add(h),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"uses",targetKey:h,fileHash:e.hash,sourceVersion:a,targetVersion:a})},this.context.logger);i.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${i.count.failed} failures out of ${r.length} schemas for ${e.realRelativePath}`)};#s=async({schemaName:e,schema:t,description:a,parentKey:n,parentVersion:s})=>{const r=`${n}-${l(e)}`,i="title"in t?t.title??t.description:null,o=JSON.stringify(t),c={type:"data-schema",key:r,title:e,summary:i,tags:[],metadata:{specType:this.specType,schema:o},version:s};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:a.realRelativePath,fileHash:a.hash}),c.key};#n=async(e,t,a,n,s)=>{if(!e.length)return;const r=await f(e,m,async({operationName:i,operation:o})=>{const c=await this.#r(o,i,t,a,n);c&&s.add(c)},this.context.logger);r.count.failed>0&&this.context.logger.warn(`Operation processing completed with ${r.count.failed} failures out of ${e.length} operations for ${t.realRelativePath}`)};#r=async(e,t,a,n,s)=>{const r=`${n}-${l(t)}`,i=await this.#o({apiOperationKey:r,operation:e,descriptionUniqueKey:n,description:a,descriptionVersion:s});return await this.#i(t,e,i,a,n,s)??null};#i=async(e,t,a,n,s,r)=>{const i={type:"api-operation",key:`${s}-${l(e)}`,title:t.title||e,summary:t.summary??"",tags:t.tags?.map(o=>o.name)??[],metadata:{method:t.action==="send"?"PUBLISH":"SUBSCRIBE",path:t.channel.address??"",payload:t.action==="receive"?a:[],responses:t.action==="send"?a:[]},version:r};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:n.realRelativePath,fileHash:n.hash}),i.key};#o=async({apiOperationKey:e,operation:t,descriptionUniqueKey:a,description:n,descriptionVersion:s})=>(await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:a,fileHash:n.hash,sourceVersion:s,targetVersion:s}),await this.#c(t,e,s),!Array.isArray(t.messages)||!t.messages?.length?[]:await this.#l(t.messages,e,n,a,s));#c=async(e,t,a)=>{e["x-catalog-relations"]?.length&&await y(e["x-catalog-relations"],m,async n=>{try{R(n),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:n.type,targetKey:n.key,sourceVersion:a,targetVersion:a})}catch(s){this.context.logger.warn(`Error creating entity relation for operation ${t} based on custom property: ${s instanceof Error?s.message:"Unknown error"}`)}})};#l=async(e,t,a,n,s)=>e.length===0?[]:(await y(e,m,async i=>await this.#h(i,t,a,n,s)??"")).filter(i=>!!i);#h=async(e,t,a,n,s)=>"$ref"in e?this.#m(e,t,a,n,s):e.payload?this.#f(e,t,a,n,s):null;#m=async(e,t,a,n,s)=>{const r=e.$ref.startsWith("#/channels/")?this.#y(e.$ref,a):e.$ref;if(!r)return null;const i=u(r);if(!i||!i.componentName||i.componentType!=="messages")return null;const o=a.documentWithReferences.components?.messages[i.componentName];return!o?.payload||!("$ref"in o.payload)||!o.payload.$ref?null:this.#e(o.payload.$ref,t,a,n,s)};#y=(e,t)=>{const a=E(e);if(!a||!a.channelName||!a.messageName)return null;const n=t.documentWithReferences.channels?.[a.channelName];if(!n?.messages)return null;const s=n.messages[a.messageName];return!s||!("$ref"in s)||typeof s.$ref!="string"||!s.$ref.startsWith("#/components/messages/")?null:s.$ref};#f=async(e,t,a,n,s)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#e(e.payload.$ref,t,a,n,s);#e=async(e,t,a,n,s)=>{const r=u(e);if(!r||!r.componentName||r.componentType!=="schemas")return null;const i=`${n}-${l(r.componentName)}`;return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"uses",targetKey:i,fileHash:a.hash,sourceVersion:s,targetVersion:s}),i}}export{I as AsyncApiEntitiesExtractor};
1
+ import{removeLeadingSlash as $}from"@redocly/theme/core/utils";import{toKebabCase as h}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as g}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as d}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as R}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as E}from"../../../entities/validate-entity.js";import{extractPartsFromChannelsMessageRef as w}from"../../../utils/extract-parts-from-channels-message-ref.js";const f=15;class k extends R{constructor(e){super("asyncapi",e)}mapApiDescriptionToEntity(e,a){const s=$(e.realRelativePath),n=e.document.info.title,t=s.replace(/\.[^.]+$/,""),r=h(t.replace(/[\\/]/g,"-")),o=e.document["x-redocly-catalog-key"],c=typeof o=="string"&&o.trim()?h(o.trim()):r;return{type:this.type,key:c,title:n,summary:d(e.document.info.description),tags:e.document.info.tags?.map(i=>i.name),metadata:{specType:this.specType,descriptionFile:s},version:a}}async loadApiDescriptions(){return(await this.context.cache.load(".","asyncapi-docs")).data}async processApiDescription(e,a,s,n){const t=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:t,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,revision:a}),n.delete(`${t.key}:${s}`);const r=this.#a(e),[o,c]=await Promise.allSettled([this.#s(e,t.key,t.version,s,a,n),this.#r(r,e,t.key,t.version,s,a,n)]);o.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",o.reason),c.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",c.reason)}#a=e=>{const a=e.documentWithReferences.operations;return a?Object.entries(a).map(([s,n])=>({operationName:s,operation:n})):[]};#s=async(e,a,s,n,t,r)=>{const o=e.document.components?.schemas;if(!o)return;const c=Object.entries(o);if(c.length===0)return;const i=await g(c,f,async([l,m])=>{const u=await this.#n({schemaName:l,schema:m,description:e,parentKey:a,parentVersion:s,parentRevision:t});r.delete(`${u.entityKey}:${n}`),u.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a,type:"uses",targetKey:u.entityKey,fileHash:e.hash,sourceVersion:s,targetVersion:s,sourceRevision:t,targetRevision:t})},this.context.logger);i.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${i.count.failed} failures out of ${c.length} schemas for ${e.realRelativePath}`)};#n=async({schemaName:e,schema:a,description:s,parentKey:n,parentVersion:t,parentRevision:r})=>{const o=`${n}-${h(e)}`,c="title"in a?a.title??a.description:null,i=JSON.stringify(a),l={type:"data-schema",key:o,title:e,summary:c,tags:[],metadata:{specType:this.specType,schema:i},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:l,sourceFile:s.realRelativePath,fileHash:s.hash,revision:r})};#r=async(e,a,s,n,t,r,o)=>{if(!e.length)return;const c=await g(e,f,async({operationName:i,operation:l})=>{const m=await this.#c(l,i,a,s,n,r);m&&o.delete(`${m}:${t}`)},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 ${a.realRelativePath}`)};#c=async(e,a,s,n,t,r)=>{const o=await this.#o(e.messages??[],s,n),c=await this.#i(a,e,o,s,n,t,r);return c.result==="created"&&await this.#l({apiOperationKey:c.entityKey,operation:e,descriptionUniqueKey:n,description:s,descriptionVersion:t,parentRevision:r}),c.entityKey??null};#o=async(e,a,s)=>{if(!e||e.length===0)return[];const n=new Set;for(const t of e){let r=null;if("$ref"in t){const o=t.$ref.startsWith("#/channels/")?this.#e(t.$ref,a):t.$ref;if(o){const c=y(o);if(c?.componentName&&c.componentType==="messages"){const i=a.documentWithReferences.components?.messages[c.componentName];i?.payload&&"$ref"in i.payload&&i.payload.$ref&&(r=i.payload.$ref)}}}else t.payload&&"$ref"in t.payload&&t.payload.$ref&&(r=t.payload.$ref);if(r){const o=y(r);o?.componentName&&o.componentType==="schemas"&&n.add(`${s}-${h(o.componentName)}`)}}return Array.from(n)};#i=async(e,a,s,n,t,r,o)=>{const c={type:"api-operation",key:`${t}-${h(e)}`,title:a.title||e,summary:a.summary??"",tags:a.tags?.map(l=>l.name)??[],metadata:{method:a.action==="send"?"PUBLISH":"SUBSCRIBE",path:a.channel.address??"",payload:a.action==="receive"?s:[],responses:a.action==="send"?s:[]},version:r};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:n.realRelativePath,fileHash:n.hash,revision:o})};#l=async({apiOperationKey:e,operation:a,descriptionUniqueKey:s,description:n,descriptionVersion:t,parentRevision:r})=>(await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:s,fileHash:n.hash,sourceVersion:t,targetVersion:t,sourceRevision:r,targetRevision:r}),await this.#h(a,e,t,r),!Array.isArray(a.messages)||!a.messages?.length?[]:await this.#m(a.messages,e,n,s,t,r));#h=async(e,a,s,n)=>{e["x-catalog-relations"]?.length&&await p(e["x-catalog-relations"],f,async t=>{try{E(t),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a,type:t.type,targetKey:t.key,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n})}catch(r){this.context.logger.warn(`Error creating entity relation for operation ${a} based on custom property: ${r instanceof Error?r.message:"Unknown error"}`)}})};#m=async(e,a,s,n,t,r)=>e.length===0?[]:(await p(e,f,async c=>await this.#y(c,a,s,n,t,r)??"")).filter(c=>!!c);#y=async(e,a,s,n,t,r)=>"$ref"in e?this.#f(e,a,s,n,t,r):e.payload?this.#u(e,a,s,n,t,r):null;#f=async(e,a,s,n,t,r)=>{const o=e.$ref.startsWith("#/channels/")?this.#e(e.$ref,s):e.$ref;if(!o)return null;const c=y(o);if(!c||!c.componentName||c.componentType!=="messages")return null;const i=s.documentWithReferences.components?.messages[c.componentName];return!i?.payload||!("$ref"in i.payload)||!i.payload.$ref?null:this.#t(i.payload.$ref,a,s,n,t,r)};#e=(e,a)=>{const s=w(e);if(!s||!s.channelName||!s.messageName)return null;const n=a.documentWithReferences.channels?.[s.channelName];if(!n?.messages)return null;const t=n.messages[s.messageName];return!t||!("$ref"in t)||typeof t.$ref!="string"||!t.$ref.startsWith("#/components/messages/")?null:t.$ref};#u=async(e,a,s,n,t,r)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#t(e.payload.$ref,a,s,n,t,r);#t=async(e,a,s,n,t,r)=>{const o=y(e);if(!o||!o.componentName||o.componentType!=="schemas")return null;const c=`${n}-${h(o.componentName)}`;return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a,type:"uses",targetKey:c,fileHash:s.hash,sourceVersion:t,targetVersion:t,sourceRevision:r,targetRevision:r}),c}}export{k as AsyncApiEntitiesExtractor};
@@ -18,7 +18,7 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
18
18
  constructor(specType: SpecType, params: BaseApiEntitiesExtractorParams);
19
19
  extract(): Promise<void>;
20
20
  protected abstract loadApiDescriptions(): Promise<BundledApiDefinition[]>;
21
- protected abstract mapApiDescriptionToEntity(definition: BundledApiDefinition): EntityFileSchema;
22
- protected abstract processApiDescription(definition: BundledApiDefinition): Promise<Set<string>>;
21
+ protected abstract mapApiDescriptionToEntity(definition: BundledApiDefinition, version: string): EntityFileSchema;
22
+ protected abstract processApiDescription(definition: BundledApiDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
23
23
  }
24
24
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- import{FileHashStatus as a}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as r}from"../../../../../utils/async/promise-map-limit.js";import{catalogDataCollector as s}from"../../../utils/catalog-data-collector.js";const o=3;class p{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}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&s.addExtractor(this.specType),await r(t,o,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){s.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE);return}const l=await this.processApiDescription(e);await this.#i(l,e.realRelativePath),s.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:a.OUTDATED}]})};#i=async(t,e)=>{t.size!==0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})}}export{p as BaseApiEntitiesExtractor};
1
+ import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as v}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as u}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as f}from"@redocly/theme/core/constants";import{resolveEntityVersion as g}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as h}from"../../../utils/catalog-data-collector.js";const E=3;class D{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}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&h.addExtractor(this.specType),await v(t,E,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){h.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE);return}const a=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(e.realRelativePath),o=new Date().toISOString(),n=this.#a(e);await this.processApiDescription(e,o,n,a),await this.#i(a,e.realRelativePath,o,e.hash),h.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#i=async(t,e,i,r)=>{if(t.size===0)return;const a=Array.from(t).map(s=>{const[l,p]=s.split(":");return{key:l,version:p}}),o=Array.from(new Set(a.map(({key:s})=>s))),n=a.map(({key:s,version:l})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:s},{field:"version",operator:"equal",value:l}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:i,fileHash:r,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:n},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#a(t){const e=t.document?.info?.version??t.definition?.info?.version??null,i=g(e,t.realRelativePath);return i.success?i.version??f:f}}export{D as BaseApiEntitiesExtractor};
@@ -13,8 +13,8 @@ export declare class GraphqlEntitiesExtractor extends BaseApiEntitiesExtractor<G
13
13
  #private;
14
14
  constructor(params: BaseApiEntitiesExtractorParams);
15
15
  loadApiDescriptions(): Promise<GraphqlBundledDefinition[]>;
16
- mapApiDescriptionToEntity(description: GraphqlBundledDefinition): EntityFileSchema;
17
- processApiDescription(description: GraphqlBundledDefinition): Promise<Set<string>>;
16
+ mapApiDescriptionToEntity(description: GraphqlBundledDefinition, version: string): EntityFileSchema;
17
+ processApiDescription(description: GraphqlBundledDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
18
18
  }
19
19
  export {};
20
20
  //# sourceMappingURL=graphql-entities-extractor.d.ts.map
@@ -1,3 +1,3 @@
1
- import{buildSchema as v,isObjectType as m,isScalarType as R,isEnumType as I,isInterfaceType as T,isUnionType as d,isInputObjectType as w,getNamedType as y,printType as $}from"graphql";import{removeLeadingSlash as O}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as D}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as u}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as S}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as L}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as F}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{resolveEntityVersion as A}from"../../../utils/resolve-entity-version.js";import{BaseApiEntitiesExtractor as j}from"./base.js";const E=15,b=15,N=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class Q extends j{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of await 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:s,metadata:o}=a.data,r=v(s),l=L(s);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:l,schema:r,content:s,metadata:o})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t){const e=O(t.realRelativePath),a=t.relativePath.replace(/\.(gql|graphql)$/,""),s=this.#s(a.split("/").pop()||"GraphQL Schema"),o=e.replace(/\.(gql|graphql)$/,""),r=f(o.replace(/[\\/]/g,"-")),l=this.#c(t.metadata?.tags),c=t.metadata?.["x-redocly-catalog-key"],i=typeof c=="string"&&c.trim()?f(c.trim()):r,n=A(null,t.realRelativePath),p=n.success?n.version:null;return{type:this.type,key:i,title:s,summary:t.metadata?.description||null,tags:l.concat("graphql"),metadata:{specType:this.specType,descriptionFile:e},version:p}}async processApiDescription(t){const e=new Set,{schema:a}=t;if(!a)return e;const s=this.mapApiDescriptionToEntity(t);return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:s,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),e.add(s.key),await Promise.all([this.#a(t,s.key,s.version,e),this.#y(t,s.key,s.version,e)]),e}#a=async(t,e,a,s)=>{const{schema:o}=t,r=o.getTypeMap(),l=this.#r(o),c=Object.entries(r).filter(([n])=>!n.startsWith("__")&&!N.has(n)&&!l.has(n));if(c.length===0)return;const i=await S(c,b,async([n,p])=>{const h=await this.#l({typeName:n,type:p,description:t,parentKey:e,parentVersion:a});s.add(h),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:h,fileHash:t.hash,sourceVersion:a,targetVersion:a})},this.#t);i.count.failed>0&&this.#t.warn(`Schema processing completed with ${i.count.failed} failures out of ${c.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:c})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&D(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${f(t)}`;#n=t=>m(t)?"object":T(t)?"interface":d(t)?"union":I(t)?"enum":w(t)?"input":R(t)?"scalar":"unknown";#r=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const s=t.getMutationType();s&&e.add(s.name);const o=t.getSubscriptionType();return o&&e.add(o.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const r=a.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"QUERY",rootTypeName:a.name})}const s=t.getMutationType();if(s){const r=s.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"MUTATION",rootTypeName:s.name})}const o=t.getSubscriptionType();if(o){const r=o.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"SUBSCRIBE",rootTypeName:o.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const r of t.args){const l=y(r.type);l&&!l.name.startsWith("__")&&a.push(this.#e(l.name,e))}const s=[],o=y(t.type);return o&&!o.name.startsWith("__")&&s.push(this.#e(o.name,e)),{inputTypes:a,returnTypes:s}};#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:s,parentVersion:o})=>{const r=this.#e(t,s),l=e.description??null,c=this.#n(e),i={type:"data-schema",key:r,title:t,summary:l,tags:["graphql"],metadata:{specType:this.specType,typeKind:c,sdl:this.#p(e,a.schema)},version:o};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:a.realRelativePath,fileHash:a.hash}),i.key};#p=(t,e)=>{const a=new Set,s=[],o=new Set(["String","ID","Int","Float","Boolean"]),r=i=>{if(!i)return;const n=i.name;if(n.startsWith("__")||o.has(n)||a.has(n))return;const p=e.getType(n);p&&(a.add(n),s.push(p))};for(r(t);s.length>0;){const i=s.pop();if(m(i)){for(const p of i.getInterfaces?.()??[])r(p);const n=i.getFields();for(const p of Object.values(n)){r(y(p.type));for(const h of p.args??[])r(y(h.type))}}else if(T(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}else if(d(i))for(const n of i.getTypes())r(n);else if(w(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}}const l=[t.name,...[...a].filter(i=>i!==t.name)],c=[];for(const i of l){const n=e.getType(i);n&&c.push($(n))}return c.join(`
1
+ import{buildSchema as R,isObjectType as g,isScalarType as O,isEnumType as D,isInterfaceType as S,isUnionType as w,isInputObjectType as E,getNamedType as u,printType as L}from"graphql";import{removeLeadingSlash as v}from"@redocly/theme/core/utils";import{toKebabCase as m}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as A}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as T}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as b}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as j}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as K}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as N}from"./base.js";const $=15,I=15,F=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class Q extends N{#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:n,metadata:r}=a.data,s=R(n),o=j(n);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:o,schema:s,content:n,metadata:r})}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=v(t.realRelativePath),n=t.relativePath.replace(/\.(gql|graphql)$/,""),r=this.#s(n.split("/").pop()||"GraphQL Schema"),s=a.replace(/\.(gql|graphql)$/,""),o=m(s.replace(/[\\/]/g,"-")),p=this.#c(t.metadata?.tags),c=t.metadata?.["x-redocly-catalog-key"],i=typeof c=="string"&&c.trim()?m(c.trim()):o;return{type:this.type,key:i,title:r,summary:t.metadata?.description||null,tags:p.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,n){const{schema:r}=t;if(!r)return;const s=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:s,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,revision:e}),n.delete(`${s.key}:${a}`),await Promise.all([this.#a(t,s.key,s.version,a,e,n),this.#y(t,s.key,s.version,a,e,n)])}#a=async(t,e,a,n,r,s)=>{const{schema:o}=t,p=o.getTypeMap(),c=this.#r(o),i=Object.entries(p).filter(([h])=>!h.startsWith("__")&&!F.has(h)&&!c.has(h));if(i.length===0)return;const l=await b(i,I,async([h,y])=>{const f=await this.#l({typeName:h,type:y,description:t,parentKey:e,parentVersion:a,parentRevision:r});s.delete(`${f.entityKey}:${n}`),f.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:f.entityKey,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:r,targetRevision:r})},this.#t);l.count.failed>0&&this.#t.warn(`Schema processing completed with ${l.count.failed} failures out of ${i.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:i,parentRevision:r})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&A(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${m(t)}`;#n=t=>g(t)?"object":S(t)?"interface":w(t)?"union":D(t)?"enum":E(t)?"input":O(t)?"scalar":"unknown";#r=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};#i(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"QUERY",rootTypeName:a.name})}const n=t.getMutationType();if(n){const s=n.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"MUTATION",rootTypeName:n.name})}const r=t.getSubscriptionType();if(r){const s=r.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"SUBSCRIBE",rootTypeName:r.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const o=u(s.type);o&&!o.name.startsWith("__")&&a.push(this.#e(o.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})=>{const o=this.#e(t,n),p=e.description??null,c=this.#n(e),i={type:"data-schema",key:o,title:t,summary:p,tags:["graphql"],metadata:{specType:this.specType,typeKind:c,sdl:this.#p(e,a.schema)},version:r};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:a.realRelativePath,fileHash:a.hash,revision:s})};#p=(t,e)=>{const a=new Set,n=[],r=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const i=c.name;if(i.startsWith("__")||r.has(i)||a.has(i))return;const l=e.getType(i);l&&(a.add(i),n.push(l))};for(s(t);n.length>0;){const c=n.pop();if(g(c)){for(const l of c.getInterfaces?.()??[])s(l);const i=c.getFields();for(const l of Object.values(i)){s(u(l.type));for(const h of l.args??[])s(u(h.type))}}else if(S(c)){const i=c.getFields();for(const l of Object.values(i))s(u(l.type))}else if(w(c))for(const i of c.getTypes())s(i);else if(E(c)){const i=c.getFields();for(const l of Object.values(i))s(u(l.type))}}const o=[t.name,...[...a].filter(c=>c!==t.name)],p=[];for(const c of o){const i=e.getType(c);i&&p.push(L(i))}return p.join(`
2
2
 
3
- `)};#h=async({description:t,descriptionUniqueKey:e,userTypes:a})=>{const s=a.filter(([,o])=>m(o));s.length!==0&&await u(s,b,async([o,r])=>{const c=r.getInterfaces?.()??[];if(!c.length)return;const i=this.#e(o,e);await u([...c],5,async n=>{const p=this.#e(n.name,e);try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:i,type:"implements",targetKey:p,fileHash:t.hash})}catch(h){this.#t.warn(`Failed to create 'implements' relation ${i} -> ${p}: ${h instanceof Error?h.message:"Unknown error"}`)}})})};#y=async(t,e,a,s)=>{const{schema:o}=t,r=this.#i(o);if(r.length===0)return;const c=(await S(r,E,async({fieldName:i,field:n,operationType:p,rootTypeName:h})=>{const g=await this.#f(i,n,p,h,t,e,a);g&&s.add(g)},this.#t)).count.failed;c>0&&this.#t.warn(`Operation extraction completed with ${c} failures out of ${r.length} operations for ${e}`)};#f=async(t,e,a,s,o,r,l)=>{const{inputTypes:c,returnTypes:i}=this.#o(e,r),n=await this.#m({fieldName:t,field:e,operationType:a,rootTypeName:s,inputTypes:c,returnTypes:i,description:o,descriptionUniqueKey:r,descriptionVersion:l});return await this.#u({apiOperationKey:n,inputTypes:c,returnTypes:i,descriptionUniqueKey:r,description:o,descriptionVersion:l}),n??null};#m=async({fieldName:t,field:e,operationType:a,rootTypeName:s,inputTypes:o,returnTypes:r,description:l,descriptionUniqueKey:c,descriptionVersion:i})=>{const n=t,p=`${c}-${f(`${a.toLowerCase()}-${t}`)}`,h={type:"api-operation",key:p,title:n,summary:e.description?F(e.description):null,tags:["graphql"],metadata:{method:a,path:`${s}.${t}`,payload:o,responses:r},version:i};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:h,sourceFile:l.realRelativePath,fileHash:l.hash}),p};#u=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:s,description:o,descriptionVersion:r})=>{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"partOf",targetKey:s,fileHash:o.hash,sourceVersion:r,targetVersion:r});const l=[...new Set(e)],c=[...new Set(a)],i=[...l.map(n=>({key:n,relationType:"uses"})),...c.map(n=>({key:n,relationType:"returns"}))];await u(i,E,async({key:n,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:p,targetKey:n,fileHash:o.hash,sourceVersion:r,targetVersion:r})}catch(h){this.#t.warn(`Failed to create relation between operation ${t} and type ${n} (${p}): ${h instanceof Error?h.message:"Unknown error"}`)}})}}export{Q as GraphqlEntitiesExtractor};
3
+ `)};#h=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:n})=>{const r=a.filter(([,s])=>g(s));r.length!==0&&await T(r,I,async([s,o])=>{const c=o.getInterfaces?.()??[];if(!c.length)return;const i=this.#e(s,e);await T([...c],5,async l=>{const h=this.#e(l.name,e);try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:i,type:"implements",targetKey:h,fileHash:t.hash,sourceRevision:n,targetRevision:n})}catch(y){this.#t.warn(`Failed to create 'implements' relation ${i} -> ${h}: ${y instanceof Error?y.message:"Unknown error"}`)}})})};#y=async(t,e,a,n,r,s)=>{const{schema:o}=t,p=this.#i(o);if(p.length===0)return;const i=(await b(p,$,async({fieldName:l,field:h,operationType:y,rootTypeName:f})=>{const d=await this.#f(l,h,y,f,t,e,a,r);d&&s.delete(`${d}:${n}`)},this.#t)).count.failed;i>0&&this.#t.warn(`Operation extraction completed with ${i} failures out of ${p.length} operations for ${e}`)};#f=async(t,e,a,n,r,s,o,p)=>{const{inputTypes:c,returnTypes:i}=this.#o(e,s),l=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:c,returnTypes:i,description:r,descriptionUniqueKey:s,descriptionVersion:o,parentRevision:p});return l.result==="created"&&await this.#m({apiOperationKey:l.entityKey,inputTypes:c,returnTypes:i,descriptionUniqueKey:s,description:r,descriptionVersion:o,parentRevision:p}),l.entityKey??null};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:r,returnTypes:s,description:o,descriptionUniqueKey:p,descriptionVersion:c,parentRevision:i})=>{const l=t,y={type:"api-operation",key:`${p}-${m(`${a.toLowerCase()}-${t}`)}`,title:l,summary:e.description?K(e.description):null,tags:["graphql"],metadata:{method:a,path:`${n}.${t}`,payload:r,responses:s},version:c};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:y,sourceFile:o.realRelativePath,fileHash:o.hash,revision:i})};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:n,description:r,descriptionVersion:s,parentRevision:o})=>{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"partOf",targetKey:n,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:o,targetRevision:o});const p=[...new Set(e)],c=[...new Set(a)],i=[...p.map(l=>({key:l,relationType:"uses"})),...c.map(l=>({key:l,relationType:"returns"}))];await T(i,$,async({key:l,relationType:h})=>{try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:h,targetKey:l,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:o,targetRevision:o})}catch(y){this.#t.warn(`Failed to create relation between operation ${t} and type ${l} (${h}): ${y instanceof Error?y.message:"Unknown error"}`)}})}}export{Q as GraphqlEntitiesExtractor};
@@ -6,7 +6,7 @@ export declare class OpenApiEntitiesExtractor extends BaseApiEntitiesExtractor<B
6
6
  #private;
7
7
  constructor(params: BaseApiEntitiesExtractorParams);
8
8
  loadApiDescriptions(): Promise<BundledDefinition[]>;
9
- mapApiDescriptionToEntity(description: BundledDefinition): EntityFileSchema;
10
- processApiDescription(description: BundledDefinition): Promise<Set<string>>;
9
+ mapApiDescriptionToEntity(description: BundledDefinition, version: string): EntityFileSchema;
10
+ processApiDescription(description: BundledDefinition, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
11
11
  }
12
12
  //# sourceMappingURL=openapi-entities-extractor.d.ts.map
@@ -1 +1 @@
1
- import{removeLeadingSlash as E}from"@redocly/theme/core/utils";import{toKebabCase as h}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as l}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as R}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as p}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as d}from"./base.js";import{OpenapiSchemaResolver as y}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as v}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as S}from"../../../entities/validate-entity.js";import{resolveEntityVersion as N}from"../../../utils/resolve-entity-version.js";import{isValidTagName as u}from"../../../utils/is-valid-tag-name.js";const x=["get","post","put","delete","patch"],g=15,$=15;class j extends d{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return await this.actions.loadOpenApiDefinitions(this.context)}mapApiDescriptionToEntity(e){const o=E(e.realRelativePath),a=e.definition.info.title,n=o.replace(/\.[^.]+$/,""),t=h(n.replace(/[\\/]/g,"-")),s=e.definition["x-redocly-catalog-key"],r=typeof s=="string"&&s.trim()?h(s.trim()):t,c=e.definition.info.version,i=N(c,e.realRelativePath);if(!i.success)throw new Error(`API "${a}" in file "${e.realRelativePath}" has conflicting versions: spec version "${i.fileVersion}" differs from folder version "${i.folderVersion}". Entity will not be created.`);return{type:this.type,key:r,title:a,summary:p(e.definition.info.description),tags:e.definition.tags?.filter(m=>m.name&&u(m.name)).map(m=>m.name),metadata:{specType:this.specType,descriptionFile:o},version:i.version}}async processApiDescription(e){const o=new Set;if(y.clearSchemaCache(),!e?.definition?.paths)return o;const a=this.mapApiDescriptionToEntity(e);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0}),o.add(a.key),await this.#n(e,a.key,a.version,o);const n=this.#s(e.definition.paths);if(n.length!==0){const s=(await R(n,g,async({operation:r,path:c,method:i})=>{if(!r.operationId)return;const m=await this.#r(r,c,i,e,a.key,a.version);m&&o.add(m)},this.#e)).count.failed;s>0&&this.#e.warn(`Extraction completed with ${s} failures out of ${n.length} operations for ${a.key}`)}return o}#s(e){return Object.entries(e).flatMap(([o,a])=>x.filter(n=>a[n]).map(n=>{const t=a[n];if(!t)throw new Error(`Operation not found for method ${n} on path ${o}`);return{operation:t,path:o,method:n.toUpperCase()}}))}async#n(e,o,a,n){const t=e.definition.components?.schemas;if(!t)return;const s=Object.entries(t);s.length!==0&&await l(s,$,async([r,c])=>{const i=await this.#o({schemaName:r,schema:c,description:e,parentKey:o,parentVersion:a});n.add(i),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,type:"uses",targetKey:i,sourceVersion:a,targetVersion:a,fileHash:e.hash})})}async#o({schemaName:e,schema:o,description:a,parentKey:n,parentVersion:t}){const s=y.resolveSchemaRefs(o,a),r=JSON.stringify(s),c={type:"data-schema",key:`${n}-${h(e)}`,title:e,summary:s.description??s.title??null,tags:[],metadata:{specType:this.specType,schema:r},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:a.realRelativePath,fileHash:a.hash}),c.key}async#r(e,o,a,n,t,s){const[r,c]=await Promise.all([this.#i(e,n,t,s),this.#c(e,n,t,s)]),i=await this.#l({path:o,method:a,operation:e,requestBodySchemasKeys:r,responseSchemasKeys:c,description:n,parentKey:t,parentVersion:s});return await this.#p({apiOperationKey:i,operationRelations:e["x-catalog-relations"],descriptionUniqueKey:t,description:n,parentVersion:s}),i??null}async#i(e,o,a,n){if(!e.requestBody||!e.operationId)return[];const t=this.#m(e.requestBody,o);return t.errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${t.errors.join(", ")}`),await this.#a(t.schemaNames,e.operationId,o.hash,a,n)}async#c(e,o,a,n){if(!e.responses||!e.operationId)return[];const t=this.#h(e.responses,o);return t.errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${t.errors.join(", ")}`),await this.#a(t.schemaNames,e.operationId,o.hash,a,n)}#m(e,o){const a=[],n=[];try{if(e&&"content"in e&&e.content)for(const t of Object.values(e.content)){if(!t.schema?.$ref)continue;const s=this.#t(t.schema.$ref);s?.componentType==="schemas"&&s.componentName&&a.push(s.componentName)}if(e&&e.$ref){const t=this.#t(e.$ref);if(t?.componentType==="requestBodies"&&t.componentName){const s=o.definition.components?.requestBodies?.[t.componentName];if(s&&"content"in s)for(const r of Object.values(s.content??{})){if(!r.schema?.$ref)continue;const c=this.#t(r.schema.$ref);c?.componentType==="schemas"&&c.componentName&&a.push(c.componentName)}}}}catch(t){n.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(a)],errors:n}}#h(e,o){const a=[],n=[];try{for(const t of Object.values(e)){if(t&&"content"in t&&t.content)for(const s of Object.values(t.content)){if(!s.schema?.$ref)continue;const r=this.#t(s.schema.$ref);r?.componentType==="schemas"&&r.componentName&&a.push(r.componentName)}if(t&&t.$ref){const s=this.#t(t.$ref);if(s?.componentType==="responses"&&s.componentName){const r=o.definition.components?.responses?.[s.componentName];if(r&&"content"in r)for(const c of Object.values(r.content??{})){if(!c.schema?.$ref)continue;const i=this.#t(c.schema.$ref);i?.componentType==="schemas"&&i.componentName&&a.push(i.componentName)}}}}}catch(t){n.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(a)],errors:n}}#t(e){try{return v(e)}catch{return{componentType:"",componentName:null}}}async#a(e,o,a,n,t){return e.length===0?[]:await l(e,$,async s=>await this.#f({operationId:o,schemaName:s,descriptionHash:a,parentKey:n,parentVersion:t}))}async#f({operationId:e,schemaName:o,descriptionHash:a,parentKey:n,parentVersion:t}){const s=`${n}-${h(o)}`;try{return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:`${n}-${h(e)}`,type:"uses",targetKey:s,fileHash:a,sourceVersion:t,targetVersion:t}),s}catch(r){throw this.#e.error(`Failed to create relation between operation ${e} and schema ${o}: ${r instanceof Error?r.message:"Unknown error"}`),r}}async#l({path:e,method:o,operation:a,requestBodySchemasKeys:n,responseSchemasKeys:t,description:s,parentKey:r,parentVersion:c}){const i=`${a.operationId}`,m=`${r}-${h(i)}`,w={type:"api-operation",key:m,title:i,summary:p(a.summary),tags:a.tags?.filter(f=>u(f)),metadata:{path:e,method:o,payload:n,responses:t},version:c};try{return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:w,sourceFile:s.realRelativePath,fileHash:s.hash}),m}catch(f){throw this.#e.error(`Failed to create API operation entity for ${i}: ${f instanceof Error?f.message:"Unknown error"}`),f}}async#p({apiOperationKey:e,operationRelations:o,descriptionUniqueKey:a,description:n,parentVersion:t}){try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:a,fileHash:n.hash,sourceVersion:t,targetVersion:t}),await this.#y(e,o,t)}catch(s){this.#e.error(`Failed to create API operation relations for ${e}: ${s instanceof Error?s.message:"Unknown error"}`)}}async#y(e,o,a){o?.length&&await l(o,g,async n=>{try{S(n),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:n.type,targetKey:n.key,sourceVersion:a,targetVersion:a})}catch(t){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${t instanceof Error?t.message:"Unknown error"}`)}})}}export{j as OpenApiEntitiesExtractor};
1
+ import{removeLeadingSlash as S}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as u}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as O}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as g}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as d}from"./base.js";import{OpenapiSchemaResolver as $}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as N}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as x}from"../../../entities/validate-entity.js";import{isValidTagName as E}from"../../../utils/is-valid-tag-name.js";const v=["get","post","put","delete","patch"],w=15,R=15;class F extends d{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return await this.actions.loadOpenApiDefinitions(this.context)}mapApiDescriptionToEntity(e,o){const s=S(e.realRelativePath),n=e.definition.info.title,t=s.replace(/\.[^.]+$/,""),a=p(t.replace(/[\\/]/g,"-")),r=e.definition["x-redocly-catalog-key"],i=typeof r=="string"&&r.trim()?p(r.trim()):a;return{type:this.type,key:i,title:n,summary:g(e.definition.info.description),tags:e.definition.tags?.filter(c=>c.name&&E(c.name)).map(c=>c.name),metadata:{specType:this.specType,descriptionFile:s},version:o}}async processApiDescription(e,o,s,n){if($.clearSchemaCache(),!e?.definition?.paths)return;const t=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:t,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,revision:o}),n.delete(`${t.key}:${s}`),await this.#n(e,t.key,t.version,s,o,n);const a=this.#s(e.definition.paths);if(a.length!==0){const i=(await O(a,w,async({operation:c,path:h,method:l})=>{if(!c.operationId)return;const f=await this.#r(c,h,l,e,t.key,t.version,o);f&&n.delete(`${f}:${s}`)},this.#e)).count.failed;i>0&&this.#e.warn(`Extraction completed with ${i} failures out of ${a.length} operations for ${t.key}`)}}#s(e){return Object.entries(e).flatMap(([o,s])=>v.filter(n=>s[n]).map(n=>{const t=s[n];if(!t)throw new Error(`Operation not found for method ${n} on path ${o}`);return{operation:t,path:o,method:n.toUpperCase()}}))}async#n(e,o,s,n,t,a){const r=e.definition.components?.schemas;if(!r)return;const i=Object.entries(r);i.length!==0&&await u(i,R,async([c,h])=>{const l=await this.#o({schemaName:c,schema:h,description:e,parentKey:o,parentVersion:s,parentRevision:t});a.delete(`${l.entityKey}:${n}`),l.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,sourceVersion:s,sourceRevision:t,type:"uses",targetKey:l.entityKey,targetVersion:s,targetRevision:t,fileHash:e.hash})})}async#o({schemaName:e,schema:o,description:s,parentKey:n,parentVersion:t,parentRevision:a}){const r=$.resolveSchemaRefs(o,s),i=JSON.stringify(r),c={type:"data-schema",key:`${n}-${p(e)}`,title:e,summary:r.description??r.title??null,tags:[],metadata:{specType:this.specType,schema:i},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:s.realRelativePath,fileHash:s.hash,revision:a})}async#r(e,o,s,n,t,a,r){const i=await Promise.all([this.#h(e.requestBody??null,n),this.#m(e.responses??{},n)]),c=i[0].schemaNames,h=i[1].schemaNames;i[0].errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${i[0].errors.join(", ")}`),i[1].errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${i[1].errors.join(", ")}`);const l=c.map(y=>`${t}-${p(y)}`),f=h.map(y=>`${t}-${p(y)}`),m=await this.#p({path:o,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:f,description:n,parentKey:t,parentVersion:a,parentRevision:r});return m.result==="created"&&await Promise.all([this.#i(c,e.operationId??"",n.hash,t,a,r),this.#c(h,e.operationId??"",n.hash,t,a,r),this.#f({apiOperationKey:m.entityKey,operationRelations:e["x-catalog-relations"],descriptionUniqueKey:t,description:n,parentVersion:a,parentRevision:r})]),m.entityKey??null}async#i(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}async#c(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}#h(e,o){const s=[],n=[];try{if(e&&"content"in e&&e.content)for(const t of Object.values(e.content)){if(!t.schema?.$ref)continue;const a=this.#t(t.schema.$ref);a?.componentType==="schemas"&&a.componentName&&s.push(a.componentName)}if(e&&e.$ref){const t=this.#t(e.$ref);if(t?.componentType==="requestBodies"&&t.componentName){const a=o.definition.components?.requestBodies?.[t.componentName];if(a&&"content"in a)for(const r of Object.values(a.content??{})){if(!r.schema?.$ref)continue;const i=this.#t(r.schema.$ref);i?.componentType==="schemas"&&i.componentName&&s.push(i.componentName)}}}}catch(t){n.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#m(e,o){const s=[],n=[];try{for(const t of Object.values(e)){if(t&&"content"in t&&t.content)for(const a of Object.values(t.content)){if(!a.schema?.$ref)continue;const r=this.#t(a.schema.$ref);r?.componentType==="schemas"&&r.componentName&&s.push(r.componentName)}if(t&&t.$ref){const a=this.#t(t.$ref);if(a?.componentType==="responses"&&a.componentName){const r=o.definition.components?.responses?.[a.componentName];if(r&&"content"in r)for(const i of Object.values(r.content??{})){if(!i.schema?.$ref)continue;const c=this.#t(i.schema.$ref);c?.componentType==="schemas"&&c.componentName&&s.push(c.componentName)}}}}}catch(t){n.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#t(e){try{return N(e)}catch{return{componentType:"",componentName:null}}}async#a(e,o,s,n,t,a){return e.length===0?[]:await u(e,R,async r=>await this.#l({operationId:o,schemaName:r,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}))}async#l({operationId:e,schemaName:o,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}){const r=`${n}-${p(o)}`;try{return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:`${n}-${p(e)}`,type:"uses",targetKey:r,fileHash:s,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),r}catch(i){throw this.#e.error(`Failed to create relation between operation ${e} and schema ${o}: ${i instanceof Error?i.message:"Unknown error"}`),i}}async#p({path:e,method:o,operation:s,requestBodySchemasKeys:n,responseSchemasKeys:t,description:a,parentKey:r,parentVersion:i,parentRevision:c}){const h=`${s.operationId}`,f={type:"api-operation",key:`${r}-${p(h)}`,title:h,summary:g(s.summary),tags:s.tags?.filter(m=>E(m)),metadata:{path:e,method:o,payload:n,responses:t},version:i};try{return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:f,sourceFile:a.realRelativePath,fileHash:a.hash,revision:c})}catch(m){throw this.#e.error(`Failed to create API operation entity for ${h}: ${m instanceof Error?m.message:"Unknown error"}`),m}}async#f({apiOperationKey:e,operationRelations:o,descriptionUniqueKey:s,description:n,parentVersion:t,parentRevision:a}){try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:s,fileHash:n.hash,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),await this.#y(e,o,t,a)}catch(r){this.#e.error(`Failed to create API operation relations for ${e}: ${r instanceof Error?r.message:"Unknown error"}`)}}async#y(e,o,s,n){o?.length&&await u(o,w,async t=>{try{x(t),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:t.type,targetKey:t.key,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n})}catch(a){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${a instanceof Error?a.message:"Unknown error"}`)}})}}export{F as OpenApiEntitiesExtractor};
@@ -1 +1 @@
1
- import{CATALOG_ENTITIES_FILES_REGEX as f,ENTITY_SCHEMA_EXCLUDED_FOLDERS as E}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as c,FileType as a}from"../../../../persistence/file-hashes/types.js";import{promiseMapLimit as u}from"../../../../utils/async/promise-map-limit.js";import{extractFileContent as d}from"../../entities/extract-entities-content.js";import{resolveEntityVersion as h}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as g}from"../../entities/validate-entity.js";import{catalogDataCollector as l}from"../../utils/catalog-data-collector.js";const m=15;class D{#e;#t;#i;#r;#s;constructor({fileHashManager:t,context:e,catalogEntitiesService:i,catalogConfig:s,shouldCalculateEntities:o}){this.#e=t,this.#t=e,this.#i=i,this.#r=s,this.#s=o}async extract(t){try{if(t&&this.#o(t)){await this.#n(t);return}await this.#e.markAllAsOutdated(a.ENTITY_DEFINITION);const i=(await this.#t.fs.scan(f)).filter(({relativePath:s})=>this.#o(s));i.length&&l.addExtractor("fs"),await u(i,m,async({relativePath:s})=>{await this.#n(s)}),await this.#f()}catch(e){this.#t.logger.error("Error extracting entities.",e)}}#o=t=>!!(t.match(f)&&!E.some(e=>t.includes(e)));#n=async t=>{try{const e=await d(t,this.#t);if(!e){this.#t.logger.warn(`Error extracting content from ${t}.`);return}const i=await this.#e.computeFileHash(e);if(!((await this.#e.getByPath(t))?.hash!==i||this.#s||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){l.increaseSkippedFilesCount(),await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE);return}const r=this.#a(e.entities,t);if(!r)return;const n=await this.#c(r,t,i);await this.#l(n,t),l.increaseProcessedFilesCount(),await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE)}catch(e){this.#t.logger.warn(`Error processing file "${t}". ${e instanceof Error?e.message:String(e)}.`)}};#a=(t,e)=>{try{return g(t,this.#r)}catch(i){return this.#t.logger.warn(`Error validating entities in "${e}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(t,e,i)=>{const s=new Set;for(const o of t)try{const r=h(o.version,e);if(!r.success){this.#t.logger.warn(`Entity "${o.key}" in file "${e}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...o,version:r.version};await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:e,fileHash:i}),o.key&&s.add(o.key)}catch(r){const n=o.key??"unknown";this.#t.logger.warn(`Error processing entity "${n}" from "${e}". ${r instanceof Error?r.message:String(r)}.`)}return s};#l=async(t,e)=>{t.size!==0&&await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})};#f=async()=>{const t=await this.#e.getAllOutdated(a.ENTITY_DEFINITION);if(!t||t.length===0)return;const e=await this.#i.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});!e||e.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.#e.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:c.OUTDATED}]}))}}export{D as FsEntitiesExtractor};
1
+ import{CATALOG_ENTITIES_FILES_REGEX as E,ENTITY_SCHEMA_EXCLUDED_FOLDERS as d}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as l,FileType as a}from"../../../../persistence/file-hashes/types.js";import{OPERATORS as u}from"../../../../providers/database/pagination/constants.js";import{promiseMapLimit as h}from"../../../../utils/async/promise-map-limit.js";import{VERSION_NOT_SPECIFIED as m}from"@redocly/theme/core/constants";import{extractFileContent as p}from"../../entities/extract-file-content.js";import{resolveEntityVersion as g}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as y}from"../../entities/validate-entity.js";import{catalogDataCollector as f}from"../../utils/catalog-data-collector.js";const I=15;class v{#t;#e;#i;#r;#s;constructor({fileHashManager:e,context:t,catalogEntitiesService:i,catalogConfig:o,shouldCalculateEntities:s}){this.#t=e,this.#e=t,this.#i=i,this.#r=o,this.#s=s}async extract(e){try{if(e&&this.#o(e)){await this.#n(e);return}await this.#t.markAllAsOutdated(a.ENTITY_DEFINITION);const i=this.#e.fs.scan(E).filter(({relativePath:o})=>this.#o(o));i.length&&f.addExtractor("fs"),await h(i,I,async({relativePath:o})=>{await this.#n(o)}),await this.#f()}catch(t){this.#e.logger.error("Error extracting entities.",t)}}#o=e=>!!(e.match(E)&&!d.some(t=>e.includes(t)));#n=async e=>{try{const t=await p(e,this.#e);if(!t){this.#e.logger.warn(`Error extracting content from ${e}.`);return}const i=await this.#t.computeFileHash(t);if(!((await this.#t.getByPath(e))?.hash!==i||this.#s||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){f.increaseSkippedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE);return}const r=this.#a(t.entities,e);if(!r)return;const n=await this.#i.getEntityKeysAndVersionsBySourceFile(e);await this.#c(r,e,i,n),await this.#l(n,e),f.increaseProcessedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE)}catch(t){this.#e.logger.warn(`Error processing file "${e}". ${t instanceof Error?t.message:String(t)}.`)}};#a=(e,t)=>{try{return y(e,this.#r)}catch(i){return this.#e.logger.warn(`Error validating entities in "${t}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(e,t,i,o)=>{for(const s of e)try{const r=g(s.version,t);if(!r.success){this.#e.logger.warn(`Entity "${s.key}" in file "${t}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...s,version:r.version};if(await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:t,fileHash:i}),s.key){const c=r.version??m;o.delete(`${s.key}:${c}`)}}catch(r){const n=s.key??"unknown";this.#e.logger.warn(`Error processing entity "${n}" from "${t}". ${r instanceof Error?r.message:String(r)}.`)}};#l=async(e,t)=>{if(e.size===0)return;const i=Array.from(e).map(r=>{const[n,c]=r.split(":");return{key:n,version:c}}),o=Array.from(new Set(i.map(({key:r})=>r))),s=i.map(({key:r,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:r},{field:"version",operator:"equal",value:n}]}));await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:s},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:t}]})};#f=async()=>{const e=await this.#t.getAllOutdated(a.ENTITY_DEFINITION);if(!e||e.length===0)return;const t=await this.#i.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:e.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});!t||t.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:t.items.map(({key:i})=>i)}),await this.#t.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:l.OUTDATED}]}))}}export{v as FsEntitiesExtractor};
@@ -1,7 +1,6 @@
1
- import type { BffCatalogEntity, BffCatalogEntityList, BffCatalogRelatedEntity, BffCatalogRelatedEntityList, CatalogSwitcherItem, CatalogViewMode } from '@redocly/theme/core/types';
1
+ import type { BffCatalogEntity, BffCatalogEntityList, BffCatalogRelatedEntity, BffCatalogRelatedEntityList, CatalogSwitcherItem, CatalogViewMode, CatalogFiltersWithCounts } from '@redocly/theme/core/types';
2
2
  import type { EntitiesCatalogConfig, CatalogEntityConfig } from '@redocly/config';
3
3
  import type { GetServerPropsFn } from '../../types/plugins/common';
4
- import type { CatalogFiltersWithCounts } from '@redocly/theme/core/types';
5
4
  export type ServerSideProps = {
6
5
  status: 'success';
7
6
  entitiesTypes: string[];
@@ -1 +1 @@
1
- import{sha1 as E}from"../../utils/crypto/sha1.js";import{CatalogEntitiesService as h}from"./database/catalog-entities-service.js";import{createPaginationParamsValidator as w}from"../../providers/database/pagination/schemas";import{parseSearch as F}from"../../providers/database/pagination/search";import{OPERATORS as v}from"../../providers/database/pagination/constants.js";import{CacheService as A}from"../../persistence/cache/services/cache-service.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as b,CATALOG_FILTERS_CACHE_TTL_IN_SECONDS as I}from"../../constants/plugins/catalog-entities.js";const x={all:"all",domains:"domain",services:"service",teams:"team",users:"user","api-descriptions":"api-description","data-schemas":"data-schema"},T={team:{field:"type",operator:"equal",value:"user"},"api-description":{field:"type",operator:"equal",value:"api-operation"}},D=async({entitiesTypes:e,serverOutDir:a,catalogConfig:t,queries:o={}})=>{const p=await h.getInstance({baseDbDir:a}),r=M.concat("domains","owners"),l=w(r).parse(o),d=t.excludes?.map(s=>s.key)??[],u=e.filter(s=>s!=="all"),n=V(u,d);return l.filter?l.filter={op:v.AND,conditions:[l.filter,n]}:l.filter=n,await p.getEntitiesWithRelations({sort:[{field:"type",order:"ASC"}],limit:10,...l})},P=async(e,a,t)=>{const o=await h.getInstance({baseDbDir:a}),p=w(["version","revision"]).parse(t??{}),r=await o.getEntityWithRelationsByKey(e,p);if(!r)return null;const l=r.type==="data-schema"?await o.getRelatedEntities(e,{limit:1,filter:{field:"type",operator:"equal",value:"api-description"}}).then(n=>n.items?.[0]??null):null,d=T[r.type]??void 0,u=await o.getRelatedEntities(e,{limit:10,sort:[{field:"title",order:"ASC"}],filter:d,search:t?.search?F(t?.search,["key","type","title","summary"]):void 0});return{status:"success",entity:r,relatedEntity:l,relations:u}},R=e=>{const a=JSON.stringify({entitiesTypes:e.entitiesTypes.sort(),filtersConfig:e.filtersConfig});return E(a)},_=async({serverOutDir:e,entitiesTypes:a,filtersConfig:t})=>{if(!t||t.length===0)return{};const o=R({entitiesTypes:a,filtersConfig:t}),p=await A.getInstance({baseDbDir:e}),r=await p.get({key:o,namespace:b});if(r)return r;const l=await h.getInstance({baseDbDir:e}),d=[],u=new Map;for(const s of t)!s.options||s.options.length===0?d.push(s.property):u.set(s.property,s.options);const n=await l.getCatalogFilters({entitiesTypes:a,emptyFilters:d}),c={};for(const s of t){const g=u.get(s.property);if(!g){const i=n[s.property];c[s.property]=i&&i.length>0?i:[];continue}const m=(await l.getCatalogFilters({entitiesTypes:a,emptyFilters:[s.property]}))[s.property];if(!m){c[s.property]=[];continue}const f=new Map;for(const i of m){const y=i.value.toLowerCase().trim();f.set(y,{originalValue:i.value,count:i.count})}c[s.property]=g.map(i=>{const y=i.toLowerCase().trim(),S=f.get(y);return{value:S?.originalValue??i,count:S?.count??0}}).filter(i=>i.count>0).sort((i,y)=>i.value.localeCompare(y.value))}return await p.set({key:o,value:c,namespace:b,ttlInSeconds:I}),c},L=async(e,{props:a},t,{serverOutDir:o,getRouteSharedDataByFsPath:p})=>{const r=a?.catalogConfig||{};if(!e.params||!a?.catalogConfig)return{status:"notFound"};const[l,d,u]=e.params;if(!l)return{status:"notFound"};const n=N(r,l),c=n?.includes?.map(f=>f.type)??[];if(!n)return{status:"notFound"};if(!u&&d!=="entities"){if(n.hide)return{status:"notFound"};const f=await _({entitiesTypes:c,serverOutDir:o,filtersConfig:n.filters}),i=e.queries?.viewMode??"table";return{status:"success",catalogSwitcherItems:O(r,n),entitiesTypes:c,entities:await D({entitiesTypes:c,serverOutDir:o,catalogConfig:n,queries:e.queries}),catalogConfig:n,filters:f,initialViewMode:i}}const s=await P(u,o,e.queries),g=s?.entity.sourceFile,C=s?.entity.type==="api-description",m=g&&C&&p(g)||{};return s?{status:"success",entity:s.entity,relatedEntity:s.relatedEntity,relations:s.relations,entitiesCatalogConfig:r,catalogConfig:n,sharedDataIds:m}:{status:"notFound"}},N=(e,a)=>Object.values(e.catalogs??{}).find(t=>t&&typeof t=="object"&&"slug"in t&&t.slug===a),O=(e,a)=>Object.values(e.catalogs??{}).filter(t=>!t?.hide).map(t=>({labelTranslationKey:t?.catalogSwitcherLabelTranslationKey??t?.slug??"",slug:t?.slug??"",selected:t?.slug===a.slug})).sort((t,o)=>t.slug.localeCompare(o.slug)),V=(e,a)=>({op:"AND",conditions:[...e.length?[{field:"type",operator:"in",value:e}]:[],...a.length?[{field:"key",operator:"in",value:a,modifier:"not"}]:[]]}),M=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"];var z=L;export{z as default};
1
+ import{sha1 as b}from"../../utils/crypto/sha1.js";import{isValidSanitizedString as E}from"../../utils/validate-and-sanitize-string";import{CatalogEntitiesService as h}from"./database/catalog-entities-service.js";import{createPaginationParamsValidator as F}from"../../providers/database/pagination/schemas";import{parseSearch as A}from"../../providers/database/pagination/search";import{OPERATORS as C}from"../../providers/database/pagination/constants.js";import{CacheService as I}from"../../persistence/cache/services/cache-service.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as w,CATALOG_FILTERS_CACHE_TTL_IN_SECONDS as D}from"../../constants/plugins/catalog-entities.js";import{isValidIsoDate as T}from"../../utils/is-valid-iso-date.js";const Z={all:"all",domains:"domain",services:"service",teams:"team",users:"user","api-descriptions":"api-description","data-schemas":"data-schema"},R={team:{field:"type",operator:"equal",value:"user"},"api-description":{field:"type",operator:"equal",value:"api-operation"}},V=async({entitiesTypes:e,serverOutDir:s,catalogConfig:t,queries:a={}})=>{const n=await h.getInstance({baseDbDir:s}),c=K.concat("domains","owners"),r=F(c).parse(a),p=t.excludes?.map(i=>i.key)??[],d=e.filter(i=>i!=="all"),l=k(d,p);return r.filter?r.filter={op:C.AND,conditions:[r.filter,l]}:r.filter=l,await n.getEntitiesWithRelations({sort:[{field:"type",order:"ASC"}],limit:10,...r})},_=async(e,s,t)=>{const a=await h.getInstance({baseDbDir:s});let n=null;const c=t?.revision;c&&T(c)&&(n=c);const r=t?.version;if(!E(r,{pattern:/^[a-zA-Z0-9._-]+$/,maxLength:100,allowEmpty:!0}))return null;const p=await a.getEntityWithRelationsByKey(e,{revision:n,version:r});if(!p)return null;const d=p.type==="data-schema"?await a.getRelatedEntities(e,{limit:1,filter:{field:"type",operator:"equal",value:"api-description"}}).then(f=>f.items?.[0]??null):null,l=R[p.type]??void 0,u=q(l,r,n),i=await a.getRelatedEntities(e,{limit:10,sort:[{field:"title",order:"ASC"}],filter:u,search:t?.search?A(t?.search,["key","type","title","summary"]):void 0});return{status:"success",entity:p,relatedEntity:d,relations:i}},N=e=>{const s=JSON.stringify({entitiesTypes:e.entitiesTypes.sort(),filtersConfig:e.filtersConfig});return b(s)},P=async({serverOutDir:e,entitiesTypes:s,filtersConfig:t})=>{if(!t||t.length===0)return{};const a=N({entitiesTypes:s,filtersConfig:t}),n=await I.getInstance({baseDbDir:e}),c=await n.get({key:a,namespace:w});if(c)return c;const r=await h.getInstance({baseDbDir:e}),p=[],d=new Map;for(const i of t)!i.options||i.options.length===0?p.push(i.property):d.set(i.property,i.options);const l=await r.getCatalogFilters({entitiesTypes:s,emptyFilters:p}),u={};for(const i of t){const f=d.get(i.property);if(!f){const o=l[i.property];u[i.property]=o&&o.length>0?o:[];continue}const y=(await r.getCatalogFilters({entitiesTypes:s,emptyFilters:[i.property]}))[i.property];if(!y){u[i.property]=[];continue}const g=new Map;for(const o of y){const m=o.value.toLowerCase().trim();g.set(m,{originalValue:o.value,count:o.count})}u[i.property]=f.map(o=>{const m=o.toLowerCase().trim(),S=g.get(m);return{value:S?.originalValue??o,count:S?.count??0}}).filter(o=>o.count>0).sort((o,m)=>o.value.localeCompare(m.value))}return await n.set({key:a,value:u,namespace:w,ttlInSeconds:D}),u},L=async(e,{props:s},t,{serverOutDir:a,getRouteSharedDataByFsPath:n})=>{const c=s?.catalogConfig||{};if(!e.params||!s?.catalogConfig)return{status:"notFound"};const[r,p,d]=e.params;if(!r)return{status:"notFound"};const l=O(c,r),u=l?.includes?.map(g=>g.type)??[];if(!l)return{status:"notFound"};if(!d&&p!=="entities"){if(l.hide)return{status:"notFound"};const g=await P({entitiesTypes:u,serverOutDir:a,filtersConfig:l.filters}),o=e.queries?.viewMode??"table";return{status:"success",catalogSwitcherItems:M(c,l),entitiesTypes:u,entities:await V({entitiesTypes:u,serverOutDir:a,catalogConfig:l,queries:e.queries}),catalogConfig:l,filters:g,initialViewMode:o}}const i=await _(d,a,e.queries),f=i?.entity.sourceFile,v=i?.entity.type==="api-description",y=f&&v&&n(f)||{};return i?{status:"success",entity:i.entity,relatedEntity:i.relatedEntity,relations:i.relations,entitiesCatalogConfig:c,catalogConfig:l,sharedDataIds:y}:{status:"notFound"}},O=(e,s)=>Object.values(e.catalogs??{}).find(t=>t&&typeof t=="object"&&"slug"in t&&t.slug===s),M=(e,s)=>Object.values(e.catalogs??{}).filter(t=>!t?.hide).map(t=>({labelTranslationKey:t?.catalogSwitcherLabelTranslationKey??t?.slug??"",slug:t?.slug??"",selected:t?.slug===s.slug})).sort((t,a)=>t.slug.localeCompare(a.slug)),k=(e,s)=>({op:"AND",conditions:[...e.length?[{field:"type",operator:"in",value:e}]:[],...s.length?[{field:"key",operator:"in",value:s,modifier:"not"}]:[]]}),q=(e,s,t)=>{let a=e;if(s!==void 0){const n={field:"version",operator:"equal",value:s};a=a?{op:C.AND,conditions:[a,n]}:n}if(t){const n={field:"revision",operator:"equal",value:t};a=a?{op:C.AND,conditions:[a,n]}:n}return a},K=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"];var $=L;export{$ as default};
@@ -126,6 +126,9 @@ export declare const entityDatabaseSchema: {
126
126
  readonly is_default_version: {
127
127
  readonly type: readonly ["boolean", "null"];
128
128
  };
129
+ readonly is_deleted: {
130
+ readonly type: readonly ["boolean", "null"];
131
+ };
129
132
  };
130
133
  readonly required: readonly ["id", "organization_id", "project_id", "key", "type", "title", "created_at", "updated_at", "source"];
131
134
  readonly additionalProperties: false;
@@ -177,7 +180,68 @@ export declare const relatedEntityDatabaseSchema: {
177
180
  readonly required: readonly ["id", "key", "title", "type", "source"];
178
181
  readonly additionalProperties: false;
179
182
  };
183
+ /**
184
+ * Schema for "query rows" coming from SQL/drizzle selects (joins/unions), normalized to a stable
185
+ * snake_case shape in mappers before validating.
186
+ */
187
+ export declare const relatedEntityQueryRowDatabaseSchema: {
188
+ readonly type: "object";
189
+ readonly properties: {
190
+ readonly id: {
191
+ readonly type: "string";
192
+ readonly minLength: 1;
193
+ };
194
+ readonly key: {
195
+ readonly type: "string";
196
+ readonly minLength: 1;
197
+ };
198
+ readonly title: {
199
+ readonly type: "string";
200
+ readonly minLength: 1;
201
+ };
202
+ readonly type: {
203
+ readonly type: "string";
204
+ readonly minLength: 1;
205
+ };
206
+ readonly summary: {
207
+ readonly type: readonly ["string", "null"];
208
+ };
209
+ readonly source: {
210
+ readonly type: "string";
211
+ readonly minLength: 1;
212
+ };
213
+ readonly source_file: {
214
+ readonly type: readonly ["string", "null"];
215
+ };
216
+ readonly created_at: {
217
+ readonly type: readonly ["string", "null"];
218
+ };
219
+ readonly updated_at: {
220
+ readonly type: readonly ["string", "null"];
221
+ };
222
+ readonly metadata: {
223
+ readonly type: readonly ["string", "object", "null"];
224
+ };
225
+ readonly version: {
226
+ readonly type: readonly ["string", "null"];
227
+ };
228
+ readonly revision: {
229
+ readonly type: readonly ["string", "null"];
230
+ };
231
+ readonly direction: {
232
+ readonly type: "string";
233
+ readonly enum: readonly ["outgoing", "incoming"];
234
+ };
235
+ readonly relation_field: {
236
+ readonly type: "string";
237
+ readonly minLength: 1;
238
+ };
239
+ };
240
+ readonly required: readonly ["id", "key", "title", "type", "source", "direction", "relation_field"];
241
+ readonly additionalProperties: false;
242
+ };
180
243
  export type EntityRelationDto = FromSchema<typeof entityRelationDatabaseSchema>;
181
244
  export type EntityDto = FromSchema<typeof entityDatabaseSchema>;
182
245
  export type RelatedEntityDto = FromSchema<typeof relatedEntityDatabaseSchema>;
246
+ export type RelatedEntityQueryRowDto = FromSchema<typeof relatedEntityQueryRowDatabaseSchema>;
183
247
  //# sourceMappingURL=database-schemas.d.ts.map
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const r={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1};export{i as entityDatabaseSchema,r as entityRelationDatabaseSchema,n as relatedEntityDatabaseSchema};
1
+ import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]},is_deleted:{type:["boolean","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},r={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1},s={type:"object",properties:{id:{type:"string",minLength:1},key:{type:"string",minLength:1},title:{type:"string",minLength:1},type:{type:"string",minLength:1},summary:{type:["string","null"]},source:{type:"string",minLength:1},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","object","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},direction:{type:"string",enum:["outgoing","incoming"]},relation_field:{type:"string",minLength:1}},required:["id","key","title","type","source","direction","relation_field"],additionalProperties:!1};export{n as entityDatabaseSchema,i as entityRelationDatabaseSchema,r as relatedEntityDatabaseSchema,s as relatedEntityQueryRowDatabaseSchema};
@@ -17,18 +17,12 @@ export declare const entityRelationDtoSchema: {
17
17
  readonly minLength: 2;
18
18
  readonly maxLength: 150;
19
19
  };
20
- readonly sourceId: {
21
- readonly type: readonly ["string", "null"];
22
- };
23
20
  readonly sourceVersion: {
24
21
  readonly type: readonly ["string", "null"];
25
22
  };
26
23
  readonly sourceRevision: {
27
24
  readonly type: readonly ["string", "null"];
28
25
  };
29
- readonly targetId: {
30
- readonly type: readonly ["string", "null"];
31
- };
32
26
  readonly targetVersion: {
33
27
  readonly type: readonly ["string", "null"];
34
28
  };
@@ -41,6 +35,9 @@ export declare const entityRelationDtoSchema: {
41
35
  readonly fileHash: {
42
36
  readonly type: readonly ["string", "null"];
43
37
  };
38
+ readonly isDeleted: {
39
+ readonly type: readonly ["boolean", "null"];
40
+ };
44
41
  };
45
42
  readonly required: readonly ["type", "sourceKey", "targetKey"];
46
43
  readonly additionalProperties: false;
@@ -64,18 +61,12 @@ export declare const entitiesRelationsDtoSchema: {
64
61
  readonly minLength: 2;
65
62
  readonly maxLength: 150;
66
63
  };
67
- readonly sourceId: {
68
- readonly type: readonly ["string", "null"];
69
- };
70
64
  readonly sourceVersion: {
71
65
  readonly type: readonly ["string", "null"];
72
66
  };
73
67
  readonly sourceRevision: {
74
68
  readonly type: readonly ["string", "null"];
75
69
  };
76
- readonly targetId: {
77
- readonly type: readonly ["string", "null"];
78
- };
79
70
  readonly targetVersion: {
80
71
  readonly type: readonly ["string", "null"];
81
72
  };
@@ -88,6 +79,9 @@ export declare const entitiesRelationsDtoSchema: {
88
79
  readonly fileHash: {
89
80
  readonly type: readonly ["string", "null"];
90
81
  };
82
+ readonly isDeleted: {
83
+ readonly type: readonly ["boolean", "null"];
84
+ };
91
85
  };
92
86
  readonly required: readonly ["type", "sourceKey", "targetKey"];
93
87
  readonly additionalProperties: false;
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceId:{type:["string","null"]},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetId:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},r={type:"array",items:t};export{r as entitiesRelationsDtoSchema,t as entityRelationDtoSchema};
1
+ import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]},isDeleted:{type:["boolean","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},i={type:"array",items:t};export{i as entitiesRelationsDtoSchema,t as entityRelationDtoSchema};