@redocly/realm 0.136.0-next.6 → 0.136.0-next.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/bin.js +1 -1
- package/dist/cli/build/analytics/collect-analytics.js +1 -1
- package/dist/cli/build/index.js +1 -1
- package/dist/cli/eject/resolveEjectParams.js +1 -1
- package/dist/cli/stats/collectors/openapi/index.js +1 -1
- package/dist/cli/stats/index.js +1 -1
- package/dist/client/App.js +1 -1
- package/dist/client/TestProvider.js +1 -1
- package/dist/client/api-docs-builder-entry.d.ts +3 -0
- package/dist/client/api-docs-builder-entry.js +1 -0
- package/dist/client/app/Feedback/useSubmitFeedback.js +1 -1
- package/dist/client/app/Sidebar/Sidebar.js +3 -3
- package/dist/client/app/Sidebar/useActions.js +1 -1
- package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
- package/dist/client/app/hooks/index.d.ts +1 -0
- package/dist/client/app/hooks/index.js +1 -1
- package/dist/client/app/hooks/useAutoScroll.js +1 -1
- package/dist/client/app/hooks/useUserClaims.js +1 -1
- package/dist/client/app/l10n/hooks/index.d.ts +1 -0
- package/dist/client/app/l10n/hooks/index.js +1 -1
- package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
- package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -0
- package/dist/client/app/markdoc/custom-components/openapi/json-schema.d.ts +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/json-schema.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.d.ts +1 -5
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/openapi-example.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -1
- package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.d.ts +8 -24
- package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
- package/dist/client/app/markdoc/hooks/use-store.d.ts +8 -6
- package/dist/client/app/markdoc/utils/build-replay-operation-source-map.d.ts +20 -0
- package/dist/client/app/markdoc/utils/build-replay-operation-source-map.js +1 -0
- package/dist/client/app/markdoc/utils/find-api-item.d.ts +15 -0
- package/dist/client/app/markdoc/utils/find-api-item.js +1 -0
- package/dist/client/app/markdoc/utils/find-code-sample-panel.d.ts +11 -0
- package/dist/client/app/markdoc/utils/find-code-sample-panel.js +1 -0
- package/dist/client/app/markdoc/utils/find-openapi-response-samples.d.ts +15 -0
- package/dist/client/app/markdoc/utils/find-openapi-response-samples.js +1 -0
- package/dist/client/app/markdoc/utils/openapi-panel-entry.d.ts +18 -0
- package/dist/client/app/markdoc/utils/openapi-panel-entry.js +1 -0
- package/dist/client/app/utils/resolveRouteBySlug.js +1 -1
- package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
- package/dist/client/runtime/loader.js +1 -1
- package/dist/client/templates/api-docs/helpers.d.ts +10 -0
- package/dist/client/templates/api-docs/helpers.js +1 -0
- package/dist/client/templates/api-docs/template.d.ts +17 -0
- package/dist/client/templates/api-docs/template.js +14 -0
- package/dist/client/types/sidebar.d.ts +0 -1
- package/dist/client/utils/utils.d.ts +0 -2
- package/dist/client/utils/utils.js +1 -1
- package/dist/constants/common.d.ts +1 -0
- package/dist/constants/common.js +1 -1
- package/dist/constants/l10n/langs/ar.js +1 -1
- package/dist/constants/l10n/langs/de.js +1 -1
- package/dist/constants/l10n/langs/en.js +1 -1
- package/dist/constants/l10n/langs/es.js +1 -1
- package/dist/constants/l10n/langs/fr.js +1 -1
- package/dist/constants/l10n/langs/hi.js +1 -1
- package/dist/constants/l10n/langs/it.js +1 -1
- package/dist/constants/l10n/langs/ja.js +1 -1
- package/dist/constants/l10n/langs/ko.js +1 -1
- package/dist/constants/l10n/langs/pl.js +1 -1
- package/dist/constants/l10n/langs/pt-BR.js +1 -1
- package/dist/constants/l10n/langs/pt.js +1 -1
- package/dist/constants/l10n/langs/ru.js +1 -1
- package/dist/constants/l10n/langs/uk.js +1 -1
- package/dist/constants/l10n/langs/zh.js +1 -1
- package/dist/server/constants/plugins/api-docs.d.ts +3 -0
- package/dist/server/constants/plugins/api-docs.js +1 -0
- package/dist/server/esbuild/esbuild-logger.js +3 -3
- package/dist/server/esbuild/esbuild.js +3 -3
- package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.d.ts +9 -0
- package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-check.js +1 -0
- package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.d.ts +2 -0
- package/dist/server/esbuild/plugins/api-docs-module-replacer/empty-overlay.js +1 -0
- package/dist/server/esbuild/plugins/api-docs-module-replacer/index.d.ts +6 -0
- package/dist/server/esbuild/plugins/api-docs-module-replacer/index.js +1 -0
- package/dist/server/plugins/api-docs/get-server-props.d.ts +4 -0
- package/dist/server/plugins/api-docs/get-server-props.js +1 -0
- package/dist/server/plugins/api-docs/get-template-path.d.ts +2 -0
- package/dist/server/plugins/api-docs/get-template-path.js +1 -0
- package/dist/server/plugins/api-docs/import-api-docs-builder.d.ts +8 -0
- package/dist/server/plugins/api-docs/import-api-docs-builder.js +1 -0
- package/dist/server/plugins/api-docs/index.d.ts +19 -0
- package/dist/server/plugins/api-docs/index.js +1 -0
- package/dist/server/plugins/api-docs/loader.d.ts +35 -0
- package/dist/server/plugins/api-docs/loader.js +3 -0
- package/dist/server/plugins/api-docs/options.d.ts +14 -0
- package/dist/server/plugins/api-docs/options.js +1 -0
- package/dist/server/plugins/api-docs/search/get-ai-search-documents.d.ts +20 -0
- package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +105 -0
- package/dist/server/plugins/api-docs/search/search-facets.d.ts +10 -0
- package/dist/server/plugins/api-docs/search/search-facets.js +1 -0
- package/dist/server/plugins/api-docs/search/search-indexer.d.ts +9 -0
- package/dist/server/plugins/api-docs/search/search-indexer.js +1 -0
- package/dist/server/plugins/api-docs/search/search-resolver.d.ts +5 -0
- package/dist/server/plugins/api-docs/search/search-resolver.js +1 -0
- package/dist/server/plugins/api-docs/spec-download.api.d.ts +4 -0
- package/dist/server/plugins/api-docs/spec-download.api.js +1 -0
- package/dist/server/plugins/api-docs/store-definition-bundles.d.ts +3 -0
- package/dist/server/plugins/api-docs/store-definition-bundles.js +1 -0
- package/dist/server/plugins/api-docs/utils/build-item-positions.d.ts +17 -0
- package/dist/server/plugins/api-docs/utils/build-item-positions.js +1 -0
- package/dist/server/plugins/api-docs/utils/build-routes-mapping.d.ts +3 -0
- package/dist/server/plugins/api-docs/utils/build-routes-mapping.js +1 -0
- package/dist/server/plugins/api-docs/utils/collect-item-routes.d.ts +12 -0
- package/dist/server/plugins/api-docs/utils/collect-item-routes.js +1 -0
- package/dist/server/plugins/api-docs/utils/decorators.d.ts +26 -0
- package/dist/server/plugins/api-docs/utils/decorators.js +1 -0
- package/dist/server/plugins/api-docs/utils/format-bundle-error.d.ts +6 -0
- package/dist/server/plugins/api-docs/utils/format-bundle-error.js +5 -0
- package/dist/server/plugins/api-docs/utils/normalize-api-version.d.ts +2 -0
- package/dist/server/plugins/api-docs/utils/normalize-api-version.js +1 -0
- package/dist/server/plugins/api-docs/utils/normalize-feedback-options.d.ts +2 -0
- package/dist/server/plugins/api-docs/utils/normalize-feedback-options.js +1 -0
- package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.d.ts +20 -0
- package/dist/server/plugins/api-docs/utils/relative-path-to-base-slug.js +1 -0
- package/dist/server/plugins/api-docs/utils/replace-file-extension.d.ts +2 -0
- package/dist/server/plugins/api-docs/utils/replace-file-extension.js +1 -0
- package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.d.ts +3 -0
- package/dist/server/plugins/api-docs/utils/resolve-api-doc-title.js +1 -0
- package/dist/server/plugins/api-docs/utils/resolve-config-rbac.d.ts +10 -0
- package/dist/server/plugins/api-docs/utils/resolve-config-rbac.js +1 -0
- package/dist/server/plugins/api-docs/utils/to-relative-slug.d.ts +2 -0
- package/dist/server/plugins/api-docs/utils/to-relative-slug.js +1 -0
- package/dist/server/plugins/api-functions/index.js +1 -1
- package/dist/server/plugins/arazzo-docs/index.js +1 -1
- package/dist/server/plugins/asyncapi-docs/index.js +1 -1
- package/dist/server/plugins/catalog-classic/index.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +13 -5
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +6 -5
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +12 -5
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/catalog-entities/template/index.js +1 -1
- package/dist/server/plugins/catalog-entities/types/openapi.d.ts +1 -1
- package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.d.ts +3 -3
- package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.d.ts +4 -3
- package/dist/server/plugins/catalog-entities/utils/openapi-schema-resolver.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/create-slugify.d.ts +17 -0
- package/dist/server/plugins/create-slugify.js +1 -0
- package/dist/server/plugins/default-theme/index.js +1 -1
- package/dist/server/plugins/dev-onboarding/index.js +1 -1
- package/dist/server/plugins/entitlements/index.js +1 -1
- package/dist/server/plugins/graphql-docs/index.js +1 -1
- package/dist/server/plugins/helpers/parse-partials.d.ts +3 -0
- package/dist/server/plugins/helpers/parse-partials.js +1 -0
- package/dist/server/plugins/l10n/index.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.d.ts +5 -3
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/load-openapi-bundle.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-open-api-ref.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-code-samples.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-openapi-response-samples.js +1 -1
- package/dist/server/plugins/markdown/index.js +1 -1
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/mcp/codemode/constants.js +1 -1
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
- package/dist/server/plugins/mcp/codemode/tools/execute.d.ts +1 -0
- package/dist/server/plugins/mcp/constants.d.ts +1 -0
- package/dist/server/plugins/mcp/constants.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.d.ts +1 -0
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.d.ts +11 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.d.ts +4 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/constants.js +1 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type-list.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/get-graphql-type.js +7 -4
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.d.ts +7 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/types.js +0 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.d.ts +5 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/graphql/utils.js +4 -2
- package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +4 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +2 -2
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +2 -2
- package/dist/server/plugins/mcp/gateway-mcp/eligibility.d.ts +1 -2
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.d.ts +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/secret-store.d.ts +4 -4
- package/dist/server/plugins/mcp/gateway-mcp/secret-store.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/subject.d.ts +20 -0
- package/dist/server/plugins/mcp/gateway-mcp/subject.js +1 -0
- package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +9 -9
- package/dist/server/plugins/mcp/index.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/servers/mcp-server.js +1 -1
- package/dist/server/plugins/mcp/types.d.ts +1 -2
- package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +1 -1
- package/dist/server/plugins/mcp/utils.d.ts +17 -5
- package/dist/server/plugins/mcp/utils.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/pages/index.js +1 -1
- package/dist/server/plugins/scorecard-classic/compute-scorecard.js +4 -4
- package/dist/server/plugins/scorecard-classic/index.js +1 -1
- package/dist/server/plugins/scorecards/plugin.js +1 -1
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +2 -2
- package/dist/server/plugins/search/documents/search-documents.js +1 -1
- package/dist/server/plugins/search/index.js +1 -1
- package/dist/server/plugins/search/llmstxt/index.js +4 -4
- package/dist/server/plugins/sidebars/index.js +1 -1
- package/dist/server/plugins/sitemap/index.js +1 -1
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/ssr/render.js +1 -1
- package/dist/server/ssr/utils.d.ts +1 -0
- package/dist/server/ssr/utils.js +5 -5
- package/dist/server/store.d.ts +2 -6
- package/dist/server/store.js +1 -1
- package/dist/server/types/plugins/common.d.ts +3 -5
- package/dist/server/types/plugins/markdown.d.ts +1 -3
- package/dist/server/types/plugins/search.d.ts +1 -0
- package/dist/server/utils/catalog-classic/get-route-slug-to-catalog-slug-map.test.js +1 -1
- package/dist/server/utils/report-all-errors.js +1 -1
- package/dist/server/utils/shared-data.js +1 -1
- package/dist/server/web-server/routes/resolve-route.js +1 -1
- package/dist/types/markdoc.d.ts +2 -1
- package/dist/utils/url/get-shared-data-fetch-url.d.ts +17 -0
- package/dist/utils/url/get-shared-data-fetch-url.js +1 -0
- package/package.json +9 -8
- package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.d.ts +0 -4
- package/dist/markdoc/helpers/get-operation/get-operation-info-by-id.js +0 -1
- package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.d.ts +0 -4
- package/dist/markdoc/helpers/get-operation/get-operation-info-by-pointer.js +0 -1
- package/dist/markdoc/helpers/get-operation/get-operation.d.ts +0 -14
- package/dist/markdoc/helpers/get-operation/get-operation.js +0 -1
- package/dist/markdoc/helpers/get-operation/index.d.ts +0 -4
- package/dist/markdoc/helpers/get-operation/index.js +0 -1
- package/dist/markdoc/helpers/get-operation/types/index.d.ts +0 -4
- package/dist/markdoc/helpers/get-operation/types/index.js +0 -0
- package/dist/markdoc/helpers/get-operation/types/operation-identifier.d.ts +0 -5
- package/dist/markdoc/helpers/get-operation/types/operation-identifier.js +0 -0
- package/dist/markdoc/helpers/get-operation/types/operation-info.d.ts +0 -6
- package/dist/markdoc/helpers/get-operation/types/operation-info.js +0 -0
- package/dist/markdoc/helpers/get-operation/types/operation-parameters.d.ts +0 -3
- package/dist/markdoc/helpers/get-operation/types/operation-parameters.js +0 -0
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.d.ts +0 -4
- package/dist/server/plugins/markdown/attribute-resolvers/helpers/get-media-content-samples.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as R}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getRouteSlugsForPath as F}from"../utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as N,asyncapiDocsLoader as j}from"./asyncapi-doc-loader.js";import{searchResolver as L}from"./search/search-resolver.js";import{getAiDocumentsStore as G}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as M}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function ot(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":N,"asyncapi-docs":j},processContent:async(e,o)=>{await M("build.plugin.
|
|
1
|
+
import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as R}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getRouteSlugsForPath as F}from"../utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as N,asyncapiDocsLoader as j}from"./asyncapi-doc-loader.js";import{searchResolver as L}from"./search/search-resolver.js";import{getAiDocumentsStore as G}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as M}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function ot(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":N,"asyncapi-docs":j},processContent:async(e,o)=>{await M("com.redocly.build.plugin.asyncapiDocs",async()=>{if((await o.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,b("../../../client/templates/asyncapi-docs/template.js")),g=e.registerServerPropsGetter(v,b("./get-server-props.js"));for(const l of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(l.relativePath))try{const{data:r,compoundHash:w}=await o.cache.load(l.realRelativePath,"asyncapi-doc");if(!r?.length)continue;p=r.map(({markdocChunks:t,relativePath:s,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:s,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(r,e.outdir,w);for(const t of r){const s=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(R,`${C(t.relativePath,".json")}?download`)},{url:D(R,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(s,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(i=>{const n={fsPath:t.relativePath,slugSuffix:`/${i.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:s}],getStaticData:S(o.withPathPrefix,i.label),serverPropsGetterIds:[g]};e.addRoute(n),i.items&&i.items.forEach(a=>{e.addRoute({...n,slugSuffix:`/${a.link}`,getStaticData:S(o.withPathPrefix,a.label)}),a.items&&a.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(o.withPathPrefix,a.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:i=>{const n=a=>{const h={...a};return a.link&&(h.routeSlug=D(i.slug,a.link),h.link=D(i.slug,a.link)),a.items&&(h.items=a.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:i.slug,link:i.slug},...f.map(n)]},getSearchDocuments:L(e,t.document),getStaticData:S(o.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:G({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:s}]})}}catch(r){console.error(r)}})},afterRoutesCreated:async(e,o)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:r}of p){const w=F(e.getAllRoutes(),g),t=(await o.cache.load(r,"asyncapi-doc")).compoundHash;await o.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:i}of c){const{ast:n}=await e.parseMarkdoc({input:{content:f,relativePath:y,isVirtual:l},context:o,deps:{sharedDataIds:[`${_}${i}`],routeSlugs:w}});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:s}of c)P.add(s)}const k=u.difference(P);for(const c of k)o.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{ot as asyncAPIDocsPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isTruthy as n}from"../../../utils/guards/is-truthy.js";import{normalizeRouteSlug as g}from"../../../utils/path/normalize-route-slug.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";async function
|
|
1
|
+
import{isTruthy as n}from"../../../utils/guards/is-truthy.js";import{normalizeRouteSlug as g}from"../../../utils/path/normalize-route-slug.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";async function f(){return{id:"CatalogClassic",requiredEntitlements:["catalogClassic"],async processContent(a,{getConfig:o}){await u("com.redocly.build.plugin.catalogClassic",async s=>{const c=a.createTemplate("catalogClassic","@redocly/theme/components/CatalogClassic/CatalogClassic"),e=await o(),i=e.catalogClassic??{};s?.setAttribute("config",JSON.stringify(e.catalogClassic));for(const[r,t]of Object.entries(i)){const l=g(t.slug);a.addRoute({duplicateInAllLocales:!0,slug:l,fsPath:l,templateId:c,excludeFromSidebar:!0,serverPropsGetterIds:[],getNavText:()=>Promise.resolve(t.title||"API Catalog"),getStaticData:async()=>({props:{catalogId:r,catalogConfig:{...t,filters:t.filters?.filter(n),items:void 0},seo:{title:t.title||"API Catalog"}}})})}})}}}export{f as catalogClassicPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import u from"node:path";import{removeLeadingSlash as w}from"@redocly/theme/core/utils";import{toKebabCase as
|
|
1
|
+
import u from"node:path";import{removeLeadingSlash as w}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as g}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as v}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as E}from"./base.js";const d=15;class K extends E{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t,o){const a=w(t.realRelativePath),c=t.document.info.title,e=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:t.document["x-redocly-catalog-key"]});return{type:this.type,key:e,title:c,summary:t.document.info.description?v(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a},version:o}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t,o,a,c){if(!this.#t(t))throw new Error("Arazzo description has no source descriptions");const e=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:{...i},revision:o,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:e,source:"file"}),c.delete(`${i.key}:${a}`),await this.#e(t,i.key,i.version,a,o,c,e);const l=t.document.sourceDescriptions||[];await g(l,d,async r=>{if(!(r.type!=="openapi"||!r.url))try{const n=this.resolveSourceDescriptionUrl(r.url,t.realRelativePath);if(!n){!r.url.startsWith("http://")&&!r.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${r.url}`);return}const s=((await this.context.cache.load(n,"api-doc")).data??[]).filter(m=>m.type==="openapi");if(s.length===0){this.context.logger.warn(`No OpenAPI definition found at path: ${n}`);return}const p=s[0],y=this.resolveEntityKey({realRelativePath:p.realRelativePath,customKey:p.document["x-redocly-catalog-key"]});await this.catalogEntitiesService.createEntityRelation({sourceKey:i.key,type:"relatesTo",targetKey:y,sourceFile:t.realRelativePath,fileHash:t.hash}),await this.#r(t,r.name,p,i.key,y,i.version,o)}catch(n){this.context.logger.warn(`Failed to create relation to OpenAPI source "${r.url}": ${n instanceof Error?n.message:"Unknown error"}`)}})}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,c,e,i,l)=>{try{const r=t.document.components?.inputs,n=r?Object.entries(r):[],h=[];for(const[s,p]of n)h.push(async()=>{const y=`${o}-${f(s)}`,m=await this.#a({schemaName:s,schema:p,description:t,parentKey:o,parentVersion:a,parentRevision:e,rbacTeams:l});i.delete(`${y}:${c}`),m&&await this.catalogEntitiesService.createEntityRelation({sourceKey:o,type:"uses",targetKey:m.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:e,targetRevision:e})});if(h.length===0)return;await g(h,d,s=>s())}catch(r){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${r instanceof Error?r.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:c,parentVersion:e,parentRevision:i,rbacTeams:l})=>{const r={type:"data-schema",key:`${c}-${f(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};try{return await this.catalogEntitiesService.createEntity({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:l,source:"file",revision:i})}catch(n){return this.context.logger.warn(`Failed to create data schema entity for ${t}: ${n instanceof Error?n.message:"Unknown error"}`),null}};#r=async(t,o,a,c,e,i,l)=>{const r=t.document.workflows||[];if(r.length===0)return;const n=new Set;for(const h of r)for(const s of h.steps||[]){if(!s.operationId)continue;const p=s.operationId.startsWith(`${o}.`)?s.operationId.substring(`${o}.`.length):s.operationId;p&&n.add(p)}n.size!==0&&await g(Array.from(n),d,async h=>{try{const s=`${e}-${f(h)}`;await this.catalogEntitiesService.createEntityRelation({sourceKey:c,type:"uses",targetKey:s,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:i,targetVersion:i,sourceRevision:l,targetRevision:l})}catch(s){this.context.logger.warn(`Failed to create relation to operation "${h}": ${s instanceof Error?s.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),c=a.startsWith("@")?a.slice(1):a,[e]=c.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return w(u.posix.normalize(e));const i=u.posix.dirname(o);return e.startsWith(i+"/")?u.posix.normalize(e):u.posix.normalize(u.posix.join(i,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{K as ArazzoEntitiesExtractor};
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AsyncApiDefinitionReferenced } from '@redocly/api-docs';
|
|
2
|
+
import type { BundledApiDefinition } from '../../../../api-docs/loader.js';
|
|
2
3
|
import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
|
|
3
4
|
import type { EntityDtoSchema } from '../../../schemas/dto-schemas';
|
|
4
5
|
import { BaseApiEntitiesExtractor } from './base.js';
|
|
5
6
|
type Params = BaseApiEntitiesExtractorParams;
|
|
6
|
-
|
|
7
|
+
type AsyncApiCatalogBundle = Omit<BundledApiDefinition, 'document' | 'isVirtual'> & {
|
|
8
|
+
type: 'asyncapi';
|
|
9
|
+
document: AsyncApiDefinitionReferenced & {
|
|
10
|
+
'x-redocly-catalog-key'?: string;
|
|
11
|
+
};
|
|
12
|
+
isVirtual: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare class AsyncApiEntitiesExtractor extends BaseApiEntitiesExtractor<AsyncApiCatalogBundle> {
|
|
7
15
|
#private;
|
|
8
16
|
constructor(params: Params);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
processApiDescription(description:
|
|
17
|
+
loadApiDescriptions(): Promise<AsyncApiCatalogBundle[]>;
|
|
18
|
+
mapApiDescriptionToEntity(description: AsyncApiCatalogBundle, version: string): EntityDtoSchema;
|
|
19
|
+
processApiDescription(description: AsyncApiCatalogBundle, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
|
|
12
20
|
}
|
|
13
21
|
export {};
|
|
14
22
|
//# sourceMappingURL=asyncapi-entities-extractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{removeLeadingSlash as d}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as E}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{extractPartsFromChannelsMessageRef as S}from"../../../utils/extract-parts-from-channels-message-ref.js";const u=15;class T extends w{constructor(e){super("asyncapi",e)}mapApiDescriptionToEntity(e,t){const a=d(e.realRelativePath),r=e.document.info.title,s=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:s,title:r,summary:E(e.document.info.description),tags:e.document.info.tags?.map(n=>n.name),metadata:{specType:this.specType,descriptionFile:a},version:t}}async
|
|
1
|
+
import{removeLeadingSlash as d}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as E}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as w}from"./base.js";import{extractPartsFromComponentsRef as y}from"../../../utils/extract-parts-from-components-ref.js";import{extractPartsFromChannelsMessageRef as S}from"../../../utils/extract-parts-from-channels-message-ref.js";const u=15;class T extends w{constructor(e){super("asyncapi",e)}async loadApiDescriptions(){return(await this.actions.loadApiDocuments(this.context)).filter(t=>t.type==="asyncapi").map(t=>({...t,isVirtual:t.isVirtual??!1}))}mapApiDescriptionToEntity(e,t){const a=d(e.realRelativePath),r=e.document.info.title,s=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:s,title:r,summary:E(typeof e.document.info.description=="string"?e.document.info.description:void 0),tags:e.document.info.tags?.map(n=>n.name),metadata:{specType:this.specType,descriptionFile:a},version:t}}async processApiDescription(e,t,a,r){const s=this.getRbacTeamsForDefinition(e.relativePath),n=this.mapApiDescriptionToEntity(e,a);await this.catalogEntitiesService.createEntity({entity:n,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,rbacTeams:s,source:"file"}),r.delete(`${n.key}:${a}`);const o=this.#a(e),[i,c]=await Promise.allSettled([this.#s(e,n.key,n.version,a,t,r,s),this.#n(o,e,n.key,n.version,a,t,r,s)]);i.status!=="fulfilled"&&this.context.logger.error("Schema processing failed:",i.reason),c.status!=="fulfilled"&&this.context.logger.error("Operation processing failed:",c.reason)}#a=e=>{const t=e.document.operations;return t?Object.entries(t).map(([a,r])=>({operationName:a,operation:r})):[]};#s=async(e,t,a,r,s,n,o)=>{const i=e.document.components?.schemas;if(!i)return;const c=Object.entries(i);if(c.length===0)return;const l=await $(c,u,async([h,m])=>{const R=`${t}-${f(h)}`,g=await this.#r({schemaName:h,schema:m,description:e,parentKey:t,parentVersion:a,parentRevision:s,rbacTeams:o});n.delete(`${R}:${r}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:g.key,sourceFile:e.realRelativePath,fileHash:e.hash,sourceVersion:a,targetVersion:a,sourceRevision:s,targetRevision:s})},this.context.logger);l.count.failed>0&&this.context.logger.warn(`Schema processing completed with ${l.count.failed} failures out of ${c.length} schemas for ${e.realRelativePath}`)};#r=async({schemaName:e,schema:t,description:a,parentKey:r,parentVersion:s,parentRevision:n,rbacTeams:o})=>{const i=`${r}-${f(e)}`,c="title"in t?t.title??t.description:null,l=JSON.stringify(t),h={type:"data-schema",key:i,title:e,summary:c,tags:[],metadata:{specType:this.specType,schema:l},version:s};try{return await this.catalogEntitiesService.createEntity({entity:h,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:o,source:"file",revision:n})}catch(m){return this.context.logger.warn(`Failed to create data schema entity for ${e}: ${m instanceof Error?m.message:"Unknown error"}`),null}};#n=async(e,t,a,r,s,n,o,i)=>{if(!e.length)return;const c=await $(e,u,async({operationName:l,operation:h})=>{const m=await this.#o(h,l,t,a,r,n,i);o.delete(`${m}:${s}`)},this.context.logger);c.count.failed>0&&this.context.logger.warn(`Operation processing completed with ${c.count.failed} failures out of ${e.length} operations for ${t.realRelativePath}`)};#o=async(e,t,a,r,s,n,o)=>{const i=`${r}-${f(t)}`,c=await this.#i(e.messages??[],a,r),l=await this.#c(t,e,c,a,r,s,n,o);return l&&await this.#l({apiOperationKey:l.key,operation:e,descriptionUniqueKey:r,description:a,descriptionVersion:s,parentRevision:n}),i};#i=async(e,t,a)=>{if(!e||e.length===0)return[];const r=new Set;for(const s of e){let n=null;if("$ref"in s){const o=s.$ref.startsWith("#/channels/")?this.#e(s.$ref,t):s.$ref;if(o){const i=y(o);if(i?.componentName&&i.componentType==="messages"){const c=t.document.components?.messages[i.componentName];c?.payload&&"$ref"in c.payload&&c.payload.$ref&&(n=c.payload.$ref)}}}else s.payload&&"$ref"in s.payload&&s.payload.$ref&&(n=s.payload.$ref);if(n){const o=y(n);o?.componentName&&o.componentType==="schemas"&&r.add(`${a}-${f(o.componentName)}`)}}return Array.from(r)};#c=async(e,t,a,r,s,n,o,i)=>{const c={type:"api-operation",key:`${s}-${f(e)}`,title:t.title||e,summary:t.summary??"",tags:t.tags?.map(l=>l.name)??[],metadata:{method:t.action==="send"?"PUBLISH":"SUBSCRIBE",path:t.channel.address??"",payload:t.action==="receive"?a:[],responses:t.action==="send"?a:[]},version:n};try{return await this.catalogEntitiesService.createEntity({entity:c,sourceFile:r.realRelativePath,fileHash:r.hash,rbacTeams:i,source:"file",revision:o})}catch(l){return this.context.logger.warn(`Failed to create API operation entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}};#l=async({apiOperationKey:e,operation:t,descriptionUniqueKey:a,description:r,descriptionVersion:s,parentRevision:n})=>(await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:a,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),await this.#h(t,e,r,s,n),!Array.isArray(t.messages)||!t.messages?.length?[]:await this.#m(t.messages,e,r,a,s,n));#h=async(e,t,a,r,s)=>{e["x-catalogRelations"]?.length&&await p(e["x-catalogRelations"],u,async n=>{try{this.validateEntityRelationFileSchema(n),await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:n.type,targetKey:n.key,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:r,targetVersion:"",sourceRevision:s,targetRevision:""})}catch(o){this.context.logger.warn(`Error creating entity relation for operation ${t} based on custom property: ${o instanceof Error?o.message:"Unknown error"}`)}})};#m=async(e,t,a,r,s,n)=>e.length===0?[]:(await p(e,u,async i=>await this.#f(i,t,a,r,s,n)??"")).filter(i=>!!i);#f=async(e,t,a,r,s,n)=>"$ref"in e?this.#y(e,t,a,r,s,n):e.payload?this.#u(e,t,a,r,s,n):null;#y=async(e,t,a,r,s,n)=>{const o=e.$ref.startsWith("#/channels/")?this.#e(e.$ref,a):e.$ref;if(!o)return null;const i=y(o);if(!i||!i.componentName||i.componentType!=="messages")return null;const c=a.document.components?.messages[i.componentName];return!c?.payload||!("$ref"in c.payload)||!c.payload.$ref?null:this.#t(c.payload.$ref,t,a,r,s,n)};#e=(e,t)=>{const a=S(e);if(!a||!a.channelName||!a.messageName)return null;const r=t.document.channels?.[a.channelName];if(!r?.messages)return null;const s=r.messages[a.messageName];return!s||!("$ref"in s)||typeof s.$ref!="string"||!s.$ref.startsWith("#/components/messages/")?null:s.$ref};#u=async(e,t,a,r,s,n)=>!e.payload||!("$ref"in e.payload)||!e.payload.$ref?null:this.#t(e.payload.$ref,t,a,r,s,n);#t=async(e,t,a,r,s,n)=>{const o=y(e);if(!o||!o.componentName||o.componentType!=="schemas")return null;const i=`${r}-${f(o.componentName)}`;return await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"uses",targetKey:i,sourceFile:a.realRelativePath,fileHash:a.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n}),i}}export{T as AsyncApiEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{sha1 as S}from"../../../../../utils/crypto/sha1.js";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as D}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as F}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as H}from"../../../utils/ajv-validator.js";const O=15,C=200,k=500;class Y{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}getDescriptionHash(t){return t.definition===void 0?t.hash:S(JSON.stringify(t.definition))}async extract(){const t=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const a=this.#s(t),i={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},
|
|
1
|
+
import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{sha1 as S}from"../../../../../utils/crypto/sha1.js";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as D}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as F}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as H}from"../../../utils/ajv-validator.js";const O=15,C=200,k=500;class Y{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}getDescriptionHash(t){return t.definition===void 0?t.hash:S(JSON.stringify(t.definition))}async extract(){const t=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const a=this.#s(t),i={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},r=[],o=new Set;await w(Array.from(a.values()),O,async c=>{for(const{description:s,version:l}of c)try{const n=this.getDescriptionHash(s);if(!n)continue;o.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),y=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:y});if(!(f!==null)){i.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&i[f]++,f==="fileHashMismatch"&&h&&r.length<3&&r.push({path:s.realRelativePath,stored:h.hash,incoming:n});const d=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(s.realRelativePath);await this.#a(d);const E=new Date().toISOString();await this.processApiDescription(s,E,l,d),(m||y||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#o(d,s.realRelativePath,E,n),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.OUTDATED),p.markFileHashPendingConfirmation({fileType:this.fileType,filePath:s.realRelativePath,hash:n})}catch(n){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${s.realRelativePath}`),this.context.logger.warn(n)}}),await this.#r(o)}#i({fileHashChanged:t,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return t?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async t=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(t).map(e=>e.split(":")[0])}),t.clear())};#t=async t=>{let e=0,a=0;for(;;){const i=await this.catalogEntitiesService.getEntities({paginationParams:{limit:k,filter:t}});if(!i||i.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:i.items.map(({id:r})=>r)}),e+=i.items.length,a+=1}return{total:e,pages:a}};#s(t){const e=new Map;for(const a of t)if(!(a.isVirtual||!a.hash))try{const i=this.#n(a),r=this.mapApiDescriptionToEntity(a,i),o=e.get(r.key)??[];o.push({description:a,version:i}),e.set(r.key,o)}catch(i){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(i)}return e}#r=async t=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!t.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const i=a.map(({filePath:l})=>l),{total:r,pages:o}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:i},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:i});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${i.length} currentRevisionsDeleted=${r} currentPages=${o} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${i.slice(0,3).join(", ")}${i.length>3?`, +${i.length-3} more`:""}`)};#o=async(t,e,a,i)=>{if(t.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const r=Array.from(t).map(o=>{const[c,s]=o.split(":");return{key:c,version:s}});for(let o=0;o<r.length;o+=C){const c=r.slice(o,o+C),s=Array.from(new Set(c.map(({key:n})=>n))),l=c.map(({key:n,version:h})=>({op:A.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:h}]}));await this.catalogEntitiesService.softDeleteEntitiesWithRelations({revision:a,fileHash:i,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:s},{op:A.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e},{field:"is_current",operator:"equal",value:!0}]}})}};#n(t){const e=t.document?.info?.version??null,a=F(e,t.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(t){H(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(t)}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(t);return D(a||{fsPath:t},e||{})}resolveEntityKey({realRelativePath:t,customKey:e,extensionPattern:a}){const i=this.#l(t,a);return typeof e=="string"&&e.trim()?R(e.trim()):i}#l(t,e){let i=_(t);for(;/^@[^/]+\//.test(i);)i=i.replace(/^@[^/]+\//,"");i=i.replace(/\/@[^/]+/g,"");const r=e?i.replace(e,""):i.replace(/\.[^.]+$/,"");return R(r.replace(/[\\/]/g,"-"))}}export{Y as BaseApiEntitiesExtractor};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import type { GraphQLSchema } from 'graphql';
|
|
2
|
-
import type {
|
|
1
|
+
import type { DocumentNode, GraphQLSchema } from 'graphql';
|
|
2
|
+
import type { BundledApiDefinition } from '../../../../api-docs/loader.js';
|
|
3
3
|
import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
|
|
4
4
|
import type { EntityDtoSchema } from '../../../schemas/dto-schemas.js';
|
|
5
5
|
import { BaseApiEntitiesExtractor } from './base.js';
|
|
6
|
-
type GraphqlBundledDefinition = Omit<
|
|
7
|
-
|
|
6
|
+
type GraphqlBundledDefinition = Omit<BundledApiDefinition, 'document' | 'isVirtual'> & {
|
|
7
|
+
type: 'graphql';
|
|
8
|
+
document: DocumentNode;
|
|
8
9
|
schema: GraphQLSchema;
|
|
9
|
-
content: string;
|
|
10
10
|
metadata?: Record<string, unknown>;
|
|
11
|
+
isVirtual: boolean;
|
|
11
12
|
};
|
|
12
13
|
export declare class GraphqlEntitiesExtractor extends BaseApiEntitiesExtractor<GraphqlBundledDefinition> {
|
|
13
14
|
#private;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{buildASTSchema as v,isObjectType as T,isScalarType as I,isEnumType as P,isInterfaceType as S,isUnionType as E,isInputObjectType as $,getNamedType as u,printType as A}from"graphql";import{removeLeadingSlash as F}from"@redocly/theme/core/utils";import{toKebabCase as d}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as k}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as R}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as C}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as j}from"./base.js";import{getApiConfigByPath as D}from"../../../../get-api-config.js";const O=15,b=15,L=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class U extends j{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=await this.actions.loadApiDocuments(this.context),e=await this.context.getConfig(),a=[];for(const n of t)if(n.type==="graphql")try{const r=n.document,s=v(r),i=D(e.apis,n.relativePath);a.push({...n,document:r,schema:s,metadata:i?.metadata,isVirtual:n.isVirtual??!1})}catch(r){this.#t.warn(`Failed to load GraphQL schema from ${n.relativePath}: ${r instanceof Error?r.message:"Unknown error"}`)}return a}mapApiDescriptionToEntity(t,e){const a=F(t.realRelativePath),n=t.relativePath.replace(/\.(gql|graphql)$/,""),r=this.#s(n.split("/").pop()||"GraphQL Schema"),s=this.#c(t.metadata?.tags),i=t.metadata?.["x-redocly-catalog-key"],h=this.resolveEntityKey({realRelativePath:t.realRelativePath,customKey:typeof i=="string"?i:void 0,extensionPattern:/\.(gql|graphql)$/});return{type:this.type,key:h,title:r,summary:t.metadata?.description||null,tags:s.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,n){const{schema:r}=t;if(!r)throw new Error("GraphQL definition is missing a parsed schema");const s=this.getRbacTeamsForDefinition(t.relativePath),i=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntity({entity:i,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,rbacTeams:s,source:"file",revision:e}),n.delete(`${i.key}:${a}`),await Promise.all([this.#a(t,i.key,i.version,a,e,n,s),this.#f(t,i.key,i.version,a,e,n,s)])}#a=async(t,e,a,n,r,s,i)=>{const{schema:h}=t,c=h.getTypeMap(),l=this.#i(h),o=Object.entries(c).filter(([f])=>!f.startsWith("__")&&!L.has(f)&&!l.has(f));if(o.length===0)return;const p=await R(o,b,async([f,m])=>{const y=this.#e(f,e),g=await this.#l({typeName:f,type:m,description:t,parentKey:e,parentVersion:a,parentRevision:r,rbacTeams:i});s.delete(`${y}:${n}`),g&&await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"uses",targetKey:g.key,sourceFile:t.realRelativePath,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:r,targetRevision:r})},this.#t);p.count.failed>0&&this.#t.warn(`Schema processing completed with ${p.count.failed} failures out of ${o.length} types for ${t.realRelativePath}`),await this.#p({description:t,descriptionUniqueKey:e,userTypes:o,parentRevision:r})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&k(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${d(t)}`;#r=t=>T(t)?"object":S(t)?"interface":E(t)?"union":P(t)?"enum":$(t)?"input":I(t)?"scalar":"unknown";#i=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const n=t.getMutationType();n&&e.add(n.name);const r=t.getSubscriptionType();return r&&e.add(r.name),e};#n(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"QUERY",rootTypeName:a.name})}const n=t.getMutationType();if(n){const s=n.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"MUTATION",rootTypeName:n.name})}const r=t.getSubscriptionType();if(r){const s=r.getFields();for(const[i,h]of Object.entries(s))e.push({fieldName:i,field:h,operationType:"SUBSCRIBE",rootTypeName:r.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const i=u(s.type);i&&!i.name.startsWith("__")&&a.push(this.#e(i.name,e))}const n=[],r=u(t.type);return r&&!r.name.startsWith("__")&&n.push(this.#e(r.name,e)),{inputTypes:a,returnTypes:n}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:n,parentVersion:r,parentRevision:s,rbacTeams:i})=>{const h=this.#e(t,n),c=e.description??null,l=this.#r(e),o={type:"data-schema",key:h,title:t,summary:c,tags:["graphql"],metadata:{specType:this.specType,typeKind:l,sdl:this.#h(e,a.schema)},version:r};try{return await this.catalogEntitiesService.createEntity({entity:o,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:i,source:"file",revision:s})}catch(p){return this.#t.warn(`Failed to create data schema entity for ${t}: ${p instanceof Error?p.message:"Unknown error"}`),null}};#h=(t,e)=>{const a=new Set,n=[],r=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const l=c.name;if(l.startsWith("__")||r.has(l)||a.has(l))return;const o=e.getType(l);o&&(a.add(l),n.push(o))};for(s(t);n.length>0;){const c=n.pop();if(T(c)){for(const o of c.getInterfaces?.()??[])s(o);const l=c.getFields();for(const o of Object.values(l)){s(u(o.type));for(const p of o.args??[])s(u(p.type))}}else if(S(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}else if(E(c))for(const l of c.getTypes())s(l);else if($(c)){const l=c.getFields();for(const o of Object.values(l))s(u(o.type))}}const i=[t.name,...[...a].filter(c=>c!==t.name)],h=[];for(const c of i){const l=e.getType(c);l&&h.push(A(l))}return h.join(`
|
|
2
2
|
|
|
3
|
-
`)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:
|
|
3
|
+
`)};#p=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:n})=>{const r=a.filter(([,s])=>T(s));r.length!==0&&await w(r,b,async([s,i])=>{const c=i.getInterfaces?.()??[];if(!c.length)return;const l=this.#e(s,e);await w([...c],5,async o=>{const p=this.#e(o.name,e);try{await this.catalogEntitiesService.createEntityRelation({sourceKey:l,type:"implements",targetKey:p,sourceFile:t.realRelativePath,fileHash:t.hash,sourceRevision:n,targetRevision:n})}catch(f){this.#t.warn(`Failed to create 'implements' relation ${l} -> ${p}: ${f instanceof Error?f.message:"Unknown error"}`)}})})};#f=async(t,e,a,n,r,s,i)=>{const{schema:h}=t,c=this.#n(h);if(c.length===0)return;const o=(await R(c,O,async({fieldName:p,field:f,operationType:m,rootTypeName:y})=>{const g=await this.#y(p,f,m,y,t,e,a,r,i);s.delete(`${g}:${n}`)},this.#t)).count.failed;o>0&&this.#t.warn(`Operation extraction completed with ${o} failures out of ${c.length} operations for ${e}`)};#y=async(t,e,a,n,r,s,i,h,c)=>{const l=`${s}-${d(`${a.toLowerCase()}-${t}`)}`,{inputTypes:o,returnTypes:p}=this.#o(e,s),f=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:o,returnTypes:p,description:r,descriptionUniqueKey:s,descriptionVersion:i,parentRevision:h,rbacTeams:c});return f&&await this.#m({apiOperationKey:f.key,inputTypes:o,returnTypes:p,descriptionUniqueKey:s,description:r,descriptionVersion:i,parentRevision:h}),l};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:r,returnTypes:s,description:i,descriptionUniqueKey:h,descriptionVersion:c,parentRevision:l,rbacTeams:o})=>{const p=t,m={type:"api-operation",key:`${h}-${d(`${a.toLowerCase()}-${t}`)}`,title:p,summary:e.description?C(e.description):null,tags:["graphql"],metadata:{method:a,path:`${n}.${t}`,payload:r,responses:s},version:c};try{return await this.catalogEntitiesService.createEntity({entity:m,sourceFile:i.realRelativePath,fileHash:i.hash,rbacTeams:o,source:"file",revision:l})}catch(y){return this.#t.warn(`Failed to create API operation entity for ${p}: ${y instanceof Error?y.message:"Unknown error"}`),null}};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:n,description:r,descriptionVersion:s,parentRevision:i})=>{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:"partOf",targetKey:n,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:i,targetRevision:i});const h=[...new Set(e)],c=[...new Set(a)],l=[...h.map(o=>({key:o,relationType:"uses"})),...c.map(o=>({key:o,relationType:"returns"}))];await w(l,O,async({key:o,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelation({sourceKey:t,type:p,targetKey:o,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:i,targetRevision:i})}catch(f){this.#t.warn(`Failed to create relation between operation ${t} and type ${o} (${p}): ${f instanceof Error?f.message:"Unknown error"}`)}})}}export{U as GraphqlEntitiesExtractor};
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenAPIDefinition } from '@redocly/api-docs';
|
|
2
|
+
import type { BundledApiDefinition } from '../../../../api-docs/loader.js';
|
|
2
3
|
import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
|
|
3
4
|
import type { EntityDtoSchema } from '../../../schemas/dto-schemas';
|
|
4
5
|
import { BaseApiEntitiesExtractor } from './base.js';
|
|
5
|
-
|
|
6
|
+
type OpenApiCatalogBundle = Omit<BundledApiDefinition, 'isVirtual'> & {
|
|
7
|
+
type: 'openapi';
|
|
8
|
+
document: OpenAPIDefinition;
|
|
9
|
+
isVirtual: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare class OpenApiEntitiesExtractor extends BaseApiEntitiesExtractor<OpenApiCatalogBundle> {
|
|
6
12
|
#private;
|
|
7
13
|
constructor(params: BaseApiEntitiesExtractorParams);
|
|
8
|
-
loadApiDescriptions(): Promise<
|
|
9
|
-
mapApiDescriptionToEntity(description:
|
|
10
|
-
processApiDescription(description:
|
|
14
|
+
loadApiDescriptions(): Promise<OpenApiCatalogBundle[]>;
|
|
15
|
+
mapApiDescriptionToEntity(description: OpenApiCatalogBundle, version: string): EntityDtoSchema;
|
|
16
|
+
processApiDescription(description: OpenApiCatalogBundle, revision: string, version: string, entitiesToRemoveFromFile: Set<string>): Promise<void>;
|
|
11
17
|
}
|
|
18
|
+
export {};
|
|
12
19
|
//# sourceMappingURL=openapi-entities-extractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as $}from"@redocly/config";import{removeLeadingSlash as T}from"@redocly/theme/core/utils";import{toKebabCase as y}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as x}from"../../../../../utils/async/promise-map-limit-with-status.js";import{extractTeamsFromScopeItems as R}from"../../../../../utils/rbac.js";import{removeMarkdocTags as w}from"../../../../../../markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as b}from"./base.js";import{OpenapiSchemaResolver as S}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as A}from"../../../utils/extract-parts-from-components-ref.js";import{isValidTagName as v}from"../../../utils/is-valid-tag-name.js";const N=["get","post","put","delete","patch"],d=15,O=15;class V extends b{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return(await this.actions.loadApiDocuments(this.context)).filter(o=>o.type==="openapi").map(o=>({...o,isVirtual:o.isVirtual??!1}))}mapApiDescriptionToEntity(e,o){const s=T(e.realRelativePath),r=e.document.info.title,t=this.resolveEntityKey({realRelativePath:e.realRelativePath,customKey:e.document["x-redocly-catalog-key"]});return{type:this.type,key:t,title:r,summary:w(typeof e.document.info.description=="string"?e.document.info.description:void 0),tags:e.document.tags?.filter(a=>a.name&&v(a.name)).map(a=>a.name),metadata:{specType:this.specType,descriptionFile:s},version:o}}async processApiDescription(e,o,s,r){if(S.clearSchemaCache(),!e?.document)throw new Error("OpenAPI definition is missing a bundled document");const t=this.getRbacTeamsForDefinition(e.relativePath),a=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntity({entity:a,sourceFile:e.realRelativePath,fileHash:e.hash,source:"file",isRootEntity:!0,rbacTeams:t,revision:o}),r.delete(`${a.key}:${s}`),await this.#r(e,a.key,a.version,s,o,r,t);const n=this.#s(e.document.paths);if(n.length!==0){const i=(await x(n,d,async({operation:m,path:h,method:f})=>{if(!m.operationId)return;const l=await this.#n(m,h,f,e,a.key,a.version,o,t);r.delete(`${l}:${s}`)},this.#e)).count.failed;i>0&&this.#e.warn(`Extraction completed with ${i} failures out of ${n.length} operations for ${a.key}`)}}#s(e){return Object.entries(e??{}).flatMap(([o,s])=>N.filter(r=>s[r]).map(r=>{const t=s[r];if(!t)throw new Error(`Operation not found for method ${r} on path ${o}`);return{operation:t,path:o,method:r.toUpperCase()}}))}async#r(e,o,s,r,t,a,n){const c=e.document.components?.schemas;if(!c)return;const i=Object.entries(c);i.length!==0&&await E(i,O,async([m,h])=>{const f=`${o}-${y(m)}`,l=await this.#o({schemaName:m,schema:h,description:e,parentKey:o,parentVersion:s,parentRevision:t,rbacTeams:n});a.delete(`${f}:${r}`),l&&await this.catalogEntitiesService.createEntityRelation({sourceKey:o,sourceVersion:s,sourceRevision:t,type:"uses",targetKey:l.key,targetVersion:s,targetRevision:t,sourceFile:e.realRelativePath,fileHash:e.hash})})}async#o({schemaName:e,schema:o,description:s,parentKey:r,parentVersion:t,parentRevision:a,rbacTeams:n}){const c=S.resolveSchemaRefs(o,s.document),i=JSON.stringify(c),m=c[$]?R(c[$]):n,h=R(c["x-rbac"]),f={type:"data-schema",key:`${r}-${y(e)}`,title:e,summary:(typeof c.description=="string"?c.description:c.title)??null,tags:[],metadata:{specType:this.specType,schema:i},version:t};try{return await this.catalogEntitiesService.createEntity({entity:f,sourceFile:s.realRelativePath,fileHash:s.hash,rbacTeams:h.length?h:m,source:"file",revision:a})}catch(l){return this.#e.error(`Failed to create data schema entity for ${e}: ${l instanceof Error?l.message:"Unknown error"}`),null}}async#n(e,o,s,r,t,a,n,c){const i=`${t}-${y(`${e.operationId}`)}`,m=await Promise.all([this.#m(e.requestBody??null,r),this.#h(e.responses??{},r)]),h=m[0].schemaNames,f=m[1].schemaNames;m[0].errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${m[0].errors.join(", ")}`),m[1].errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${m[1].errors.join(", ")}`);const l=h.map(p=>`${t}-${y(p)}`),u=f.map(p=>`${t}-${y(p)}`),g=await this.#f({path:o,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:u,description:r,parentKey:t,parentVersion:a,parentRevision:n,rbacTeams:c});return g&&await Promise.all([this.#c(h,e.operationId??"",r.realRelativePath,r.hash,t,a,n),this.#i(f,e.operationId??"",r.realRelativePath,r.hash,t,a,n),this.#p({apiOperationKey:g.key,operationRelations:e["x-catalogRelations"],descriptionUniqueKey:t,description:r,parentVersion:a,parentRevision:n})]),i}async#c(e,o,s,r,t,a,n){return e.length===0||!o?[]:await this.#a(e,o,s,r,t,a,n)}async#i(e,o,s,r,t,a,n){return e.length===0||!o?[]:await this.#a(e,o,s,r,t,a,n)}#m(e,o){const s=[],r=[];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.document.components?.requestBodies?.[t.componentName];if(a&&"content"in a)for(const n of Object.values(a.content??{})){if(!n.schema?.$ref)continue;const c=this.#t(n.schema.$ref);c?.componentType==="schemas"&&c.componentName&&s.push(c.componentName)}}}}catch(t){r.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:r}}#h(e,o){const s=[],r=[];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 n=this.#t(a.schema.$ref);n?.componentType==="schemas"&&n.componentName&&s.push(n.componentName)}if(t&&t.$ref){const a=this.#t(t.$ref);if(a?.componentType==="responses"&&a.componentName){const n=o.document.components?.responses?.[a.componentName];if(n&&"content"in n)for(const c of Object.values(n.content??{})){if(!c.schema?.$ref)continue;const i=this.#t(c.schema.$ref);i?.componentType==="schemas"&&i.componentName&&s.push(i.componentName)}}}}}catch(t){r.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:r}}#t(e){try{return A(e)}catch{return{componentType:"",componentName:null}}}async#a(e,o,s,r,t,a,n){return e.length===0?[]:await E(e,O,async c=>await this.#l({operationId:o,schemaName:c,descriptionSourceFile:s,descriptionHash:r,parentKey:t,parentVersion:a,parentRevision:n}))}async#l({operationId:e,schemaName:o,descriptionSourceFile:s,descriptionHash:r,parentKey:t,parentVersion:a,parentRevision:n}){const c=`${t}-${y(o)}`;try{return await this.catalogEntitiesService.createEntityRelation({sourceKey:`${t}-${y(e)}`,type:"uses",targetKey:c,sourceFile:s,fileHash:r,sourceVersion:a,targetVersion:a,sourceRevision:n,targetRevision:n}),c}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#f({path:e,method:o,operation:s,requestBodySchemasKeys:r,responseSchemasKeys:t,description:a,parentKey:n,parentVersion:c,parentRevision:i,rbacTeams:m}){const h=`${s.operationId}`,f=`${n}-${y(h)}`,l=s[$]?R(s[$]):m,u=R(s["x-rbac"]),g={type:"api-operation",key:f,title:h,summary:w(s.summary),tags:s.tags?.filter(p=>v(p)),metadata:{path:e,method:o,payload:r,responses:t},version:c};try{return await this.catalogEntitiesService.createEntity({entity:g,sourceFile:a.realRelativePath,fileHash:a.hash,rbacTeams:u.length>0?u:l,source:"file",revision:i})}catch(p){return this.#e.error(`Failed to create API operation entity for ${h}: ${p instanceof Error?p.message:"Unknown error"}`),null}}async#p({apiOperationKey:e,operationRelations:o,descriptionUniqueKey:s,description:r,parentVersion:t,parentRevision:a}){try{await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:"partOf",targetKey:s,sourceFile:r.realRelativePath,fileHash:r.hash,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),await this.#y(e,r,o,t,a)}catch(n){this.#e.error(`Failed to create API operation relations for ${e}: ${n instanceof Error?n.message:"Unknown error"}`)}}async#y(e,o,s,r,t){s?.length&&await E(s,d,async a=>{try{this.validateEntityRelationFileSchema(a),await this.catalogEntitiesService.createEntityRelation({sourceKey:e,type:a.type,targetKey:a.key,sourceFile:o.realRelativePath,fileHash:o.hash,sourceVersion:r,targetVersion:"",sourceRevision:t,targetRevision:""})}catch(n){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${n instanceof Error?n.message:"Unknown error"}`)}})}}export{V as OpenApiEntitiesExtractor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{FileHashStatus as v,FileType as h}from"../../persistence/file-hashes/types.js";import{envConfig as C}from"../../config/env-config.js";import{CATALOG_BASE_SLUG as S}from"../../../constants/catalog-entities.js";import{telemetryTraceStep as $}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as f}from"./utils/catalog-data-collector.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as k,ENTITIES_MAP_GLOBAL_DATA_KEY as B}from"../../constants/plugins/catalog-entities.js";import{CacheService as z}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as R}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as O}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as Y}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as U}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as j}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as q}from"./database/catalog-entities-service.js";import{CatalogEntitiesPublisher as V}from"./database/catalog-entities-publisher.js";import{CatalogEntitiesRevisionsPruner as
|
|
1
|
+
import{FileHashStatus as v,FileType as h}from"../../persistence/file-hashes/types.js";import{envConfig as C}from"../../config/env-config.js";import{CATALOG_BASE_SLUG as S}from"../../../constants/catalog-entities.js";import{telemetryTraceStep as $}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as f}from"./utils/catalog-data-collector.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as k,ENTITIES_MAP_GLOBAL_DATA_KEY as B}from"../../constants/plugins/catalog-entities.js";import{CacheService as z}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as R}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as O}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as Y}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as U}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as j}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as q}from"./database/catalog-entities-service.js";import{CatalogEntitiesPublisher as V}from"./database/catalog-entities-publisher.js";import{CatalogEntitiesRevisionsPruner as I}from"./database/catalog-entities-revisions-pruner.js";import{DEFAULT_MAX_ENTITY_REVISIONS as W}from"./database/consts.js";import{DatabaseConnectionFactory as J}from"../../providers/database/database-connection-factory.js";import{ArazzoEntitiesExtractor as X}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as Z}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as K}from"./utils/hash-manager.js";import{RbacConfigHashCache as Q}from"./utils/rbac-config-hash-cache.js";import{OpenApiEntitiesExtractor as ee}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const te="catalog-entity-template",ie="catalog-entity";let _=!0;async function ae(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(e,i){const o=await i.getConfig(),r=O(o.entitiesCatalog);if(!r.show)return;const{logger:n}=i,a=e.registerServerPropsGetter(ie,R("../get-server-props.js")),g=e.createTemplate(te,R("../template/index.js"));e.addRoute({duplicateInAllLocales:!0,slug:S,fsPath:"",templateId:g,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[a],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([P,m])=>!m?.hide)||[];l&&e.addRedirect(S,{type:302,to:`${S}/${l}`},{trackOriginalSource:!1}),n.info("Catalog Entities plugin finished")},async afterRoutesCreated(e,i){await $("com.redocly.build.plugin.catalogEntities",async o=>{const r=await i.getConfig(),n=O(r.entitiesCatalog);if(o?.setAttribute("config",JSON.stringify(n)),!n.show)return;const{logger:a}=i;f.resetForRun();const g=_&&C.isDevelopMode,l=await z.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),P=new Q(l),{rbacConfigChanged:m}=await P.syncAndDetectChange(r.access?.rbac??null),c=g||m,s=await q.getInstance({baseDbDir:e.serverOutDir,removeExisting:g,databaseType:"local",runWithPragmaWalWriteOptimization:!0}),T=await j.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),u=new K(T),w=[new Z({fileHashManager:u,context:i,catalogEntitiesService:s,catalogConfig:n,shouldCalculateEntities:c}),new ee({actions:e,context:i,catalogEntitiesService:s,fileHashManager:u,fileType:h.OPENAPI_DESCRIPTION,shouldCalculateEntities:c}),new Y({actions:e,context:i,catalogEntitiesService:s,fileHashManager:u,fileType:h.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:c}),new U({actions:e,context:i,catalogEntitiesService:s,fileHashManager:u,fileType:h.GRAPHQL_DESCRIPTION,shouldCalculateEntities:c}),new X({actions:e,context:i,catalogEntitiesService:s,fileHashManager:u,fileType:h.ARAZZO_DESCRIPTION,shouldCalculateEntities:c})];a.info("Starting entities extractors...");const F=a.startTiming();await s.transaction(async()=>{await Promise.all(w.map(async t=>t.extract()))});const H=s.getEntitySources();e.setGlobalData({[B]:H}),await l.deleteByNamespace(k),a.infoTime(F,"Entities extractors finished");const y=C.CATALOG_MAX_REVISIONS??W,d=await J.create({baseDbDir:e.serverOutDir,databaseType:"local"}),N=!C.isDevelopMode&&C.isProductionEnv;let E=[];if(N&&d&&y>0){const t=await I.pruneLocalRevisions({localConnection:d,maxRevisions:y});if(t.prunedEntities>0||t.prunedRelations>0||t.legacyRelationsHealed>0||t.legacyRelationsDeleted>0){a.info(`Pruned entity revision history: entities=${t.prunedEntities} relations=${t.prunedRelations} legacyHealed=${t.legacyRelationsHealed} legacyDeleted=${t.legacyRelationsDeleted} files=${t.affectedSourceFiles.length} (keeping ${y} revisions per entity)`),E=t.affectedSourceFiles;for(const D of E)f.markSourceFileAsChanged(D)}}const{changedSourceFiles:L,removedSourceFiles:b}=f.getPublishDelta(),x=a.startTiming(),A=await V.publishFromLocalToRemote(m?{baseDbDir:e.serverOutDir}:{baseDbDir:e.serverOutDir,changedSourceFiles:L,removedSourceFiles:b});if(A.published&&a.infoTime(x,"Entities published to the database"),A.shouldFinalizeFileHashes){b.length&&await T.deleteFileHashes({op:"AND",conditions:[{field:"status",operator:"equal",value:v.OUTDATED},{field:"file_path",operator:"in",value:b}]});const t=f.getFileHashConfirmations();for(const{fileType:D,filePath:G,hash:M}of t)await T.upsertFileHash({fileType:D,filePath:G,hash:M,status:v.UP_TO_DATE});A.published&&E.length&&d&&await I.confirmPrunedFiles({localConnection:d,sourceFiles:E})}else a.warn("Skipped file_hashes finalization because remote catalog publish connection is unavailable; next build will retry.");const p=await f.getCatalogEntitiesData(s);o?.setAttribute("totalEntities",p.totalEntitiesCount),o?.setAttribute("entitiesCountByType",JSON.stringify(p.countOfEntitiesByType)),o?.setAttribute("totalFilesSkippedByHash",p.totalFilesSkippedByHash),o?.setAttribute("totalProcessedFiles",p.totalProcessedFiles),o?.setAttribute("extractors",p.extractors),_=!1})}}}var ve=ae;export{ae as catalogEntitiesPlugin,ve as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as t from"react";import{useMemo as
|
|
1
|
+
import*as t from"react";import{useMemo as l}from"react";import{QueryClientProvider as c,QueryClient as m}from"@tanstack/react-query";import{RedocSchema as u,StoreProvider as i,GraphQLTypeViewByName as d,MarkdownAdapterProvider as n,createMarkdocAdapter as f,buildGraphqlStoreFromSdl as s}from"@redocly/api-docs";import{Catalog as y}from"@redocly/theme/components/Catalog/Catalog";import{CatalogEntity as p}from"@redocly/theme/components/Catalog/CatalogEntity/CatalogEntity";import{NotFound as h}from"@redocly/theme/layouts/NotFound";const E=new m({defaultOptions:{queries:{refetchOnWindowFocus:!1}}}),o=f();function S({sdl:e,typeName:a}){const r=l(()=>{try{return s(e)}catch{return null}},[e]);return r?t.createElement(i,{apiStore:r,options:{specType:"graphql"}},t.createElement(n,{value:o},t.createElement(d,{typeName:a,fieldExpandLevel:0}))):null}function w({pageProps:e}){return e.status==="notFound"?t.createElement(h,null):t.createElement(c,{client:E},"entities"in e&&t.createElement(y,{entitiesTypes:e.entitiesTypes,catalogConfig:e.catalogConfig,filters:e.filters,initialEntitiesList:e.entities,catalogSwitcherItems:e.catalogSwitcherItems,initialViewMode:e.initialViewMode}),"entity"in e&&t.createElement(n,{value:o},t.createElement(p,{RedocSchema:u,StoreProvider:i,GraphqlTypeRenderer:S})))}export{w as default};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { REDOCLY_TEAMS_RBAC } from '@redocly/config';
|
|
2
|
-
import type { OpenAPIOperation, OpenAPISchema } from '@redocly/
|
|
2
|
+
import type { OpenAPIOperation, OpenAPISchema } from '@redocly/api-docs';
|
|
3
3
|
export type RedoclyOpenAPISchema = OpenAPISchema & {
|
|
4
4
|
[REDOCLY_TEAMS_RBAC]?: Record<string, string>;
|
|
5
5
|
'x-rbac'?: Record<string, string>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { OpenAPIDefinition } from '@redocly/api-docs';
|
|
2
|
+
import type { OpenAPIMediaType, OpenAPIOperation, OpenAPIPath, OpenAPIRequestBody, OpenAPIResponse } from '@redocly/api-docs';
|
|
3
3
|
import type { Logger } from '../../../tools/notifiers/logger.js';
|
|
4
4
|
export declare class OpenapiComponentContentExtractor {
|
|
5
5
|
#private;
|
|
6
6
|
constructor(logger: Logger);
|
|
7
7
|
extract({ component, definition, openapiOperation, visitedRefs, }: {
|
|
8
8
|
component: OpenAPIResponse | OpenAPIRequestBody;
|
|
9
|
-
definition:
|
|
9
|
+
definition: OpenAPIDefinition;
|
|
10
10
|
openapiOperation: OpenAPIOperation;
|
|
11
11
|
responseCode?: string;
|
|
12
12
|
visitedRefs?: Set<string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class i{#n;constructor(t){this.#n=t}extract({component:t,definition:p,openapiOperation:e,visitedRefs:r=new Set}){if("content"in t)return t?.content??{};const n=t?.$ref;if(!n)return{};if(r.has(n))return this.#n.warn(`Circular reference detected: ${n} for operation: ${e.operationId}`),{};r.add(n);const s=/^#\/components\/(?<componentType>.+)\/(?<componentName>.+)$/,c=n.match(s);if(!c?.groups?.componentType||!c?.groups?.componentName)return this.#n.warn(`Invalid component reference format: ${n}. Should be #/components/<componentType>/<componentName>`),{};const{componentType:m,componentName:a}=c.groups,o=p.
|
|
1
|
+
class i{#n;constructor(t){this.#n=t}extract({component:t,definition:p,openapiOperation:e,visitedRefs:r=new Set}){if("content"in t)return t?.content??{};const n=t?.$ref;if(!n)return{};if(r.has(n))return this.#n.warn(`Circular reference detected: ${n} for operation: ${e.operationId}`),{};r.add(n);const s=/^#\/components\/(?<componentType>.+)\/(?<componentName>.+)$/,c=n.match(s);if(!c?.groups?.componentType||!c?.groups?.componentName)return this.#n.warn(`Invalid component reference format: ${n}. Should be #/components/<componentType>/<componentName>`),{};const{componentType:m,componentName:a}=c.groups,o=p.components?.[m]?.[a];return o?"$ref"in o?this.extract({component:o,definition:p,openapiOperation:e,visitedRefs:r}):"content"in o?o.content??{}:{}:(this.#n.warn(`Component not found: ${m}/${a} for operation: ${e.operationId}`),{})}}export{i as OpenapiComponentContentExtractor};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Referenced } from '@redocly/openapi-core';
|
|
2
|
+
import type { OpenAPIDefinition } from '@redocly/api-docs';
|
|
3
|
+
import type { OpenAPISchema } from '@redocly/api-docs';
|
|
3
4
|
export declare class OpenapiSchemaResolver {
|
|
4
5
|
#private;
|
|
5
|
-
static resolveSchemaRefs(schema: OpenAPISchema
|
|
6
|
+
static resolveSchemaRefs(schema: Referenced<OpenAPISchema>, root: OpenAPIDefinition, visitedRefs?: Set<string>): OpenAPISchema;
|
|
6
7
|
static clearSchemaCache(): void;
|
|
7
8
|
}
|
|
8
9
|
//# sourceMappingURL=openapi-schema-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class
|
|
1
|
+
class p{static#e=new Map;static resolveSchemaRefs(i,r,a=new Set){if(!i||typeof i!="object")return i;if("$ref"in i&&typeof i.$ref=="string"){const t=i.$ref;if(this.#e.has(t))return this.#e.get(t)??{};if(a.has(t))return{$ref:t};const f=this.#t(t);if(f){const n=r.components?.schemas?.[f];if(n){const c=new Set(a);c.add(t);const o=this.resolveSchemaRefs(n,r,c);return this.#e.set(t,o),o}}return{$ref:t}}const e=i,s={...e};if(e.allOf&&Array.isArray(e.allOf)&&(s.allOf=e.allOf.map(t=>this.resolveSchemaRefs(t,r,a))),e.anyOf&&Array.isArray(e.anyOf)&&(s.anyOf=e.anyOf.map(t=>this.resolveSchemaRefs(t,r,a))),e.oneOf&&Array.isArray(e.oneOf)&&(s.oneOf=e.oneOf.map(t=>this.resolveSchemaRefs(t,r,a))),e.not&&(s.not=this.resolveSchemaRefs(e.not,r,a)),Array.isArray(e.items)?s.items=e.items.map(t=>this.resolveSchemaRefs(t,r,a)):typeof e.items=="object"&&(s.items=this.resolveSchemaRefs(e.items,r,a)),e.additionalProperties&&typeof e.additionalProperties=="object"&&(s.additionalProperties=this.resolveSchemaRefs(e.additionalProperties,r,a)),e.properties&&typeof e.properties=="object"){s.properties={};for(const[t,f]of Object.entries(e.properties))s.properties[t]=this.resolveSchemaRefs(f,r,a)}if(e.patternProperties&&typeof e.patternProperties=="object"){s.patternProperties={};for(const[t,f]of Object.entries(e.patternProperties))s.patternProperties[t]=this.resolveSchemaRefs(f,r,a)}return e.if&&(s.if=this.resolveSchemaRefs(e.if,r,a)),e.then&&(s.then=this.resolveSchemaRefs(e.then,r,a)),e.else&&(s.else=this.resolveSchemaRefs(e.else,r,a)),e.additionalItems&&typeof e.additionalItems=="object"&&(s.additionalItems=this.resolveSchemaRefs(e.additionalItems,r,a)),e.prefixItems&&Array.isArray(e.prefixItems)&&(s.prefixItems=e.prefixItems.map(t=>this.resolveSchemaRefs(t,r,a))),s}static clearSchemaCache(){this.#e.clear()}static#t=i=>{const r=i.match(/^#\/components\/schemas\/(.+)$/);return r?r[1]:null}}export{p as OpenapiSchemaResolver};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import P from"path";import{REDOCLY_ROUTE_RBAC as g,REDOCLY_TEAMS_RBAC as b}from"@redocly/config";import{deepMerge as S}from"../../../utils/object/deep-merge.js";import{buildWildcardRedirectsTree as v}from"../../utils/redirects/build-wildcard-redirects-tree.js";import{shaHexShort as D}from"../../utils/crypto/sha-hex-short.js";import{formatCustomScripts as u,formatCustomLinks as T}from"./format-custom-tags.js";import{applyL10nToRbacConfig as w,resolveDirectoryHashes as L}from"../../utils/rbac.js";import{copySeoAssets as O}from"./copy-seo-assets.js";import{normalizeRedirectSources as k}from"./normalize-redirect-sources.js";import{applyL10nToRedirects as E}from"./apply-l10n-to-redirects.js";import{DEFAULT_LOADERS as G}from"./loaders/index.js";import{resolveSearchFacets as B}from"./resolve-search-facets.js";import{telemetryTraceStep as _}from"../../../cli/telemetry/helpers/trace-step.js";import{transformMdAst as j}from"../markdown/runtime-transform.js";async function V(){return{id:"Config Parser",loaders:G,async processContent(e,{getConfig:i,fs:t}){await _("com.redocly.build.plugin.configParser",async o=>{const{contentDir:s,setGlobalConfig:a,setGlobalData:l}=e,r=await i(),c=r.access||{},d=w(t,c.rbac||{}),f={outdir:e.outdir,contentDir:s},y=await u(r.scripts?.head,f),h=await T(r.links,f),R=await u(r.scripts?.body,f),p=S(r,{headScriptTags:y,linkTags:h,postBodyScriptTags:R});o?.setAttribute("config",JSON.stringify(p));const m=r.redirects?k(r.redirects):{},C=Object.keys(m),A=p.banner?.map(n=>typeof n=="object"&&n!==null&&n.rbac?{...n,[b]:n.rbac}:n);a({...p,banner:A,access:{...c,requiresLogin:!!c.requiresLogin,rbac:d},directoryPaths:await L(t,c.rbac),seo:r.seo&&await O(r.seo,f.contentDir,f.outdir),redirects:E(m,r.l10n),wildcardRedirectsTree:v(m),originalRedirectSources:C}),B(r.search?.filters?.facets||[],e.getSearchFacets,e.setSearchFacets),l({removeAttribution:!!r.removeAttribution})})},async afterRoutesCreated(e,i){x(e);const t=e.getGlobalConfig("banner");if(Array.isArray(t)){const o=await Promise.all(t.map(async(s,a)=>{const{content:l,...r}=s,{ast:c}=await e.parseMarkdoc({input:{content:l,relativePath:"redocly.yaml"},context:i,resource:`redocly.yaml#banner${a}`}),{renderableAst:d}=await j(c,{variables:{},partials:{}},e.serverOutDir);return{...r,ast:d,hash:D(l)}}));e.setGlobalConfig({banner:o})}}}}function x(e){const i=e.getGlobalConfig("access")?.rbac,t=e.getGlobalConfig("directoryPaths");if(!(!i||Object.keys(i).length===0))for(const o of e.getAllRoutes()){if(o.versions&&t)for(const s of o.versions){const a=t[s.folderId],r=a==="."||a==="/"?"":a;s[g]={slug:s.link,fsPath:P.posix.join(r,"@"+s.version,"index.md")}}o[g]||o[b]||(o[g]={slug:o.slug,fsPath:o.fsPath})}}export{V as configParserPlugin};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ContentSlugs } from './config-parser/loaders/content-slugs-loader.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the canonical fsPath -> route slug function backed by the
|
|
4
|
+
* precalculated `content-slugs` cache. The cache is the single place where
|
|
5
|
+
* versioned folders (`@2.0` -> `2.0`, default version -> removed) and custom
|
|
6
|
+
* slugs are resolved, so every route slug must be derived through it —
|
|
7
|
+
* registering a route with a hand-built slug bypasses these transforms.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from `lifecycle.ts` so plugins that need a base slug before route
|
|
10
|
+
* creation (e.g. `api-docs`, which bakes absolute links into items at build
|
|
11
|
+
* time) compute the exact same slug the core route builder will.
|
|
12
|
+
*
|
|
13
|
+
* `contentSlugs` may be undefined if the cache entry is unpopulated; slugify
|
|
14
|
+
* then falls back to computing the slug directly.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createSlugify(contentSlugs: ContentSlugs | undefined): (relativePath: string) => string;
|
|
17
|
+
//# sourceMappingURL=create-slugify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import s from"path";import{combineUrls as n}from"@redocly/theme/core/utils";import{removeTrailingSlash as a}from"../../utils/url/remove-trailing-slash.js";import{slash as p}from"../../utils/path/slash.js";import{slug as f}from"../utils/index.js";import{parseBaseName as u}from"./utils.js";function b(i){return function(r){const o=p(r).replace(new RegExp("^(@i18n|@l10n)\\/"),""),l=i?.fileSlugs.get(o)||i?.dirSlugs.get(a(o));if(l)return l;const{baseName:t,isIndexFile:m}=u(r);let e=s.dirname(r.replace(new RegExp("^(@i18n|@l10n)\\/"),""));return e=e==="."?"/":e,n("/",f(m?e:n(e,t)),"/")}}export{b as createSlugify};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as u,INVITE_SLUG as h,PUBLIC_RBAC_SCOPE_ITEM as m,UI_ACCESSIBLE_CONFIG_PROPS as P,CONFIG_FILE_NAME as n,DEFAULT_SSO_IDP_TITLE as
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as u,INVITE_SLUG as h,PUBLIC_RBAC_SCOPE_ITEM as m,UI_ACCESSIBLE_CONFIG_PROPS as P,CONFIG_FILE_NAME as n,DEFAULT_SSO_IDP_TITLE as F}from"../../../constants/common.js";import{envConfig as T}from"../../config/env-config.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as p}from"../nav-utils.js";import{resolveLogoConfig as _}from"./resolve-logo.js";import{extractTeamNames as E}from"./extract-team-names.js";import{resolveProductsConfig as O}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as A}from"./resolve-catalog-entities.js";import{telemetryTraceStep as j}from"../../../cli/telemetry/helpers/trace-step.js";async function q(r){return{id:"Default Theme",async processContent(e){await j("com.redocly.build.plugin.defaultTheme",async()=>{const t=v(e),i=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,o=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:h,[c]:m,fsPath:h,templateId:o}),r.devLogin&&i){const a={frontmatter:{},seo:{title:"Login page"},authIdps:S(t),rbac:{teams:E(e.getConfig().access?.rbac)}},l=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:a})})}else if(t.length>1){const a={frontmatter:{},seo:{title:"Login page"},authIdps:S(t)},l=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:a})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),T.isDevelopMode&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:i,outdir:o}=e,a=e.getConfig(),{navbar:l,footer:D,userMenu:g,search:f,breadcrumbs:I,products:b}=a,C=Object.keys(a?.ssoDirect||{}).length>0,d=y(a),L={navFile:n,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...k(a),navbar:await p(l,i,e,t,L),footer:await p(D,i,e,t,L),breadcrumbs:{...I,prefixItems:await p(I?.prefixItems||[],i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},userMenu:{...g,hide:g?.hide??!C,menu:await p(g?.items,i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},logo:await _(a.logo,n,o,t.fs),auth:{idpsInfo:v(e),devLogin:r.devLogin&&C},products:await O(b,e,t),search:{...f,suggestedPages:await p(f?.suggestedPages,i,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await A(a.entitiesCatalog,n,o,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(r){const e=r.getConfig().ssoDirect;return Object.entries(e||{}).map(([i,o])=>({idpId:i,type:o.type,title:o.title}))}function S(r){return T.LOCALHOST_LOGIN?r:r.filter(e=>e.title!==F)}function k(r){const e={};for(const t of P)r[t]&&(e[t]=r[t]);return e}export{q as defaultThemePlugin,k as pickUiAccessibleConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as o}from"@redocly/config";import{getTemplatePath as c}from"./get-template-path.js";import{getDevOnboardingRbacConfig as s}from"./utils.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const d="apigee-";async function
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as o}from"@redocly/config";import{getTemplatePath as c}from"./get-template-path.js";import{getDevOnboardingRbacConfig as s}from"./utils.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const d="apigee-";async function M({contentDir:g}){return{id:"Developer Onboarding",requiredEntitlements:["devOnboarding"],async processContent(e,{getConfig:n}){await u("com.redocly.build.plugin.devOnboarding",async()=>{const t=await n();if(!t.developerOnboarding)return;const r=t.access?.rbac,a=e.createTemplate(d,c("./template/index.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:"/apps/",fsPath:"",templateId:a,hasClientRoutes:!0,[o]:r?s(r):void 0,getNavText:()=>Promise.resolve("My Apps"),getStaticData:async()=>({props:{proxyUrl:"https://api.enterprise.apigee.com/v1/organizations/ORGNAME/apis",seo:{title:"My Apps"}}})})})},async afterRoutesCreated(e){const n=e.getConfig();if(!n.developerOnboarding)return;const t=n.access?.rbac,a=e.getGlobalData().userMenu||{},i={type:"link",link:"/apps/",label:"My Apps",[o]:t?s(t):void 0,labelTranslationKey:"userMenu.devOnboardingLabel"},p=a?.menu||[],l={...a,menu:[...p,i]};e.setGlobalData({userMenu:l})}}}export{M as apiKeyMgmtPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{writeFileSync as F}from"node:fs";import S from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as b}from"../../constants/common.js";import{envConfig as O}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as C}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as $,isPathIgnored as M}from"../../utils/index.js";import{isGraphqlDoc as k}from"../graphql-docs/is-graphql-doc.js";import{isMarkdownPage as D}from"../markdown/is-markdown-page.js";import{isOpenapiDoc as E}from"../openapi-docs/is-openapi-doc.js";import{PRODUCT_NAME as p}from"../../../config/product-gates.js";import{isAsyncapiDoc as _}from"../asyncapi-docs/is-asyncapi-doc.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{getBilledCatalogBuildPagesCount as j}from"./utils/get-billed-catalog-build-pages-count.js";async function X(){return{id:"entitlements",async afterRoutesCreated(g,u){await I("build.plugin.entitlements",async t=>{const i=R.instance(),s=[],n=[],r=[],a=[],l=[];for(const{relativePath:e}of u.fs.scan())M(e)||(D(e)?s.push(e):k(e)?r.push(e):C(e)?a.push(e):await E(e,u)?n.push(e):await _(e,u)&&l.push(e));const c=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",s.length.toString()),t?.setAttribute("isMarkdownSupported",(!!c).toString()),s.length>0&&!c&&o.warn(`The product you are using ("${p}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const d=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",n.length.toString()),t?.setAttribute("isOpenApiSupported",(!!d).toString()),n.length>0&&!d&&o.warn(`The product you are using ("${p}") does not support OpenAPI documents. The following files are ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const
|
|
1
|
+
import{writeFileSync as F}from"node:fs";import S from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as b}from"../../constants/common.js";import{envConfig as O}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as C}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as R}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as $,isPathIgnored as M}from"../../utils/index.js";import{isGraphqlDoc as k}from"../graphql-docs/is-graphql-doc.js";import{isMarkdownPage as D}from"../markdown/is-markdown-page.js";import{isOpenapiDoc as E}from"../openapi-docs/is-openapi-doc.js";import{PRODUCT_NAME as p}from"../../../config/product-gates.js";import{isAsyncapiDoc as _}from"../asyncapi-docs/is-asyncapi-doc.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";import{getBilledCatalogBuildPagesCount as j}from"./utils/get-billed-catalog-build-pages-count.js";async function X(){return{id:"entitlements",async afterRoutesCreated(g,u){await I("com.redocly.build.plugin.entitlements",async t=>{const i=R.instance(),s=[],n=[],r=[],a=[],l=[];for(const{relativePath:e}of u.fs.scan())M(e)||(D(e)?s.push(e):k(e)?r.push(e):C(e)?a.push(e):await E(e,u)?n.push(e):await _(e,u)&&l.push(e));const c=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",s.length.toString()),t?.setAttribute("isMarkdownSupported",(!!c).toString()),s.length>0&&!c&&o.warn(`The product you are using ("${p}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const d=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",n.length.toString()),t?.setAttribute("isOpenApiSupported",(!!d).toString()),n.length>0&&!d&&o.warn(`The product you are using ("${p}") does not support OpenAPI documents. The following files are ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const m=i.canAccessFeature("asyncapi");t?.setAttribute("totalAsyncApiFiles",l.length.toString()),t?.setAttribute("isAsyncApiSupported",(!!m).toString()),l.length>0&&!m&&o.warn(`The product you are using ("${p}") does not support AsyncAPI documents. The following files are ignored: ${l.map(()=>"%rp").join(", ")}`,...l);const f=i.canAccessFeature("graphql");t?.setAttribute("totalGraphqlFiles",r.length.toString()),t?.setAttribute("isGraphqlSupported",(!!f).toString()),r.length>0&&!f&&o.warn(`The product you are using ("${p}") does not support GraphQL documents. The following files are ignored: ${r.map(()=>"%rp").join(", ")}`,...r);const A=i.canAccessFeature("reactPages");t?.setAttribute("totalReactFiles",a.length.toString()),t?.setAttribute("isReactPagesSupported",(!!A).toString()),a.length>0&&!A&&o.warn(`The product you are using ("${p}") does not support React pages. The following files are ignored: ${a.map(()=>"%rp").join(", ")}`,...a);const P=(await u.getConfig()).entitiesCatalog,y=$(g.getAllRoutes()),{total:T}=await j(g.serverOutDir,P),h=y+T;t?.setAttribute("totalBilledPages",h.toString());const w=O.REDOCLY_METADATA_OUTPUT_FOLDER;w&&(o.info("Save total pages..."),F(S.join(w,b),JSON.stringify({totalPages:h},null)))})}}}export{X as entitlementsPlugin};
|