@redocly/realm 0.138.0-next.0 → 0.138.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +207 -0
- package/dist/bin.js +0 -0
- package/dist/cli/build/analytics/collect-analytics.js +1 -1
- package/dist/cli/build/analytics/collectors/get-sidebars-usage.d.ts +12 -0
- package/dist/cli/build/analytics/collectors/get-sidebars-usage.js +1 -0
- package/dist/cli/build/index.js +1 -1
- package/dist/cli/develop.js +1 -1
- package/dist/cli/eject/resolveEjectParams.js +1 -1
- package/dist/cli/generate/string-utils.js +1 -1
- package/dist/cli/stats/collectors/extension-sampling.js +1 -1
- package/dist/cli/translations/collect-config-translations.js +1 -1
- package/dist/client/App.js +1 -1
- package/dist/client/TestProvider.d.ts +3 -1
- package/dist/client/TestProvider.js +1 -1
- package/dist/client/api-request-handlers-entry.d.ts +1 -1
- package/dist/client/app/Link.js +1 -1
- package/dist/client/app/ReviewComments/ReviewComments.js +2 -2
- package/dist/client/app/Sidebar/Sidebar.js +1 -1
- package/dist/client/app/Sidebar/useSidebarItems.js +1 -1
- package/dist/client/app/hooks/codeHighlight/treeview-transformer.js +1 -1
- package/dist/client/app/hooks/codeHighlight/useCodeHighlight.js +1 -1
- package/dist/client/app/hooks/index.d.ts +1 -1
- package/dist/client/app/hooks/index.js +1 -1
- package/dist/client/app/hooks/markdown/useMarkdownText.js +1 -1
- package/dist/client/app/hooks/useConsent.d.ts +11 -0
- package/dist/client/app/hooks/useConsent.js +1 -0
- package/dist/client/app/l10n/L10nContext.d.ts +10 -0
- package/dist/client/app/l10n/L10nContext.js +1 -0
- package/dist/client/app/l10n/hooks/useL10n.js +1 -1
- package/dist/client/app/l10n/hooks/useTranslate.js +1 -1
- package/dist/client/app/l10n/hooks/useTranslationKeys.d.ts +2 -0
- package/dist/client/app/l10n/hooks/useTranslationKeys.js +1 -1
- package/dist/client/app/l10n/ssrL10n.d.ts +4 -0
- package/dist/client/app/l10n/ssrL10n.js +1 -0
- 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.js +1 -1
- package/dist/client/app/markdoc/hooks/use-store.d.ts +2 -3
- package/dist/client/app/pages/DevLogin/DevLoginForm.js +1 -1
- package/dist/client/app/pages/Invite/Invite.js +1 -1
- package/dist/client/app/search/index.d.ts +1 -1
- package/dist/client/app/search/index.js +1 -1
- package/dist/client/app/search/useSearch.d.ts +3 -0
- package/dist/client/app/search/useSearch.js +1 -1
- package/dist/client/app/webmcp/index.d.ts +2 -0
- package/dist/client/app/webmcp/index.js +1 -0
- package/dist/client/app/webmcp/tools/api-tools.d.ts +8 -0
- package/dist/client/app/webmcp/tools/api-tools.js +1 -0
- package/dist/client/app/webmcp/tools/shared.d.ts +13 -0
- package/dist/client/app/webmcp/tools/shared.js +1 -0
- package/dist/client/app/webmcp/tools/site-tools.d.ts +5 -0
- package/dist/client/app/webmcp/tools/site-tools.js +3 -0
- package/dist/client/app/webmcp/types.d.ts +36 -0
- package/dist/client/app/webmcp/types.js +0 -0
- package/dist/client/app/webmcp/useWebMcpTools.d.ts +9 -0
- package/dist/client/app/webmcp/useWebMcpTools.js +1 -0
- package/dist/client/mcp-tool-handlers-entry.d.ts +1 -1
- package/dist/client/middleware-entry.d.ts +1 -1
- package/dist/client/providers/page-data/hooks.d.ts +2 -0
- package/dist/client/providers/page-data/hooks.js +1 -1
- package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
- package/dist/client/runtime/loader.js +1 -1
- package/dist/client/server-entry.d.ts +2 -1
- package/dist/client/server-entry.js +1 -1
- package/dist/client/server-props-entry.d.ts +1 -1
- package/dist/client/templates/api-docs/helpers.js +1 -1
- package/dist/client/templates/api-docs/template.js +7 -3
- package/dist/client/utils/catalog/parse-filter-query.js +1 -1
- package/dist/client/{app/Sidebar/helpers → utils}/filter-out-versioned-items.d.ts +12 -2
- package/dist/client/utils/filter-out-versioned-items.js +1 -0
- package/dist/client/utils/navigation-tabs.d.ts +14 -0
- package/dist/client/utils/navigation-tabs.js +1 -0
- package/dist/compiled/svgo/svgo-node.js +39 -39
- 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/markdoc/nodes/table.d.ts +2 -0
- package/dist/markdoc/nodes/table.js +1 -1
- package/dist/server/config/env-config.d.ts +0 -6
- package/dist/server/config/env-schema.d.ts +0 -15
- package/dist/server/config/env-schemas/feature-flags.d.ts +0 -12
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/constants/common.d.ts +3 -1
- package/dist/server/constants/common.js +1 -1
- package/dist/server/constants/entitlements.js +1 -1
- package/dist/server/constants/plugins/consent.d.ts +3 -0
- package/dist/server/constants/plugins/consent.js +1 -0
- package/dist/server/constants/plugins/search.js +1 -1
- package/dist/server/esbuild/esbuild-logger.js +3 -3
- package/dist/server/plugins/analytics/adobe/index.js +1 -1
- package/dist/server/plugins/analytics/amplitude/browser-hooks.js +1 -1
- package/dist/server/plugins/analytics/amplitude/index.js +1 -1
- package/dist/server/plugins/analytics/fullstory/index.js +1 -1
- package/dist/server/plugins/analytics/ga/index.js +1 -1
- package/dist/server/plugins/analytics/gtm/browser-hooks.js +1 -1
- package/dist/server/plugins/analytics/gtm/index.js +1 -1
- package/dist/server/plugins/analytics/heap/browser-hooks.js +1 -1
- package/dist/server/plugins/analytics/rudderstack/index.js +1 -1
- package/dist/server/plugins/analytics/segment/index.js +1 -1
- package/dist/server/plugins/api-docs/index.js +1 -1
- package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.d.ts +9 -0
- package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.js +1 -0
- package/dist/server/plugins/api-docs/utils/decorators.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.d.ts +5 -1
- package/dist/server/plugins/catalog-entities/database/repositories/common/version-repository.js +7 -1
- package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.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/utils/ajv-validator.js +1 -1
- package/dist/server/plugins/catalog-entities/utils/extract-parts-from-components-ref.js +1 -1
- package/dist/server/plugins/catalog-entities/utils/is-valid-tag-name.js +1 -1
- package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
- package/dist/server/plugins/config-parser/format-custom-tags.d.ts +1 -0
- package/dist/server/plugins/config-parser/format-custom-tags.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
- package/dist/server/plugins/config-parser/loaders/versions-config-loader.js +1 -1
- package/dist/server/plugins/config-parser/safe-parse.js +1 -1
- package/dist/server/plugins/consent/build-consent-script.d.ts +6 -0
- package/dist/server/plugins/consent/build-consent-script.js +230 -0
- package/dist/server/plugins/consent/gate-ssr-components.d.ts +5 -0
- package/dist/server/plugins/consent/gate-ssr-components.js +1 -0
- package/dist/server/plugins/consent/index.d.ts +3 -0
- package/dist/server/plugins/consent/index.js +1 -0
- package/dist/server/plugins/consent/is-consent-enabled.d.ts +8 -0
- package/dist/server/plugins/consent/is-consent-enabled.js +1 -0
- package/dist/server/plugins/consent/zone-modes.d.ts +8 -0
- package/dist/server/plugins/consent/zone-modes.js +1 -0
- package/dist/server/plugins/default-theme/extract-team-names.js +1 -1
- package/dist/server/plugins/dev-onboarding/template/App.js +5 -5
- package/dist/server/plugins/dev-onboarding/template/components/ApiKeyOverview.js +3 -3
- package/dist/server/plugins/get-reserved-routes.d.ts +4 -2
- package/dist/server/plugins/get-reserved-routes.js +1 -1
- package/dist/server/plugins/l10n/index.js +1 -1
- package/dist/server/plugins/lifecycle.js +2 -2
- package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/file-chunk-parser.js +2 -2
- package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +2 -0
- package/dist/server/plugins/markdown/search/get-ai-search-documents.js +9 -9
- package/dist/server/plugins/markdown/search/nodes/tag-node.d.ts +1 -1
- package/dist/server/plugins/markdown/search/nodes/tag-node.js +1 -1
- package/dist/server/plugins/markdown/search/to-markdown.js +1 -1
- package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +1 -1
- package/dist/server/plugins/mcp/audit/audit-log.js +1 -1
- package/dist/server/plugins/mcp/audit/secret-patterns.js +1 -1
- package/dist/server/plugins/mcp/auth/assistant-anonymous-token.d.ts +9 -0
- package/dist/server/plugins/mcp/auth/assistant-anonymous-token.js +1 -0
- package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +5 -3
- package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
- package/dist/server/plugins/mcp/codemode/build-tool-list.d.ts +6 -1
- package/dist/server/plugins/mcp/codemode/build-tool-list.js +2 -2
- package/dist/server/plugins/mcp/codemode/build-tool-type-declarations.js +4 -4
- package/dist/server/plugins/mcp/codemode/capabilities/fetch/index.js +3 -3
- package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +0 -1
- package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +1 -2
- package/dist/server/plugins/mcp/codemode/capabilities/utils.js +4 -4
- package/dist/server/plugins/mcp/codemode/code-execution-audit.d.ts +3 -2
- package/dist/server/plugins/mcp/codemode/code-execution-audit.js +1 -1
- package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +3 -4
- package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -1
- package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +2 -2
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +0 -2
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.js +1 -1
- package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
- package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +2 -2
- package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/core/create-anonymous-session.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/core/whoami.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.d.ts +2 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/endpoint-suggestions.d.ts +6 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/endpoint-suggestions.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.d.ts +2 -0
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/load-api-description.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +6 -2
- package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.d.ts +20 -14
- package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/credential-validation.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +16 -10
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +5 -5
- package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/ssrf-guard.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/url-placeholders.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/rate-limit/ip-key.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.d.ts +0 -6
- package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +2 -2
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/mcp-credentials-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +35 -35
- 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 +2 -4
- package/dist/server/plugins/mcp/types.d.ts +5 -11
- package/dist/server/plugins/mcp/utils/disabled-tools.d.ts +3 -0
- package/dist/server/plugins/mcp/utils/disabled-tools.js +1 -0
- package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +2 -2
- package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -1
- package/dist/server/plugins/mcp/utils/mcp-client.js +1 -1
- package/dist/server/plugins/mcp/utils/public-endpoint.d.ts +9 -0
- package/dist/server/plugins/mcp/utils/public-endpoint.js +1 -0
- package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +2 -1
- package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -1
- package/dist/server/plugins/mcp/utils/tool-registration.d.ts +2 -1
- package/dist/server/plugins/mcp/utils/tool-registration.js +1 -1
- package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +0 -7
- package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +5 -7
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
- package/dist/server/plugins/nav-utils.js +1 -1
- package/dist/server/plugins/scorecard-classic/index.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/Grid/GridHeader.js +21 -8
- package/dist/server/plugins/scorecard-classic/template/ScorecardDashboard.js +3 -3
- package/dist/server/plugins/scorecard-classic/template/index.styles.d.ts +1 -0
- package/dist/server/plugins/scorecard-classic/template/index.styles.js +15 -5
- package/dist/server/plugins/scorecard-classic/template/useData.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
- package/dist/server/plugins/search/engines/flexsearch/index.js +2 -1
- package/dist/server/plugins/search/engines/flexsearch/search-index.d.ts +2 -2
- package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
- package/dist/server/plugins/search/llmstxt/index.js +1 -1
- package/dist/server/plugins/sidebars/index.js +7 -3
- package/dist/server/plugins/sidebars/tabs.d.ts +19 -0
- package/dist/server/plugins/sidebars/tabs.js +1 -0
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/providers/database/pagination/after-and-before.js +1 -1
- package/dist/server/providers/database/pagination/utils/decode-cursor.js +1 -1
- package/dist/server/providers/database/pagination/utils/is-base-64.js +1 -1
- package/dist/server/ssr/render.js +1 -1
- package/dist/server/store.d.ts +2 -0
- package/dist/server/store.js +1 -1
- package/dist/server/tools/notifiers/helpers/privacy/mask-subject.js +1 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii-from-url.js +1 -1
- package/dist/server/tools/notifiers/helpers/privacy/remove-pii.js +1 -1
- package/dist/server/types/plugins/search.d.ts +7 -5
- package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.d.ts +3 -0
- package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.js +1 -0
- package/dist/server/utils/envs/interpolate-env-variables.js +1 -1
- package/dist/server/utils/rbac-expand.js +1 -1
- package/dist/server/utils/rbac.js +1 -1
- package/dist/server/utils/redact-url.d.ts +6 -0
- package/dist/server/utils/redact-url.js +1 -0
- package/dist/server/utils/report-all-errors.js +1 -1
- package/dist/server/utils/sandbox-context.js +1 -1
- package/dist/server/utils/search/highlight-text-for-search.d.ts +1 -0
- package/dist/server/utils/search/highlight-text-for-search.js +1 -1
- package/dist/server/utils/search/text-match.d.ts +6 -0
- package/dist/server/utils/search/text-match.js +1 -0
- package/dist/server/utils/static-data.js +1 -1
- package/dist/server/utils/write-problems-report.d.ts +3 -0
- package/dist/server/utils/write-problems-report.js +1 -0
- package/dist/server/web-server/auth.d.ts +16 -2
- package/dist/server/web-server/auth.js +4 -4
- package/dist/server/web-server/jwt/jwt.js +1 -1
- package/dist/server/web-server/jwt/token-types.d.ts +11 -0
- package/dist/server/web-server/jwt/token-types.js +1 -0
- package/dist/server/web-server/jwt/types.d.ts +4 -4
- package/dist/server/web-server/jwt/types.js +1 -1
- package/dist/server/web-server/middleware/apiKeyMiddleware.js +1 -1
- package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
- package/dist/server/web-server/middleware/ensureSearchData.js +1 -1
- package/dist/server/web-server/middleware/responseHeadersMiddleware.js +1 -1
- package/dist/server/web-server/middleware/telemetry-middleware.js +1 -1
- package/dist/server/web-server/routes/ask-ai.js +1 -1
- package/dist/server/web-server/routes/auth.d.ts +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/cors-proxy.js +2 -2
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
- package/dist/server/web-server/routes/semantic-search.d.ts +1 -1
- package/dist/server/web-server/routes/semantic-search.js +1 -1
- package/dist/server/web-server/routes/static-content.js +1 -1
- package/dist/server/workers/worker-pool.js +1 -1
- package/dist/types/entitlements.d.ts +1 -0
- package/dist/utils/path/parse-path-versions.js +1 -1
- package/dist/utils/string/to-kebab-case.js +1 -1
- package/package.json +10 -10
- package/dist/client/app/Sidebar/helpers/filter-out-versioned-items.js +0 -1
- package/dist/client/app/hooks/useAnchorPositioning.d.ts +0 -6
- package/dist/client/app/hooks/useAnchorPositioning.js +0 -1
- package/dist/server/plugins/mcp/auth/token-audience-telemetry.d.ts +0 -7
- package/dist/server/plugins/mcp/auth/token-audience-telemetry.js +0 -1
- package/dist/server/plugins/mcp/auth/token-audience.d.ts +0 -6
- package/dist/server/plugins/mcp/auth/token-audience.js +0 -1
- /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-blocklist.d.ts +0 -0
- /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-blocklist.js +0 -0
- /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-safe-lookup.d.ts +0 -0
- /package/dist/server/{plugins/mcp/gateway-mcp/fetch → web-server/utils}/ssrf-safe-lookup.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{ELICITATION_TTL_MS as
|
|
1
|
+
import{withPathPrefix as g}from"@redocly/theme/core/utils";import{MCP_CREDENTIALS_ROUTE as C}from"../../../constants/mcp.js";import{ELICITATION_TTL_MS as f}from"../gateway-mcp/secret-store.js";const b=6,v=`<svg class="logo" width="193" height="56" viewBox="0 0 193 56" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Redocly">
|
|
2
2
|
<g clip-path="url(#redocly-logo-clip)">
|
|
3
3
|
<path d="M84.3634 40.7533H80.0357L73.199 30.9849H69.8119V40.8155H66.1738V14.5592H76.3353C78.9067 14.5592 80.9139 15.368 82.2308 16.9857C83.5483 18.5412 84.1756 20.5322 84.1756 22.8343C84.1756 25.0119 83.6107 26.7541 82.4193 28.3095C81.2902 29.865 79.5339 30.7361 77.2134 30.8605L84.3634 40.7533ZM69.8743 17.8568V27.6251H76.2098C79.22 27.6251 80.5999 25.4475 80.5999 22.7098C80.5999 20.0344 79.22 17.7945 76.3353 17.7945H69.8743V17.8568Z" fill="currentColor"/>
|
|
4
4
|
<path d="M103.117 33.225H88.5654C89.0042 36.1492 91.2623 38.078 94.3355 38.078C96.5312 38.078 98.5384 37.0203 99.4789 35.3403C99.8553 35.4648 100.357 35.7137 101.047 35.9626L102.553 36.4603C101.047 39.5091 97.9111 41.1889 94.2731 41.1889C91.701 41.1889 89.506 40.3179 87.6873 38.638C85.931 36.8959 85.1152 34.7182 85.1152 31.9184C85.1152 29.1185 85.9934 26.9409 87.6873 25.2609C89.4436 23.5188 91.6386 22.71 94.2731 22.71C96.8445 22.71 98.9771 23.581 100.608 25.2609C102.302 26.9409 103.18 29.1807 103.18 31.9184C103.117 32.5405 103.117 32.9139 103.117 33.225ZM99.6674 30.4873C99.228 27.563 97.0954 25.7587 94.21 25.7587C91.1999 25.7587 88.9418 27.6252 88.5654 30.4873H99.6674Z" fill="currentColor"/>
|
|
@@ -13,7 +13,7 @@ import{ELICITATION_TTL_MS as m}from"../gateway-mcp/secret-store.js";const f=6,b=
|
|
|
13
13
|
<path d="M28.5385 16.6127H44.4703C45.3484 16.6127 46.0383 15.9282 46.0383 15.0572C46.0383 14.1861 45.3484 13.5017 44.4703 13.5017H28.5385C27.6604 13.5017 26.9705 14.1861 26.9705 15.0572C26.9077 15.8661 27.6604 16.6127 28.5385 16.6127Z" fill="currentColor"/>
|
|
14
14
|
</g>
|
|
15
15
|
<defs><clipPath id="redocly-logo-clip"><rect width="193" height="56" fill="white"/></clipPath></defs>
|
|
16
|
-
</svg>`;function r(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}function s(e){return`<!doctype html>
|
|
16
|
+
</svg>`;function r(e){return e.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""")}function c(){return r(g(C))}function s(e){return`<!doctype html>
|
|
17
17
|
<html lang="en">
|
|
18
18
|
<head>
|
|
19
19
|
<meta charset="utf-8">
|
|
@@ -88,21 +88,21 @@ label.check input{width:auto;margin:0}
|
|
|
88
88
|
footer{margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--border);font-size:.75rem;color:var(--text-muted);text-align:center;line-height:1.45}
|
|
89
89
|
</style>
|
|
90
90
|
</head>
|
|
91
|
-
<body><main class="card">${
|
|
92
|
-
</html>`}function l(e){return`<h1>\u{1F512} ${r(e)}</h1>`}function d(){return"<footer>Secured by Redocly · Credentials never enter the AI conversation</footer>"}function
|
|
91
|
+
<body><main class="card">${v}${e}</main></body>
|
|
92
|
+
</html>`}function l(e){return`<h1>\u{1F512} ${r(e)}</h1>`}function d(){return"<footer>Secured by Redocly · Credentials never enter the AI conversation</footer>"}function u(){return`<p class="hint">This link expires ${Math.round(f/6e4)} minutes after it was issued. If it stops working, request a new one in your AI client.</p>`}function h({name:e,schemeLabel:t,schemes:o}){return o&&o.length>1?e:t?`${e} (${t})`:e}function y(e){return`
|
|
93
93
|
<div class="section">
|
|
94
94
|
<h2>Remove stored credentials</h2>
|
|
95
95
|
<p class="hint">This API already has credentials stored. Enter new credentials to replace them, or remove them to make calls anonymous again.</p>
|
|
96
|
-
<form method="post" action="
|
|
96
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
97
97
|
<input type="hidden" name="token" value="${r(e)}">
|
|
98
98
|
<input type="hidden" name="mode" value="clear">
|
|
99
99
|
<button class="danger" type="submit">Remove credentials</button>
|
|
100
100
|
</form>
|
|
101
|
-
</div>`}function
|
|
101
|
+
</div>`}function Z(e,t,o){const n=o?`<p class="error">${r(o)}</p>`:"";if(e.schemes&&e.schemes.length>1)return I(e,e.schemes,t,n);const a=e.hasExistingSecret?y(t):"",i=h(e);switch(e.auth.kind){case"bearer":return $(i,t,a,n);case"apiKey":return x(i,t,e.auth.header,a,n);case"cookie":return k(i,t,e.auth.name,a,n);case"oauth2ClientCredentials":return w(i,t,e.auth.scopes,a,n);default:return A(i,t,a,n)}}function $(e,t,o,n){return s(`
|
|
102
102
|
${l(`Credentials for ${e}`)}
|
|
103
103
|
${n}
|
|
104
104
|
<p class="hint">Encrypted and visible only to you for 24 hours (anonymous) or 30 days (signed in).<br />Sent to the API as the <code>Authorization header</code>. It never passes through the AI conversation.</p>
|
|
105
|
-
<form method="post" action="
|
|
105
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
106
106
|
<input type="hidden" name="token" value="${r(t)}">
|
|
107
107
|
<input type="hidden" name="mode" value="token">
|
|
108
108
|
<label for="secret">API token</label>
|
|
@@ -111,12 +111,12 @@ ${n}
|
|
|
111
111
|
<button type="submit">Save credentials</button>
|
|
112
112
|
</form>
|
|
113
113
|
${o}
|
|
114
|
-
${
|
|
115
|
-
${d()}`)}function
|
|
114
|
+
${u()}
|
|
115
|
+
${d()}`)}function x(e,t,o,n,a){return s(`
|
|
116
116
|
${l(`Credentials for ${e}`)}
|
|
117
117
|
${a}
|
|
118
118
|
<p class="hint">Encrypted and visible only to you for 24 hours (anonymous) or 30 days (signed in).<br />Sent to the API as the <code>${r(o)}</code> header. It never passes through the AI conversation.</p>
|
|
119
|
-
<form method="post" action="
|
|
119
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
120
120
|
<input type="hidden" name="token" value="${r(t)}">
|
|
121
121
|
<input type="hidden" name="mode" value="token">
|
|
122
122
|
<label for="secret">${r(o)} value</label>
|
|
@@ -124,12 +124,12 @@ ${a}
|
|
|
124
124
|
<button type="submit">Save credentials</button>
|
|
125
125
|
</form>
|
|
126
126
|
${n}
|
|
127
|
-
${
|
|
128
|
-
${d()}`)}function
|
|
127
|
+
${u()}
|
|
128
|
+
${d()}`)}function k(e,t,o,n,a){return s(`
|
|
129
129
|
${l(`Credentials for ${e}`)}
|
|
130
130
|
${a}
|
|
131
131
|
<p class="hint">Encrypted and visible only to you for 24 hours (anonymous) or 30 days (signed in).<br />Sent to the API as the <code>${r(o)}</code> cookie. It never passes through the AI conversation.</p>
|
|
132
|
-
<form method="post" action="
|
|
132
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
133
133
|
<input type="hidden" name="token" value="${r(t)}">
|
|
134
134
|
<input type="hidden" name="mode" value="token">
|
|
135
135
|
<label for="secret">${r(o)} cookie value</label>
|
|
@@ -138,14 +138,14 @@ ${a}
|
|
|
138
138
|
<button type="submit">Save credentials</button>
|
|
139
139
|
</form>
|
|
140
140
|
${n}
|
|
141
|
-
${
|
|
142
|
-
${d()}`)}function
|
|
141
|
+
${u()}
|
|
142
|
+
${d()}`)}function w(e,t,o,n,a){const i=o.length>0?o.map(r).join(", "):"default scopes";return s(`
|
|
143
143
|
${l(`Credentials for ${e}`)}
|
|
144
144
|
${a}
|
|
145
145
|
<p class="hint">Paste your token, or provide your OAuth2 client credentials.</p>
|
|
146
146
|
<div class="section">
|
|
147
147
|
<h2>I have a token</h2>
|
|
148
|
-
<form method="post" action="
|
|
148
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
149
149
|
<input type="hidden" name="token" value="${r(t)}">
|
|
150
150
|
<input type="hidden" name="mode" value="token">
|
|
151
151
|
<label for="secret">API token</label>
|
|
@@ -157,7 +157,7 @@ ${a}
|
|
|
157
157
|
<div class="section">
|
|
158
158
|
<h2>Exchange client credentials</h2>
|
|
159
159
|
<p class="hint">We request a token from the API on your behalf. Scopes: ${i}.</p>
|
|
160
|
-
<form method="post" action="
|
|
160
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
161
161
|
<input type="hidden" name="token" value="${r(t)}">
|
|
162
162
|
<input type="hidden" name="mode" value="client-credentials">
|
|
163
163
|
<label for="client_id">Client ID</label>
|
|
@@ -168,12 +168,12 @@ ${a}
|
|
|
168
168
|
</form>
|
|
169
169
|
</div>
|
|
170
170
|
${n}
|
|
171
|
-
${
|
|
172
|
-
${d()}`)}function
|
|
171
|
+
${u()}
|
|
172
|
+
${d()}`)}function A(e,t,o,n){return s(`
|
|
173
173
|
${l(`Credentials for ${e}`)}
|
|
174
174
|
${n}
|
|
175
175
|
<p class="hint">The value is stored and encrypted only for you for 24 hours (anonymous) or 30 days (signed in).<br />It is sent to the API as the <code>Authorization</code> header. It never passes through the AI conversation.</p>
|
|
176
|
-
<form method="post" action="
|
|
176
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
177
177
|
<input type="hidden" name="token" value="${r(t)}">
|
|
178
178
|
<input type="hidden" name="mode" value="token">
|
|
179
179
|
<label for="secret">Authorization header value</label>
|
|
@@ -181,45 +181,45 @@ ${n}
|
|
|
181
181
|
<button type="submit">Save credentials</button>
|
|
182
182
|
</form>
|
|
183
183
|
${o}
|
|
184
|
-
${
|
|
185
|
-
${d()}`)}function
|
|
184
|
+
${u()}
|
|
185
|
+
${d()}`)}function I(e,t,o,n){const a=t.map((i,p)=>P(i,p)).join(`
|
|
186
186
|
`);return s(`
|
|
187
187
|
${l(`Credentials for ${e.name}`)}
|
|
188
188
|
${n}
|
|
189
189
|
<p class="hint">This API accepts more than one kind of credential. Fill in the one(s) you have and leave the rest blank - each value is stored encrypted for you only (24 hours for anonymous callers, 30 days when signed in) and sent straight to the API. It never passes through the AI conversation.</p>
|
|
190
|
-
<form method="post" action="
|
|
190
|
+
<form method="post" action="${c()}" autocomplete="off">
|
|
191
191
|
<input type="hidden" name="token" value="${r(o)}">
|
|
192
192
|
<input type="hidden" name="mode" value="multi">
|
|
193
193
|
${a}
|
|
194
194
|
<button type="submit">Save credentials</button>
|
|
195
195
|
</form>
|
|
196
|
-
${
|
|
197
|
-
${d()}`)}function
|
|
196
|
+
${u()}
|
|
197
|
+
${d()}`)}function P(e,t){const o=M(e.auth),n=e.label?`<p class="hint">${r(e.label)}</p>`:"",a=S(e.operations),i=e.hasExistingSecret?`<label class="check"><input type="checkbox" name="remove__${t}" value="1"> Remove the stored credential</label>`:"",p=e.hasExistingSecret?'<span class="badge stored">Stored</span>':'<span class="badge">Not set</span>';return`
|
|
198
198
|
<div class="section">
|
|
199
|
-
<h2>${r(e.name)} ${
|
|
199
|
+
<h2>${r(e.name)} ${p}</h2>
|
|
200
200
|
<p class="hint">Sent to the API as the <code>${r(o.code)}</code> ${o.suffix}.</p>
|
|
201
201
|
${n}
|
|
202
202
|
${a}
|
|
203
|
-
${
|
|
203
|
+
${_(e.auth,t)}
|
|
204
204
|
${i}
|
|
205
|
-
</div>`}function
|
|
205
|
+
</div>`}function _(e,t){const o=`secret__${t}`;if(e.kind==="oauth2ClientCredentials"){const a=e.scopes.length>0?e.scopes.map(r).join(", "):"default scopes";return`<label for="${o}">API token</label>
|
|
206
206
|
<input type="password" id="${o}" name="${o}" placeholder="paste a token you already have">
|
|
207
207
|
<p class="hint">Or exchange client credentials for one (scopes: ${a}). We add <code>Bearer</code> automatically.</p>
|
|
208
208
|
<label for="client_id__${t}">Client ID</label>
|
|
209
209
|
<input type="text" id="client_id__${t}" name="client_id__${t}">
|
|
210
210
|
<label for="client_secret__${t}">Client secret</label>
|
|
211
|
-
<input type="password" id="client_secret__${t}" name="client_secret__${t}">`}const n=
|
|
212
|
-
<input type="password" id="${o}" name="${o}" placeholder="value">`}function
|
|
211
|
+
<input type="password" id="client_secret__${t}" name="client_secret__${t}">`}const n=H(e);return`<label for="${o}">${r(n)}</label>
|
|
212
|
+
<input type="password" id="${o}" name="${o}" placeholder="value">`}function H(e){switch(e.kind){case"apiKey":return`${e.header} value`;case"cookie":return`${e.name} cookie value`;case"bearer":return"API token";default:return"Authorization header value"}}function M(e){switch(e.kind){case"apiKey":return{code:e.header,suffix:"header"};case"cookie":return{code:e.name,suffix:"cookie"};case"bearer":return{code:"Authorization",suffix:"header (bearer token)"};case"oauth2ClientCredentials":return{code:"Authorization",suffix:"header (OAuth2 bearer token)"};default:return{code:"Authorization",suffix:"header"}}}function S(e){if(!e||e.length===0)return"";const t=e.slice(0,b).map(r).join(", "),o=e.length-b,n=o>0?`, and ${o} more`:"";return`<p class="hint">Used by ${t}${n}.</p>`}function E(e){return s(`
|
|
213
213
|
${l("Credentials removed")}
|
|
214
|
-
<p>Credentials for ${r(
|
|
215
|
-
${d()}`)}function
|
|
214
|
+
<p>Credentials for ${r(h(e))} are removed. Calls to the API are anonymous again until you add new credentials.</p>
|
|
215
|
+
${d()}`)}function R(e,t){const o=t.saved.length===0?"Credentials removed":t.removed.length===0?"Credentials saved":"Credentials updated",n=[t.saved.length>0?`<p>Saved: ${m(t.saved)}.</p>`:"",t.removed.length>0?`<p>Removed: ${m(t.removed)}.</p>`:"",t.stored.length>0?`<p>${r(e.name)} now has stored credentials for ${m(t.stored)}.</p>`:`<p>${r(e.name)} has no stored credentials. Calls to the API are anonymous until you add new ones.</p>`];return s(`
|
|
216
216
|
${l(o)}
|
|
217
217
|
${n.join(`
|
|
218
218
|
`)}
|
|
219
219
|
<p>Retry in your AI client, or confirm any prompt it left open. You can close this tab.</p>
|
|
220
220
|
<p class="hint">This link is single-use and is now spent. To change anything, request a new one in your AI client.</p>
|
|
221
|
-
${d()}`)}function
|
|
221
|
+
${d()}`)}function m(e){return e.map(t=>`<code>${r(t)}</code>`).join(", ")}function F(e){return s(`
|
|
222
222
|
${l("Credentials saved")}
|
|
223
|
-
<p>Credentials for ${r(
|
|
223
|
+
<p>Credentials for ${r(h(e))} are saved. Retry in your AI client, or confirm any prompt it left open. You can close this tab.</p>
|
|
224
224
|
<p class="hint">This link is single-use and is now spent. To change anything, request a new one in your AI client.</p>
|
|
225
|
-
${d()}`)}function
|
|
225
|
+
${d()}`)}function q(){return s(`${l("Link expired")}<p>This credentials link is invalid, already used, or older than ${Math.round(f/6e4)} minutes. Retry in your AI client to get a fresh link.</p>${d()}`)}export{E as clearedPage,Z as formPage,R as multiOutcomePage,q as notFoundPage,F as successPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fileURLToPath as
|
|
1
|
+
import{fileURLToPath as U}from"node:url";import{dirname as $,join as h}from"node:path";import{MCP_ROUTE as k,PUBLIC_MCP_ROUTE as D}from"@redocly/theme/core/constants/mcp";import{logger as c}from"../../tools/notifiers/logger.js";import{reporter as F}from"../../tools/notifiers/reporter.js";import{isDefined as B}from"../../../utils/guards/is-defined.js";import{MCP_CREDENTIALS_HANDLER_ID as P,MCP_CREDENTIALS_ROUTE as x,MCP_DOCS_SERVER_HANDLER_ID as E,MCP_NOT_ALLOWED_TEMPLATE_ID as V}from"../../constants/mcp.js";import{bundledOpenApiDocumentsToMcpOpenApi as J,bundledGraphqlDocumentsToMcpOpenApi as W,buildGraphqlDescriptions as X,collectIgnoredRoutes as z,filterIgnoredApiDescriptions as A,getCleanedUpApiDescriptions as K,isMcpInRedirects as Q}from"./utils.js";import{getMcpMode as R,isMcpElicitationEnabled as Y,isMcpGatewayEnabled as Z}from"./utils/mode.js";import{getPublicMcpEndpointStatus as _}from"./utils/public-endpoint.js";import{findGatedToolNames as ee}from"./utils/find-gated-tool-names.js";import{getDefaultToolSchemas as te}from"./docs-mcp/tool-schemas.js";import{EXECUTE_TOOL_SCHEMA as oe}from"./codemode/tools/execute-schema.js";import{isGatewayCapabilityEnabled as ie,isGatewayEligible as re}from"./gateway-mcp/eligibility.js";import{resolveGatewayFetchLimits as se}from"./gateway-mcp/rate-limit/limits.js";import{resetCustomMcpTools as ne,scanCustomMcpTools as ae}from"./custom-tools/scan-custom-tools.js";import{telemetryTraceStep as ce}from"../../../cli/telemetry/helpers/trace-step.js";import{DEFAULT_DOCS_MCP_SERVER_NAME as S}from"./constants.js";const M=$(U(import.meta.url));async function pe(){let i;const l={registeredToolNames:[],warnedNoOutputSchemaTools:new Set};let m=0,u=!1;return{id:"mcp",async processContent(e,n){await ce("com.redocly.build.plugin.mcp",async s=>{const o=await n.getConfig(),{mcp:r,redirects:f}=o;if(s?.setAttribute("config",JSON.stringify(r||{})),s?.setAttribute("mcpMode",R()),s?.setAttribute("mcpGateway",String(Z())),r?.hide||r?.docs?.hide){ne(e,l);return}Q(f)&&await F.panicOnBuildContentError('The reserved route "/mcp" cannot be used in redirect configuration. Please remove any redirects involving "/mcp" from your redocly.yaml config.'),e.createTemplate(V,"@redocly/theme/layouts/McpNotAllowed");const p=!!o?.access?.requiresLogin,b=o?.access?.rbac||{},g=R(),d=Y(),{budgetPerExec:T}=se();if(!i){c.info("Configuring MCP servers...");const w=J(await e.loadApiDocuments(n)),O=W(await e.loadApiDocuments(n)),v=r?.docs?.ignore||[],L=K(A(w,v)),q=ie(r),C=new Map;for(const t of L){const H=t.definition.info?.title||"",j=t.definition.info?.version||"";C.set(t.relativePath,{name:H,description:typeof t.definition.info?.description=="string"?t.definition.info.description:"",version:j,servers:t.definition.servers||[],relativePath:t.relativePath,...q&&re(t.definition.info,t.relativePath,b)?{fetchEligible:!0}:{}})}const y=X(A(O,v)),I=Object.values(o.products||{}).map(t=>t?.name).filter(B),N=o.l10n?.locales?.map(t=>t.code)??n.fs.localeFolders,G=te({products:I,locales:N,requiresLogin:p,rbac:b,hasGraphqlApis:y.length>0,elicitationEnabled:d,hasCallableApis:C.values().some(t=>t.fetchEligible),feedbackHidden:o.feedback?.hide===!0});e.addMcpTools(h(M,"./docs-mcp/tools/index.js"),G),g==="code"&&e.addMcpTools(h(M,"./codemode/tools/execute.js"),[oe]),i={apiDescriptionsMap:Object.fromEntries(C),graphqlDescriptions:y}}const a=await ae(e,n,l);s?.setAttribute("customToolsCount",String(a)),a!==m&&(m=a,a>0&&c.info(`Registered ${a} custom MCP tool${a===1?"":"s"} from @mcp folders`)),await de({actions:e,handlerPath:h(M,"./handlers/docs-mcp-handler.js"),apiDescriptionsMap:i.apiDescriptionsMap,graphqlDescriptions:i.graphqlDescriptions,mcpConfig:r,mcpMode:g,elicitationEnabled:d,gatewayFetchBudgetPerExec:T,publicEndpointStatus:_(o)}),u||(c.info("Registered Docs MCP Server endpoint at /mcp"),u=!0)})},async afterRoutesCreated(e,n){const s=await n.getConfig(),{mcp:o}=s,r=!o?.hide&&!o?.docs?.hide;e.markGatedMcpTools(await ee(e.getMcpTools())),e.setGlobalData({mcpData:{docs:{enabled:r,name:o?.docs?.name||S,publicEndpoint:_(s)==="served"}}})}}}var Se=pe;async function de({actions:i,handlerPath:l,apiDescriptionsMap:m,graphqlDescriptions:u,mcpConfig:e,mcpMode:n,elicitationEnabled:s,gatewayFetchBudgetPerExec:o,publicEndpointStatus:r}){i.createRequestHandler(E,l);const f=p=>async(b,g)=>{const d=z(g.getAllRoutes(),e?.docs?.ignore||[]);return d.length>0&&c.verbose(`mcp.docs.ignore: hiding ${d.length} page routes from MCP search`),{props:{config:{apiDescriptionsMap:m,graphqlDescriptions:u,mcpDocsServerName:e?.docs?.name||S,mcpMode:n,elicitationEnabled:s,gatewayFetchBudgetPerExec:o,searchIgnoredRoutes:d,...p?{isPublicEndpoint:p}:{}},serverOutDir:i.serverOutDir,tools:i.getMcpTools().map(({importPath:T,...a})=>a)}}};if(i.addApiRoute({slug:k,requestHandlerId:E,httpMethod:"all",getStaticData:f(!1)}),r==="no-protected-content"?c.info(`mcp.docs.publicEndpoint is enabled, but the project has no protected content - /mcp already serves anonymous users, skipping ${D}.`):r==="anonymous-denied"?c.info(`mcp.docs.publicEndpoint is enabled, but anonymous users are denied the MCP feature (rbac.features.mcp or requiresLogin) - skipping ${D}.`):r==="served"&&(i.addApiRoute({slug:D,requestHandlerId:E,httpMethod:"all",getStaticData:f(!0)}),c.verbose(`Registered public Docs MCP Server endpoint at ${D}`)),s){const p=h(M,"./handlers/mcp-credentials-handler.js");i.createRequestHandler(P,p),i.addApiRoute({slug:x,requestHandlerId:P,httpMethod:"all",getStaticData:async()=>({props:{}})}),c.verbose("Registered MCP credentials endpoint at /mcp/credentials")}}export{Se as default,pe as mcpServerPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{logger as
|
|
1
|
+
import{logger as v}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as L,MCP_TOOL_IS_AVAILABLE_KEY as k}from"../../../workers/mcp-tool-worker-pool.js";import{CREATE_ANONYMOUS_SESSION_TOOL_NAME as C,MANAGE_API_CREDENTIALS_TOOL_NAME as y}from"../constants.js";import{isAnonymousSessionToolAvailable as D}from"../docs-mcp/tools/core/create-anonymous-session.js";import{isManageApiCredentialsToolAvailable as N,manageApiCredentials as x,manageApiCredentialsSchema as w}from"../codemode/tools/manage-credentials.js";import{EXECUTE_TOOL_SCHEMA as _}from"../codemode/tools/execute-schema.js";import{EXECUTE_TOOL_NAME as I,CODE_MODE_TOOL_NAMES as H,FETCH_TOOL_NAME as P}from"../codemode/constants.js";import{buildCodeModeInstructions as R,buildExecuteDescription as U}from"../codemode/prompts.js";import{toToolListEntries as F}from"../codemode/build-tool-list.js";import{composeExecuteAnnotations as z,getActiveCapabilities as B}from"../codemode/capabilities/index.js";import{describeToolsSchema as W,describeTools as X}from"../codemode/tools/describe-tools.js";import{availableSandboxTools as Y}from"../utils/available-sandbox-tools.js";import{isToolDisabledByCaller as S}from"../utils/disabled-tools.js";import{toRegisterToolConfig as h}from"../utils/tool-registration.js";import{createMcpServer as $,createToolDispatch as j,extractSerializableContext as G}from"./mcp-server.js";function O(r,t){const o=t.schema;if(r)return o;const{sessionHandle:T,...p}=o.properties;return{...o,properties:p}}function K(r){return Object.fromEntries(r.map(t=>[t.name,t.schema]))}async function me({name:r,tools:t,context:o,skills:T=[],getKv:p}){const n=G(o),s=o.mcpMode==="code",l=s?B(o):[],b=l.some(e=>e.id===P),c=s?await Y(t.filter(e=>!H.has(e.name)),n):[],E=F(c,l),d=D(o)&&!S(C,o.metadata),g=s&&N(o)&&!S(y,o.metadata),m=$(r,s?R(b,E):void 0),u={getClientCapabilities:()=>m.server.getClientCapabilities(),getKv:p},f=j(s?{...n,sandboxToolSchemas:K(c)}:n,u),A=async e=>{try{return await L.exec(k,[{toolName:e,context:n}],{timeout:1e4})}catch(i){return v.error(`Failed to check MCP tool availability for "${e}": ${i instanceof Error?i.message:String(i)}`),!1}};if(s){const e=[{tool:{..._,description:U(b,E),schema:O(d,_),annotations:z(c,l)},callback:f(I)},{tool:W(c,l),callback:X(c,A,l,o)}],i=t.find(a=>a.name===C);if(i&&d&&e.push({tool:i,callback:f(i.name)}),g){const a=w(o);e.push({tool:{...a,schema:O(d,a)},callback:x(n,u)})}for(const{tool:a,callback:M}of e)m.registerTool(a.name,h(a),M)}else await Promise.all(t.map(async e=>{const i=m.registerTool(e.name,h({...e,outputSchema:void 0}),f(e.name));await A(e.name)||i.disable()}));for(const e of T)m.registerResource(e.slug,e.uri,{title:e.name,description:e.description,mimeType:"text/markdown"},async()=>({contents:[{uri:e.uri,mimeType:"text/markdown",text:e.content}]}));return m}export{me as createDocsMcpServer};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import{McpServer as
|
|
1
|
+
import{McpServer as C}from"@modelcontextprotocol/server";import{logger as S}from"../../../tools/notifiers/logger.js";import{mcpToolWorkers as O,MCP_TOOL_WORKER_KEY as _}from"../../../workers/mcp-tool-worker-pool.js";import{secretStore as L}from"../gateway-mcp/secret-store.js";import{readAuthRequiredMeta as D,stripAuthRequiredMeta as E,upstreamAuthKey as b}from"../gateway-mcp/upstream-auth.js";import{acceptedCredentialsLink as K,buildCredentialsAcceptedHint as j,buildCredentialsToolHint as F,buildUpstreamCredentialFallback as q,buildUpstreamCredentialInputRequired as v,credentialElicitationAnswer as H,dedupeElicitation as N,isStatelessRequest as P,schemeLabelOf as $,supportsUrlElicitation as B}from"../gateway-mcp/elicitation.js";import{DEFAULT_SCHEME_NAME as y,resolveUpstreamApiAuth as G}from"../gateway-mcp/upstream-auth-scheme.js";import{MISSING_SESSION_HANDLE_MESSAGE as V,resolveSecretSubject as W}from"../gateway-mcp/subject.js";const Y=6e4;function ue(e,t){return new C({name:e,version:new Date().toISOString().slice(0,10)},{capabilities:{logging:{}},...t?{instructions:t}:{}})}function le(e,t){return r=>async(n,s)=>{S.info(`MCP tool called: ${r}`);const i=e.elicitationEnabled??!1,c=P(s.mcpReq),a=i?W(e.user,n.sessionHandle):{kind:"anonymous"},o=a.kind==="resolved"?a.subject:void 0;if(a.kind==="invalid")return{content:[{type:"text",text:a.message}],isError:!0};const u=async()=>{if(!(!i||!o||!t?.getKv))try{const m=await t.getKv();return await L.getSecretsForSubject(m,o)}catch(m){S.warn(`gateway mcp secret store error, continuing unauthenticated: ${String(m)}`);return}};let l;const p=async()=>{l=await u();const m={toolName:r,args:n,context:{...e,upstreamSecrets:l},extra:ee(s)};return await O.exec(_,[m],{timeout:Y})};let d=await p();const f=D(d);if(f.length>0&&i&&!o)return E(I(d,[{type:"text",text:V}]));if(f.length>0&&i&&o&&t?.getKv){S.info(`gateway mcp credentials prompt: era=${c?"2026-07-28":"2025"} clientElicitation=${J(t)}`);const m=await t.getKv(),h=await Q(e,f),w=f.map(U=>X(U,h)),k=Z(l),g=c?await x(e,s,w,o,m,k,h,t):await z(e,w,o,m,k,h);switch(g.kind){case"inputRequired":return g.result;case"retry":d=await p();break;case"prependText":d=I(d,[{type:"text",text:g.text},...d.content]);break;case"none":break}}return E(d)}}function I(e,t){const{structuredContent:r,...n}=e;return{...n,content:t,isError:!0}}function J(e){const t=e?.getClientCapabilities()?.elicitation;if(!t)return"none";const r=[t.form?"form":void 0,t.url?"url":void 0].filter(Boolean);return r.length>0?r.join("+"):"none"}async function Q(e,t){const r=new Map;for(const n of new Set(t.map(s=>s.api)))r.set(n,await G(e,n));return r}function X(e,t){const r=t.get(e.api);if(!r)return{...e,scheme:e.scheme??y};const n=e.scheme&&r.schemes[e.scheme]?e.scheme:r.defaultScheme;return{...e,scheme:n}}function Z(e){const t=new Set;for(const[r,n]of Object.entries(e??{}))for(const s of Object.keys(n))t.add(b({api:r,scheme:s}));return t}function R(e,t){return e.status===401&&!t.has(b(e))}function T(e,t){const r=t.get(e.api),n=e.sentScheme??e.scheme;return r&&n?$(r.schemes,n):void 0}function M(e,t){return e.map(r=>F(r,T(r,t))).join(`
|
|
2
2
|
|
|
3
|
-
`)}function
|
|
4
|
-
|
|
5
|
-
`)}function U(e,t,r,n,s){const[i,...c]=t,a=s.get(i.api),o=i.scheme??a?.defaultScheme??q,p=M(i,s);return{subject:r,baseUrl:e.baseUrl??"",target:{api:i.api,name:i.name,scheme:o,...p?{schemeLabel:p}:{}},auth:a?.schemes[o]??{kind:"raw"},...a?{apiAuth:a}:{},kv:n,hasExistingSecret:!1,reason:{kind:"authFailure",status:i.status,...i.detail?{detail:i.detail}:{},otherApiNames:c.map(u=>u.name)}}}async function ee(e,t,r,n,s,i,c,a){if(B(t.mcpReq.inputResponses))return{kind:"none"};const o=r.filter(l=>R(l,i));if(o.length===0)return{kind:"prependText",text:k(r,c)};const p=o.filter(l=>I(l,c));if(p.length>0){const l=r.filter(d=>!p.includes(d));return{kind:"prependText",text:C(p,l,c)}}const u=U(e,o,n,s,c);return v(a?.getClientCapabilities())?{kind:"inputRequired",result:await P(u)}:{kind:"prependText",text:await T(u)}}async function te(e,t,r,n,s,i){const c=t.filter(u=>R(u,s));if(c.length===0)return{kind:"prependText",text:k(t,i)};const a=c.filter(u=>I(u,i));if(a.length>0){const u=t.filter(l=>!a.includes(l));return{kind:"prependText",text:C(a,u,i)}}const o=U(e,c,r,n,i);return{kind:"prependText",text:await $(`${r}:${b(c[0])}`,()=>T(o))}}function re(e){return{sessionId:e.sessionId,authInfo:e.http?.authInfo,requestId:e.mcpReq.id,_meta:e.mcpReq._meta}}function me(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata,upstreamAuthorization:e.upstreamAuthorization,mcpMode:e.mcpMode,elicitationEnabled:e.elicitationEnabled,gatewayFetchBudgetPerExec:e.gatewayFetchBudgetPerExec,clientIp:e.clientIp,client:e.client,clientVersion:e.clientVersion,upstreamSecrets:e.upstreamSecrets,searchIgnoredRoutes:e.searchIgnoredRoutes,internalBaseUrl:e.internalBaseUrl,sandboxToolSchemas:e.sandboxToolSchemas,fs:void 0}}export{pe as createMcpServer,de as createToolDispatch,me as extractSerializableContext};
|
|
3
|
+
`)}function A(e,t,r,n,s){const[i,...c]=t,a=s.get(i.api),o=i.scheme??a?.defaultScheme??y,l=(i.schemes?.length??0)<=1?T(i,s):void 0;return{subject:r,baseUrl:e.baseUrl??"",target:{api:i.api,name:i.name,scheme:o,...l?{schemeLabel:l}:{}},auth:a?.schemes[o]??{kind:"raw"},...a?{apiAuth:a}:{},kv:n,hasExistingSecret:!1,reason:{kind:"authFailure",status:i.status,...i.detail?{detail:i.detail}:{},otherApiNames:c.map(p=>p.name)}}}async function x(e,t,r,n,s,i,c,a){const o=H(t.mcpReq.inputResponses);if(o==="declined")return{kind:"none"};const u=r.filter(p=>R(p,i));if(u.length===0)return{kind:"prependText",text:M(r,c)};if(o==="accepted"){const p=await K(t.mcpReq.requestState(),{kv:s,subject:n,baseUrl:e.baseUrl??"",apis:u.map(f=>f.api)}),d=p?.apiName??u[0].name;return{kind:"prependText",text:j(d,p?.url)}}const l=A(e,u,n,s,c);return B(a?.getClientCapabilities())?{kind:"inputRequired",result:await v(l)}:{kind:"prependText",text:await q(l)}}async function z(e,t,r,n,s,i){const c=t.filter(u=>R(u,s));if(c.length===0)return{kind:"prependText",text:M(t,i)};const a=A(e,c,r,n,i);return{kind:"prependText",text:await N(`${r}:${b(c[0])}`,()=>q(a))}}function ee(e){return{sessionId:e.sessionId,authInfo:e.http?.authInfo,requestId:e.mcpReq.id,_meta:e.mcpReq._meta}}function pe(e){return{user:e.user,config:e.config,outdir:e.outdir,baseUrl:e.baseUrl,params:e.params,query:e.query,cookies:e.cookies,apiDescriptionsMap:e.apiDescriptionsMap,graphqlDescriptions:e.graphqlDescriptions,products:e.products,accessToken:e.accessToken,metadata:e.metadata,upstreamAuthorization:e.upstreamAuthorization,mcpMode:e.mcpMode,elicitationEnabled:e.elicitationEnabled,gatewayFetchBudgetPerExec:e.gatewayFetchBudgetPerExec,clientIp:e.clientIp,client:e.client,clientVersion:e.clientVersion,requestId:e.requestId,messageId:e.messageId,upstreamSecrets:e.upstreamSecrets,searchIgnoredRoutes:e.searchIgnoredRoutes,internalBaseUrl:e.internalBaseUrl,sandboxToolSchemas:e.sandboxToolSchemas,fs:void 0}}export{ue as createMcpServer,le as createToolDispatch,pe as extractSerializableContext};
|
|
@@ -63,17 +63,6 @@ export type McpEndpoint = OpenAPIOperation & {
|
|
|
63
63
|
'x-mcp'?: XMcpConfig;
|
|
64
64
|
};
|
|
65
65
|
export type McpMode = 'tools' | 'code';
|
|
66
|
-
export type McpUserInfo = {
|
|
67
|
-
email?: string;
|
|
68
|
-
name?: string;
|
|
69
|
-
sub?: string;
|
|
70
|
-
aud?: string | string[];
|
|
71
|
-
client_id?: string;
|
|
72
|
-
scope?: string;
|
|
73
|
-
iat?: number;
|
|
74
|
-
exp?: number;
|
|
75
|
-
[key: string]: unknown;
|
|
76
|
-
};
|
|
77
66
|
export type SemanticSearchResult = {
|
|
78
67
|
title: string;
|
|
79
68
|
url: string;
|
|
@@ -85,6 +74,8 @@ export type McpToolWorkerResponse = CallToolResult & {
|
|
|
85
74
|
};
|
|
86
75
|
export type ToolArgs = Record<string, unknown>;
|
|
87
76
|
export type McpToolCallback = ToolCallback<StandardSchemaWithJSON<ToolArgs, ToolArgs>>;
|
|
77
|
+
/** The caller and request fields every MCP telemetry event and audit record carries. */
|
|
78
|
+
export type McpCallAttribution = Pick<McpToolContext, 'client' | 'clientVersion' | 'requestId' | 'messageId'>;
|
|
88
79
|
export type McpToolExtra = {
|
|
89
80
|
sessionId?: string;
|
|
90
81
|
authInfo?: AuthInfo;
|
|
@@ -104,6 +95,8 @@ export type McpToolContext = Omit<ApiFunctionsContext, 'telemetry' | 'getKv' | k
|
|
|
104
95
|
clientIp?: string;
|
|
105
96
|
client?: string;
|
|
106
97
|
clientVersion?: string;
|
|
98
|
+
requestId?: string;
|
|
99
|
+
messageId?: string;
|
|
107
100
|
upstreamSecrets?: UpstreamSecrets;
|
|
108
101
|
searchIgnoredRoutes?: string[];
|
|
109
102
|
internalBaseUrl?: string;
|
|
@@ -124,6 +117,7 @@ export type McpToolExecutionParams = {
|
|
|
124
117
|
};
|
|
125
118
|
export type CustomMcpToolsState = {
|
|
126
119
|
registeredToolNames: string[];
|
|
120
|
+
warnedNoOutputSchemaTools: Set<string>;
|
|
127
121
|
};
|
|
128
122
|
export type ToolDefinitionValidationResult = {
|
|
129
123
|
ok: true;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function r(o,s){const l=s?.disabledTools;return Array.isArray(l)&&l.includes(o)}export{r as isToolDisabledByCaller};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { jsonSchemaValidator } from '@modelcontextprotocol/server';
|
|
2
2
|
/**
|
|
3
3
|
* Validates tool arguments with the same engine and options the forked SDK
|
|
4
4
|
* (@redocly/mcp-typescript-sdk) used internally, so migrating to the upstream
|
|
5
5
|
* v2 SDK does not change which arguments are accepted. The SDK default would
|
|
6
6
|
* be a lenient draft-2020-12 engine instead.
|
|
7
7
|
*/
|
|
8
|
-
export declare const mcpJsonSchemaValidator:
|
|
8
|
+
export declare const mcpJsonSchemaValidator: jsonSchemaValidator;
|
|
9
9
|
//# sourceMappingURL=json-schema-validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AjvJsonSchemaValidator as
|
|
1
|
+
import{AjvJsonSchemaValidator as a}from"@modelcontextprotocol/server/validators/ajv";import l from"@redocly/ajv";const c=new a(new l({allErrors:!0})),j={getValidator(r){const o=c.getValidator(r),t=Object.keys(r.properties??{});return t.length===0||r.additionalProperties!==!1?o:n=>{const e=o(n),i=Object.keys(n??{}).filter(s=>!t.includes(s));return e.valid||i.length===0?e:{...e,errorMessage:`${e.errorMessage}. Unknown properties: ${i.join(", ")}. Accepted properties: ${t.join(", ")}.`}}}};export{j as mcpJsonSchemaValidator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const o="(none)",r="(unparsed)",N=40,i=/^[A-Za-z0-9._\- ]+/,c
|
|
1
|
+
const o="(none)",r="(unparsed)",N=40,i=/^[A-Za-z0-9._\- ]+/,c=/(?<!\s)\s+([0-9]\S*)(?:[^\S\n].*)?$/,l=/^[/\s]+v?([0-9][^\s;,)]*)/;function a(e){return E(e.headers.get("user-agent"))}function E(e){if(e==null)return{client:o};const n=i.exec(e)?.[0]??"",t=n.replace(c,"").trim();if(!t)return{client:r};const s=c.exec(n)?.[1]??l.exec(e.slice(n.length))?.[1];return{client:t.replace(/\s+/g,"-").toLowerCase().slice(0,40),clientVersion:s?.slice(0,40)}}export{E as parseUserAgent,a as resolveMcpClient};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RedoclyConfig } from '@redocly/config';
|
|
2
|
+
export type PublicMcpEndpointStatus = 'served' | 'disabled' | 'no-protected-content' | 'anonymous-denied';
|
|
3
|
+
/**
|
|
4
|
+
* Whether `/mcp-public` is served for this config, and why not when it is not.
|
|
5
|
+
* Ignores the `mcp` entitlement, so it is safe in request handlers; build-time callers
|
|
6
|
+
* that need the full answer must also check the entitlement.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getPublicMcpEndpointStatus(config: Pick<RedoclyConfig, 'mcp' | 'access'>): PublicMcpEndpointStatus;
|
|
9
|
+
//# sourceMappingURL=public-endpoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{canAnonymousAccessMcpFeature as c}from"../../../utils/rbac/can-anonymous-access-mcp-feature.js";import{shouldHandleMcpAuth as i}from"../../../utils/rbac/should-handle-mcp-auth.js";function d(t){const{mcp:n,access:e}=t;if(n?.hide||n?.docs?.hide||!n?.docs?.publicEndpoint)return"disabled";const o=!!e?.requiresLogin,r=e?.rbac||{};return i(o,r)?c(r,o)?"served":"anonymous-denied":"no-protected-content"}export{d as getPublicMcpEndpointStatus};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { McpServerType } from '../types.js';
|
|
1
|
+
import type { McpCallAttribution, McpServerType, McpToolContext } from '../types.js';
|
|
2
2
|
/** CloudEvent resource attributes shared by every `mcpServer` telemetry event. */
|
|
3
3
|
export declare function serverAttributes(serverType: McpServerType): {
|
|
4
4
|
id: "docs";
|
|
5
5
|
object: 'mcpServer';
|
|
6
6
|
uri: string;
|
|
7
7
|
};
|
|
8
|
+
export declare function callAttribution(context: McpToolContext | undefined): McpCallAttribution;
|
|
8
9
|
//# sourceMappingURL=telemetry-attributes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e
|
|
1
|
+
function r(e){return{id:e,object:"mcpServer",uri:`urn:redocly:realm:mcp:server:${e}`}}function i(e){return{client:e?.client,clientVersion:e?.clientVersion,requestId:e?.requestId,messageId:e?.messageId}}export{i as callAttribution,r as serverAttributes};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { McpToolSchema } from '../../../types';
|
|
2
2
|
import type { ToolArgs } from '../types.js';
|
|
3
3
|
export declare function normalizeToolDisplayName(tool: McpToolSchema): McpToolSchema;
|
|
4
|
-
/** The `registerTool` config for a tool schema, with its input
|
|
4
|
+
/** The `registerTool` config for a tool schema, with its input and output schemas compiled for validation. */
|
|
5
5
|
export declare function toRegisterToolConfig(tool: McpToolSchema): {
|
|
6
6
|
title: string | undefined;
|
|
7
7
|
description: string;
|
|
8
8
|
inputSchema: import("@modelcontextprotocol/server").StandardSchemaWithJSON<ToolArgs, ToolArgs>;
|
|
9
|
+
outputSchema?: import("@modelcontextprotocol/server").StandardSchemaWithJSON<unknown, unknown> | undefined;
|
|
9
10
|
annotations: {
|
|
10
11
|
title?: string | undefined;
|
|
11
12
|
readOnlyHint?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fromJsonSchema as
|
|
1
|
+
import{fromJsonSchema as i}from"@modelcontextprotocol/server";import{mcpJsonSchemaValidator as e}from"./json-schema-validator.js";function c(t){const n=t.title??t.annotations?.title;return n?{...t,title:n,annotations:{...t.annotations,title:n}}:t}function u(t){const{title:n,description:a,schema:r,outputSchema:o,annotations:m}=c(t);return{title:n,description:a,inputSchema:i(r,e),...o?{outputSchema:i(o,e)}:{},annotations:m}}export{c as normalizeToolDisplayName,u as toRegisterToolConfig};
|
|
@@ -4,13 +4,6 @@ import type { XMcpConfig, XMcpSection } from '../types.js';
|
|
|
4
4
|
export declare function isEndpointHidden(endpoint: {
|
|
5
5
|
'x-mcp'?: XMcpConfig;
|
|
6
6
|
} | undefined, section: XMcpSection): boolean;
|
|
7
|
-
/**
|
|
8
|
-
* Returns false when the endpoint is hidden for `section`; otherwise strips x-mcp from the
|
|
9
|
-
* output and returns true.
|
|
10
|
-
*/
|
|
11
|
-
export declare function checkEndpointAndDeleteXMcp(endpoint: {
|
|
12
|
-
'x-mcp'?: XMcpConfig;
|
|
13
|
-
}, section: XMcpSection): boolean;
|
|
14
7
|
/** Whether the definition's info-level x-mcp hides it for `section` (defaults to `docs`). */
|
|
15
8
|
export declare function isDefinitionHidden(info?: OpenAPIDefinition['info'], section?: XMcpSection): boolean;
|
|
16
9
|
/** Whether the API explicitly opts into the gateway via `x-mcp.gateway`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function
|
|
1
|
+
function r(t,e){return!!t?.["x-mcp"]?.[e]?.hide}function o(t,e){if(!t)return!1;const n=t["x-mcp"];return!n||typeof n!="object"?!1:e?n[e]?.hide===!0:n.docs?.hide===!0}function i(t){if(!t)return!1;const e=t["x-mcp"];return!!(e&&typeof e=="object"&&e.gateway)}export{i as hasGatewayConfig,o as isDefinitionHidden,r as isEndpointHidden};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetry as h}from"../../../telemetry/index.js";import{McpServerType as c}from"../constants.js";import{EXECUTE_TOOL_NAME as w}from"../codemode/constants.js";import{isPlainObject as p}from"../../../../utils/guards/is-plain-object.js";import{logMcpToolCallAudit as g,reportMcpToolCalled as
|
|
1
|
+
import{telemetry as h}from"../../../telemetry/index.js";import{McpServerType as c}from"../constants.js";import{EXECUTE_TOOL_NAME as w}from"../codemode/constants.js";import{isPlainObject as p}from"../../../../utils/guards/is-plain-object.js";import{logMcpToolCallAudit as g,reportMcpToolCalled as b,reportMcpToolError as u}from"./mcp-tool-telemetry.js";import{isToolDisabledByCaller as S}from"../utils/disabled-tools.js";import{attachToolFileSystem as E}from"./tool-file-system.js";import{callAttribution as M}from"../utils/telemetry-attributes.js";import{importMcpToolHandlers as A}from"./import-mcp-tool-handlers.js";function O(e){return e.content.map(t=>t.type==="text"?t.text:"")}async function X(e){h.initialize();const{toolName:t,args:o,extra:s}=e,r=E(e.context),n=r?.mcpMode??"tools",a=M(r),d=performance.now();try{const i=await C(t);if(!i)throw new Error(`MCP tool "${t}" is not registered or its module does not export a handler for "${t}". Expected \`export default { '${t}': handler }\` or a single tool definition with \`description\` and \`execute\` as the default export.`);const v=typeof i=="function"?i:i.execute,l=L(t,await v(o,r,s),n),m=Math.round(performance.now()-d),{errorClass:y}=l;delete l.errorClass;const f=l.isError?y??(t===w?"sandbox_error":"tool_error"):void 0,_=t===w&&y==="tool_error",x=O(l),T=x.join("");return g({tool:t,mode:n,serverType:c.Docs,args:o,result:T,errorClass:f,...a}),f?_||u({tool:t,message:x.join(" "),mode:n,serverType:c.Docs,durationMs:m,errorClass:f,...a}):b({tool:t,mode:n,serverType:c.Docs,durationMs:m,outputLength:T.length,...a}),l}catch(i){throw g({tool:t,mode:n,serverType:c.Docs,args:o,errorClass:"server_error",...a}),u({tool:t,message:i instanceof Error?i.message:String(i),mode:n,serverType:c.Docs,durationMs:Math.round(performance.now()-d),stack:i instanceof Error&&i.stack||"",errorClass:"server_error",...a}),i}}function P(e){return"execute"in e&&typeof e.execute=="function"&&"description"in e&&typeof e.description=="string"}async function C(e){const t=(await A())[e];if(!t)return;const{default:o}=await t();return k(o,e)}function k(e,t){return P(e)?e:e[t]}function L(e,t,o){if(N(t))return t;if(typeof t=="string")return{content:[{type:"text",text:t}]};let s;try{s=JSON.stringify(t)}catch(n){throw new Error(`MCP tool "${e}" returned a value that cannot be serialized to JSON: `+(n instanceof Error?n.message:String(n)))}if(s===void 0)throw new Error(`MCP tool "${e}" returned an invalid result.`);const r=o==="code"?JSON.parse(s):void 0;return p(r)?{content:[{type:"text",text:s}],structuredContent:r}:{content:[{type:"text",text:s}]}}const j=new Set(["text","image","audio","resource","resource_link"]);function N(e){if(!p(e))return!1;const{content:t}=e;return Array.isArray(t)&&t.every(o=>p(o)&&j.has(o.type))}async function $(e){h.initialize();const{toolName:t}=e;if(S(t,e.context.metadata))return!1;const o=E(e.context),s=performance.now();try{const r=await C(t);return r?typeof r=="object"&&typeof r.isAvailable=="function"?await r.isAvailable(o):!0:!1}catch(r){throw u({tool:t,message:"Failed to check if MCP tool is available: "+(r instanceof Error?r.message:String(r)),mode:o?.mcpMode??"tools",serverType:c.Docs,durationMs:Math.round(performance.now()-s),stack:r instanceof Error&&r.stack||"",errorClass:"server_error",...M(o)}),r}}async function Y(e){const{toolNames:t,context:o}=e,s=await Promise.all(t.map(r=>$({toolName:r,context:o}).catch(()=>!1)));return Object.fromEntries(t.map((r,n)=>[r,s[n]]))}export{X as executeMcpTool,$ as isMcpToolAvailable,Y as mcpToolAvailability,k as resolveToolHandler};
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type { McpErrorClass, McpMode, McpServerType } from '../types.js';
|
|
2
|
-
type McpToolEvent = {
|
|
1
|
+
import type { McpCallAttribution, McpErrorClass, McpMode, McpServerType } from '../types.js';
|
|
2
|
+
type McpToolEvent = McpCallAttribution & {
|
|
3
3
|
tool: string;
|
|
4
4
|
mode: McpMode;
|
|
5
5
|
serverType: McpServerType;
|
|
6
6
|
durationMs: number;
|
|
7
|
-
client?: string;
|
|
8
|
-
clientVersion?: string;
|
|
9
7
|
};
|
|
10
|
-
export declare function reportMcpToolCalled({ tool, mode, serverType, durationMs, outputLength, client, clientVersion, }: McpToolEvent & {
|
|
8
|
+
export declare function reportMcpToolCalled({ tool, mode, serverType, durationMs, outputLength, client, clientVersion, requestId, messageId, }: McpToolEvent & {
|
|
11
9
|
outputLength: number;
|
|
12
10
|
}): void;
|
|
13
11
|
/**
|
|
@@ -16,12 +14,12 @@ export declare function reportMcpToolCalled({ tool, mode, serverType, durationMs
|
|
|
16
14
|
* identifies the invocation. The result body itself is never recorded — a tool can return
|
|
17
15
|
* credentials no pattern will recognise — so only its digest lands here.
|
|
18
16
|
*/
|
|
19
|
-
export declare function logMcpToolCallAudit({ tool, mode, serverType, args, result, errorClass, client, clientVersion, }: Omit<McpToolEvent, 'durationMs'> & {
|
|
17
|
+
export declare function logMcpToolCallAudit({ tool, mode, serverType, args, result, errorClass, client, clientVersion, requestId, messageId, }: Omit<McpToolEvent, 'durationMs'> & {
|
|
20
18
|
args: unknown;
|
|
21
19
|
result?: string;
|
|
22
20
|
errorClass?: McpErrorClass;
|
|
23
21
|
}): void;
|
|
24
|
-
export declare function reportMcpToolError({ tool, mode, serverType, durationMs, message, stack, errorClass, client, clientVersion, }: McpToolEvent & {
|
|
22
|
+
export declare function reportMcpToolError({ tool, mode, serverType, durationMs, message, stack, errorClass, client, clientVersion, requestId, messageId, }: McpToolEvent & {
|
|
25
23
|
message: string;
|
|
26
24
|
stack?: string;
|
|
27
25
|
errorClass: McpErrorClass;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetry as
|
|
1
|
+
import{telemetry as p}from"../../../telemetry/index.js";import{serverAttributes as _}from"../utils/telemetry-attributes.js";import{EXECUTE_TOOL_NAME as g}from"../codemode/constants.js";import{auditInput as m,auditOutputDigest as f,auditSha256 as M,logAuditRecord as h}from"../audit/audit-log.js";function b({tool:e,mode:t,serverType:s,durationMs:o,outputLength:r,client:i,clientVersion:n,requestId:a,messageId:l}){p.sendMcpToolCalledMessage([{..._(s),tool:e,mode:t,output_length:r,duration_ms:o,client:i,client_version:n,message_id:l}],{requestId:a})}function v({tool:e,mode:t,serverType:s,args:o,result:r,errorClass:i,client:n,clientVersion:a,requestId:l,messageId:d}){if(e===g)return;const u=y(o),c=r===void 0?void 0:f(r);h("Record MCP tool call",{tool:e,mode:t,server_type:s,error_class:i,client:n,client_version:a,request_id:l,message_id:d,args_sha256:M(u),args:m(u),result_sha256:c?.sha256,result_bytes:c?.bytes})}function y(e){try{return JSON.stringify(e)??String(e)}catch{return"\xAB[unserializable]\xBB"}}function O({tool:e,mode:t,serverType:s,durationMs:o,message:r,stack:i="",errorClass:n,client:a,clientVersion:l,requestId:d,messageId:u}){p.sendMcpErrorMessage([{..._(s),tool:e,message:r,stack:i,error_class:n,mode:t,duration_ms:o,client:a,client_version:l,message_id:u}],{requestId:d})}export{v as logMcpToolCallAudit,b as reportMcpToolCalled,O as reportMcpToolError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as v from"path";import{REDOCLY_ROUTE_RBAC as b,REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{VERSION_SEPARATOR as M}from"../constants/common.js";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../constants/common.js";import{removeTrailingSlash as j}from"../../utils/url/remove-trailing-slash.js";import{isPrimitive as W}from"../../utils/guards/is-primitive.js";import{slash as w}from"../../utils/path/slash.js";import{isAbsoluteUrl as z}from"../../utils/url/is-absolute-url.js";import{normalizeRouteSlug as U}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as R}from"../../utils/path/parse-path-versions.js";import{logger as A}from"../tools/notifiers/logger.js";import{reporter as S}from"../tools/notifiers/reporter.js";import{shaDirPathShort as C}from"../utils/crypto/sha-dir-path-short.js";import{copyStaticFile as H,FileNotFoundError as E}from"../utils/fs.js";import{isIconPath as J,resolveAssetPath as Y}from"../utils/index.js";import{resolveSrcSet as G}from"../utils/resolve-src-set.js";import{isL10nPath as B}from"../fs/utils/is-l10n-path.js";import{getLocaleFromRelativePath as q}from"../fs/utils/get-locale-from-relative-path.js";async function D(e,s,n,t,a){if(!e)return;const f={...a,ignoreCustomSidebar:!0};if(W(e)){if(typeof e=="string"){const r=F(n.contentDir,s,a,e,t.fs);if(t.fs.exists(r)){if(n.getRouteByFsPath(r))return K({page:e},s,n,t,f);{const g=t.fs.getFileInfo(r);return g?H(n.contentDir,g.realRelativePath,n.outdir):void 0}}}return e}return Array.isArray(e)?I(N(e),s,n,t,f):Object.fromEntries(await Promise.all(Object.entries(e).map(async([r,l])=>[r,await D(l,s,n,t,a)])))}function N(e){return e.map(s=>({...s,items:s.items?N(s.items):void 0}))}async function I(e,s,n,t,a){if(Array.isArray(e))return(await Promise.all(e.map(f=>K(f,s,n,t,a)))).flatMap(f=>f)}async function P(e,s,n,t){let a,f;if(typeof e.icon=="object"){if("srcSet"in e.icon)try{a=await G(e.icon.srcSet,n.fs,{fromFileRelativePath:t.navFile,contentDir:s.contentDir,outdir:s.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`):await S.panicOnBuild(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`)}}else if(typeof e.icon=="string")if(z(e.icon)||J(e.icon))try{f=await Y(e.icon,n.fs,{fromFileRelativePath:t.navFile,contentDir:s.contentDir,outdir:s.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon" from ${t.navFile}: file ${f} does not exist`):await S.panicOnBuild(`Cannot resolve "item.icon" from ${t.navFile}: ${d.message}`)}else f=e.icon;return{icon:f,srcSet:a}}function Q(e){return s=>{if(s.type==="link"||s.type==="group"){const n=s.metadata;return n?Object.entries(e).every(([t,a])=>Array.isArray(a)?a.some(f=>n[t]===f):n[t]===a):!1}return!0}}async function K(e,s,n,t,a){if(e?.directory&&e.items?.length)return{type:"error",label:`Can't have both "directory" and "items" in the nav item: ${JSON.stringify(e)}`};e?.directory&&e?.group&&(e={...e,directory:void 0,items:[{directory:e.directory}]});const f=e?.directory?F(n.contentDir,s,a,e.directory,t.fs):void 0;if(f!==void 0){const i=f===""?"":f+"/",{locale:u,ignoredRoutes:o}=a;let h=n.getAllRoutesForLocale(u).filter(c=>!o?.has(c.baseSlug||"")&&c.fsPath.startsWith(i)&&!c.excludeFromSidebar).sort((c,y)=>c.fsPath===y.fsPath?0:c.baseSlug.localeCompare(y.baseSlug,void 0,{numeric:!0}));const m=e.includeByMetadata?Q(e.includeByMetadata):Boolean;if(!h.length)return[];const $=(await Promise.all(h.map(async c=>{const y=c.versions?.find(x=>x.active),L=y&&{version:y.version,isDefault:y.default,versionFolderId:y.folderId},V=ee(v.posix.relative(f,c.fsPath)),O=c.getSidebar?.(c);return!a.ignoreCustomSidebar&&O?.length?{type:"group",fsPath:c.fsPath,metadata:c.metadata,link:c.slug,routeSlug:c.slug,label:await c.getNavText?.()||c.slug,[p]:c[p],[b]:c[b],sidebarItems:k(O,L,c[p],c[b]),...L,relativePathFromDirectory:v.relative(f,c.fsPath).replace(/@[^/]+\//,"")}:{type:"link",fsPath:c.fsPath,metadata:c.metadata,[p]:c[p],[b]:c[b],label:await c.getNavText?.()||c.slug,link:c.slug,routeSlug:c.slug,...L,relativePathFromDirectory:V}}))).filter(m);return e.flatten?T($,a):Z($,a)}let d=typeof e=="string"?e:e?.page,r,l;if(d){if(d.includes("#")){const[i,u]=d.split("#");u?l=u:A.warn(`Invalid heading anchor format in sidebar: "${u}". Heading anchors should contain only alphanumeric characters, hyphens, and underscores.`),d=i}if(d=j(d),a.locale&&a.locale!==_){const i=U(v.join(a.locale.toLowerCase(),d));r=n.getRouteBySlug(i)}r||(r=n.getRouteBySlug(d)),r||(r=n.getRouteByFsPath(F(n.contentDir,s,a,d,t.fs)))}const g=r?.metadata;if(e?.$ref){let i=F(n.contentDir,s,a,e.$ref,t.fs);if(a.ref!==void 0&&(i=v.posix.join(a.ref,e.$ref)),!t.fs.exists(i))return await S.panicOnBuildContentError(`Failed to load ${i} file. Make sure sidebar $ref path is correct.`),[];const u=await t.cache.load(i,"yaml"),o=v.dirname(i);return await I(u.data,s,n,t,{...a,navFile:i,ref:o})||[]}if(!r){const i=a.excludedFromLinkCheckerPatterns?.catalog.some(o=>o.test(d||"")),u=a.excludedFromLinkCheckerPatterns?.apiFunctions.some(o=>o.test(d||e.href||""));(u||i)&&(e={...e,href:d||e.href,page:void 0,target:e.target??(u?"_blank":void 0)}),await X(e,a,t,s)}if(r&&!e.disconnect&&!a.ignoreCustomSidebar&&(l||r?.getSidebar)){const i=r.versions?.find(o=>o.active),u=i&&{version:i.version,isDefault:i.default,versionFolderId:i.folderId};if(l){let o=[];if(r.getSidebar&&(o=r.getSidebar(r,{...e,...await P(e,n,t,a)}),o&&o.length>0)){const h=o[0];h&&h.link&&(h.link=`${h.link}#${l}`)}if(!o||o.length===0){let h=e.group||e.label||l;o=[{type:"link",fsPath:r.fsPath,metadata:r.metadata,link:`${r.slug}#${l}`,routeSlug:r.slug,label:h,labelTranslationKey:e.labelTranslationKey,...await P(e,n,t,a),[p]:r[p],[b]:{slug:r.slug,fsPath:r.fsPath},...u}]}return k(o,u,r[p],r[b])}if(r?.getSidebar){const o=r.getSidebar(r,{...e,...await P(e,n,t,a)}),h=e.group&&o?.[0]?.routeSlug===r.slug?o.slice(1):o;return k(a.groupCustomSidebars||e.group?[{type:"group",fsPath:r.fsPath,link:r.slug,routeSlug:r.slug,label:e.group||e.label||await r.getNavText?.()||r.slug,items:h,labelTranslationKey:e.labelTranslationKey,metadata:g,badges:e.badges,...await P(e,n,t,a)}]:o,u,r[p],r[b])}}if(r&&!e.group){const i=l?`${r.slug}#${l}`:r.slug;let u=e.label||l||"";u||(u=await r.getNavText?.()||r.slug);const o=r.versions?.find(m=>m.active),h=o&&{version:o.version,isDefault:o.default,versionFolderId:o.folderId};return{type:"link",fsPath:r.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,[p]:e?.rbac||r[p],[b]:{slug:r.slug,fsPath:r.fsPath},label:u,labelTranslationKey:e.labelTranslationKey,link:i,items:await I(e.items,s,n,t,a),separatorLine:e.separatorLine,linePosition:e.linePosition,routeSlug:e.disconnect?void 0:i,external:e.external,target:e.target,badges:e.badges,...await P(e,n,t,a),...h,additionalProps:e.additionalProps}}else if(e?.group){const i=r?.versions?.find(o=>o.active),u=R(a?.navFile);return{type:"group",fsPath:r?.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,version:i?.version||u?.versionName,versionFolderId:i?.folderId||(u?.versionFolderPath?C(u.versionFolderPath):void 0),label:e.group,link:r?.slug,routeSlug:r?.slug,badges:e.badges,labelTranslationKey:e.groupTranslationKey,items:await I(e.items,s,n,t,a),expanded:e.expanded?e.expanded.toString():void 0,selectFirstItemOnExpand:e.selectFirstItemOnExpand,menuStyle:e.menuStyle,separatorLine:e.separatorLine,linePosition:e.linePosition,...await P(e,n,t,a),[p]:e?.rbac,[b]:{slug:r?.slug||"",fsPath:r?.fsPath||""},additionalProps:e.additionalProps}}else{if(e?.href||e?.label)return{type:"link",metadata:g,link:e.href||"",label:e?.label||e?.href||"",labelTranslationKey:e.labelTranslationKey,external:e.external,target:e.target,separatorLine:e.separatorLine,linePosition:e.linePosition,badges:e.badges,...await P(e,n,t,a),[p]:e?.rbac,additionalProps:e.additionalProps};if(e?.separator!=null||e?.separatorLine!=null){const i=R(a?.navFile);return{type:"separator",metadata:g,version:i?.versionName,versionFolderId:i?.versionFolderPath?C(i.versionFolderPath):void 0,label:e.separator,labelTranslationKey:e.separatorTranslationKey,separatorLine:e.separatorLine,linePosition:e.linePosition,...await P(e,n,t,a),[p]:e?.rbac,additionalProps:e.additionalProps}}else{const i=R(a?.navFile);return{type:"error",label:`Can't resolve page: ${JSON.stringify(e)}`,version:i?.versionName,versionFolderId:i?.versionFolderPath?C(i.versionFolderPath):void 0}}}}async function X(e,s,n,t){const{href:a,page:f}=e;if(a||!f)return;const d=F(n.fs.cwd,t,s,f,n.fs),r=n.fs.exists(d),l=await n.isPathIgnored(d),g=(r?"The page is ignored: ":"Can't resolve page: ")+f;(!r||l)&&S.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",title:e.label||e.group||"",link:d,rawLink:f,message:g,sourceFileRelativePath:s.navFile,sourceFileLocation:{line:0}})}function F(e,s,n,t="",a){if(n.ref!==void 0)return w(v.relative(e,v.resolve(e,v.join(n.ref,t))));if(t.startsWith("/")){const f=B(s)?q(s):void 0,d=f?`${a.localizationFolder}/${f}/`:"",r=t.slice(1);return B(r)?r:d+w(r)}return w(v.relative(e,v.resolve(e,s,t)))}function Z(e,s){const n={};for(const r of e){const l=v.dirname(r.relativePathFromDirectory),g=r.version?M+r.version:"",i=v.basename(r.relativePathFromDirectory)+g;d(l,r,i)}const t=f(a(n));return T(t,s);function a(r){const l=[];for(const g of Object.keys(r)){const i=r[g];l.push({...i,items:i.items?a(i.items):void 0})}return l}function f(r){return r.sort((l,g)=>{const i=typeof l=="string"?l.toLowerCase():l.relativePathFromDirectory||l.label||"",u=typeof g=="string"?g.toLowerCase():g.relativePathFromDirectory||g.label||"";return i.startsWith("index.")?-1:u.startsWith("index.")?1:i.localeCompare(u,void 0,{numeric:!0})})}function d(r,l,g){r==="."&&(r="");const i=r.split("/").filter(Boolean);let u=n;for(const o of i){const h=o+(l?.version||"");u[h]||(u[h]={type:"group",version:l?.version,label:o,isDefault:l?.isDefault,versionFolderId:l.versionFolderId,items:{}}),u=u[h].items}u[g]=l}}function T(e,s){return e.flatMap(n=>n?.sidebarItems?s.groupCustomSidebars?{...n,items:n.sidebarItems,sidebarItems:void 0,relativePathFromDirectory:void 0}:n.sidebarItems:{...n,items:n.items?T(n.items,s):void 0})}function k(e,s,n,t){return e.map(a=>({...a,...s,[p]:a[p]||n,[b]:a[b]||t,items:a.type==="group"&&a.items?k(a.items,s,n):a.items}))}function ee(e){return e.replace(/@[^/]+\//,"")}async function Pe(e,s,n,t){const a=(e?.items||[]).filter(r=>r.linkedSidebars?.length).map(r=>({...r,items:void 0})),f=await D(a,s.contentDir,s,n,t),d=new Map;for(const r of f)if(r.linkedSidebars?.length)for(const l of r.linkedSidebars){if(d.has(l)){A.warn(`Only one navbar item can belong to sidebar. "${l}" on 'linkedSidebars' property on "${r.label}" will be ignored.`);continue}d.set(l,{label:r.label,link:r.link})}return d}export{Pe as collectItemsLinkedToSidebars,N as normalizeItems,K as resolveItem,I as resolveItems,D as resolveLinksFromConfig};
|
|
1
|
+
import*as v from"path";import{REDOCLY_ROUTE_RBAC as b,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import{VERSION_SEPARATOR as M}from"../constants/common.js";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../constants/common.js";import{removeTrailingSlash as j}from"../../utils/url/remove-trailing-slash.js";import{isPrimitive as W}from"../../utils/guards/is-primitive.js";import{slash as w}from"../../utils/path/slash.js";import{isAbsoluteUrl as z}from"../../utils/url/is-absolute-url.js";import{normalizeRouteSlug as J}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as C}from"../../utils/path/parse-path-versions.js";import{logger as A}from"../tools/notifiers/logger.js";import{reporter as S}from"../tools/notifiers/reporter.js";import{shaDirPathShort as R}from"../utils/crypto/sha-dir-path-short.js";import{copyStaticFile as U,FileNotFoundError as E}from"../utils/fs.js";import{isIconPath as H,resolveAssetPath as Y}from"../utils/index.js";import{resolveSrcSet as G}from"../utils/resolve-src-set.js";import{isL10nPath as B}from"../fs/utils/is-l10n-path.js";import{getLocaleFromRelativePath as q}from"../fs/utils/get-locale-from-relative-path.js";async function N(e,i,n,t,a){if(!e)return;const f={...a,ignoreCustomSidebar:!0};if(W(e)){if(typeof e=="string"){const r=F(n.contentDir,i,a,e,t.fs);if(t.fs.exists(r)){if(n.getRouteByFsPath(r))return K({page:e},i,n,t,f);{const g=t.fs.getFileInfo(r);return g?U(n.contentDir,g.realRelativePath,n.outdir):void 0}}}return e}return Array.isArray(e)?I(D(e),i,n,t,f):Object.fromEntries(await Promise.all(Object.entries(e).map(async([r,l])=>[r,await N(l,i,n,t,a)])))}function D(e){return e.map(i=>({...i,items:i.items?D(i.items):void 0}))}async function I(e,i,n,t,a){if(Array.isArray(e))return(await Promise.all(e.map(f=>K(f,i,n,t,a)))).flatMap(f=>f)}async function y(e,i,n,t){let a,f;if(typeof e.icon=="object"){if("srcSet"in e.icon)try{a=await G(e.icon.srcSet,n.fs,{fromFileRelativePath:t.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`):await S.panicOnBuild(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`)}}else if(typeof e.icon=="string")if(z(e.icon)||H(e.icon))try{f=await Y(e.icon,n.fs,{fromFileRelativePath:t.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon" from ${t.navFile}: file ${f} does not exist`):await S.panicOnBuild(`Cannot resolve "item.icon" from ${t.navFile}: ${d.message}`)}else f=e.icon;return{icon:f,srcSet:a}}function Q(e){return i=>{if(i.type==="link"||i.type==="group"){const n=i.metadata;return n?Object.entries(e).every(([t,a])=>Array.isArray(a)?a.some(f=>n[t]===f):n[t]===a):!1}return!0}}async function K(e,i,n,t,a){if(e?.tab!==void 0||e?.menu!==void 0){const s=`Navigation tabs ("tab"/"menu") are only allowed at the top level of a sidebars.yaml file: ${JSON.stringify(e)}`;return await S.panicOnBuildContentError(`Invalid nav item in %rp. ${s}`,a.navFile),{type:"error",label:s}}if(e?.directory&&e.items?.length)return{type:"error",label:`Can't have both "directory" and "items" in the nav item: ${JSON.stringify(e)}`};e?.directory&&e?.group&&(e={...e,directory:void 0,items:[{directory:e.directory}]});const f=e?.directory?F(n.contentDir,i,a,e.directory,t.fs):void 0;if(f!==void 0){const s=f===""?"":f+"/",{locale:u,ignoredRoutes:o}=a;let p=n.getAllRoutesForLocale(u).filter(c=>!o?.has(c.baseSlug||"")&&c.fsPath.startsWith(s)&&!c.excludeFromSidebar).sort((c,P)=>c.fsPath===P.fsPath?0:c.baseSlug.localeCompare(P.baseSlug,void 0,{numeric:!0}));const m=e.includeByMetadata?Q(e.includeByMetadata):Boolean;if(!p.length)return[];const T=(await Promise.all(p.map(async c=>{const P=c.versions?.find(x=>x.active),L=P&&{version:P.version,isDefault:P.default,versionFolderId:P.folderId},V=ee(v.posix.relative(f,c.fsPath)),O=c.getSidebar?.(c);return!a.ignoreCustomSidebar&&O?.length?{type:"group",fsPath:c.fsPath,metadata:c.metadata,link:c.slug,routeSlug:c.slug,label:await c.getNavText?.()||c.slug,[h]:c[h],[b]:c[b],sidebarItems:k(O,L,c[h],c[b]),...L,relativePathFromDirectory:v.relative(f,c.fsPath).replace(/@(?<!@[^/]*?@)[^/]+\//,"")}:{type:"link",fsPath:c.fsPath,metadata:c.metadata,[h]:c[h],[b]:c[b],label:await c.getNavText?.()||c.slug,link:c.slug,routeSlug:c.slug,...L,relativePathFromDirectory:V}}))).filter(m);return e.flatten?$(T,a):Z(T,a)}let d=typeof e=="string"?e:e?.page,r,l;if(d){if(d.includes("#")){const[s,u]=d.split("#");u?l=u:A.warn(`Invalid heading anchor format in sidebar: "${u}". Heading anchors should contain only alphanumeric characters, hyphens, and underscores.`),d=s}if(d=j(d),a.locale&&a.locale!==_){const s=J(v.join(a.locale.toLowerCase(),d));r=n.getRouteBySlug(s)}r||(r=n.getRouteBySlug(d)),r||(r=n.getRouteByFsPath(F(n.contentDir,i,a,d,t.fs)))}const g=r?.metadata;if(e?.$ref){let s=F(n.contentDir,i,a,e.$ref,t.fs);if(a.ref!==void 0&&(s=v.posix.join(a.ref,e.$ref)),!t.fs.exists(s))return await S.panicOnBuildContentError(`Failed to load ${s} file. Make sure sidebar $ref path is correct.`),[];const u=await t.cache.load(s,"yaml"),o=v.dirname(s);return await I(u.data,i,n,t,{...a,navFile:s,ref:o})||[]}if(!r){const s=a.excludedFromLinkCheckerPatterns?.catalog.some(o=>o.test(d||"")),u=a.excludedFromLinkCheckerPatterns?.apiFunctions.some(o=>o.test(d||e.href||""));(u||s)&&(e={...e,href:d||e.href,page:void 0,target:e.target??(u?"_blank":void 0)}),await X(e,a,t,i)}if(r&&!e.disconnect&&!a.ignoreCustomSidebar&&(l||r?.getSidebar)){const s=r.versions?.find(o=>o.active),u=s&&{version:s.version,isDefault:s.default,versionFolderId:s.folderId};if(l){let o=[];if(r.getSidebar&&(o=r.getSidebar(r,{...e,...await y(e,n,t,a)}),o&&o.length>0)){const p=o[0];p&&p.link&&(p.link=`${p.link}#${l}`)}if(!o||o.length===0){let p=e.group||e.label||l;o=[{type:"link",fsPath:r.fsPath,metadata:r.metadata,link:`${r.slug}#${l}`,routeSlug:r.slug,label:p,labelTranslationKey:e.labelTranslationKey,...await y(e,n,t,a),[h]:r[h],[b]:{slug:r.slug,fsPath:r.fsPath},...u}]}return k(o,u,r[h],r[b])}if(r?.getSidebar){const o=r.getSidebar(r,{...e,...await y(e,n,t,a)}),p=e.group&&o?.[0]?.routeSlug===r.slug?o.slice(1):o;return k(a.groupCustomSidebars||e.group?[{type:"group",fsPath:r.fsPath,link:r.slug,routeSlug:r.slug,label:e.group||e.label||await r.getNavText?.()||r.slug,items:p,labelTranslationKey:e.labelTranslationKey,metadata:g,badges:e.badges,...await y(e,n,t,a)}]:o,u,r[h],r[b])}}if(r&&!e.group){const s=l?`${r.slug}#${l}`:r.slug;let u=e.label||l||"";u||(u=await r.getNavText?.()||r.slug);const o=r.versions?.find(m=>m.active),p=o&&{version:o.version,isDefault:o.default,versionFolderId:o.folderId};return{type:"link",fsPath:r.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,[h]:e?.rbac||r[h],[b]:{slug:r.slug,fsPath:r.fsPath},label:u,labelTranslationKey:e.labelTranslationKey,link:s,items:await I(e.items,i,n,t,a),separatorLine:e.separatorLine,linePosition:e.linePosition,routeSlug:e.disconnect?void 0:s,external:e.external,target:e.target,badges:e.badges,...await y(e,n,t,a),...p,additionalProps:e.additionalProps}}else if(e?.group){const s=r?.versions?.find(o=>o.active),u=C(a?.navFile);return{type:"group",fsPath:r?.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,version:s?.version||u?.versionName,versionFolderId:s?.folderId||(u?.versionFolderPath?R(u.versionFolderPath):void 0),label:e.group,link:r?.slug,routeSlug:r?.slug,badges:e.badges,labelTranslationKey:e.groupTranslationKey,items:await I(e.items,i,n,t,a),expanded:e.expanded?e.expanded.toString():void 0,selectFirstItemOnExpand:e.selectFirstItemOnExpand,menuStyle:e.menuStyle,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,t,a),[h]:e?.rbac,[b]:{slug:r?.slug||"",fsPath:r?.fsPath||""},additionalProps:e.additionalProps}}else{if(e?.href||e?.label)return{type:"link",metadata:g,link:e.href||"",label:e?.label||e?.href||"",labelTranslationKey:e.labelTranslationKey,external:e.external,target:e.target,separatorLine:e.separatorLine,linePosition:e.linePosition,badges:e.badges,...await y(e,n,t,a),[h]:e?.rbac,additionalProps:e.additionalProps};if(e?.separator!=null||e?.separatorLine!=null){const s=C(a?.navFile);return{type:"separator",metadata:g,version:s?.versionName,versionFolderId:s?.versionFolderPath?R(s.versionFolderPath):void 0,label:e.separator,labelTranslationKey:e.separatorTranslationKey,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,t,a),[h]:e?.rbac,additionalProps:e.additionalProps}}else{const s=C(a?.navFile);return{type:"error",label:`Can't resolve page: ${JSON.stringify(e)}`,version:s?.versionName,versionFolderId:s?.versionFolderPath?R(s.versionFolderPath):void 0}}}}async function X(e,i,n,t){const{href:a,page:f}=e;if(a||!f)return;const d=F(n.fs.cwd,t,i,f,n.fs),r=n.fs.exists(d),l=await n.isPathIgnored(d),g=(r?"The page is ignored: ":"Can't resolve page: ")+f;(!r||l)&&S.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",title:e.label||e.group||"",link:d,rawLink:f,message:g,sourceFileRelativePath:i.navFile,sourceFileLocation:{line:0}})}function F(e,i,n,t="",a){if(n.ref!==void 0)return w(v.relative(e,v.resolve(e,v.join(n.ref,t))));if(t.startsWith("/")){const f=B(i)?q(i):void 0,d=f?`${a.localizationFolder}/${f}/`:"",r=t.slice(1);return B(r)?r:d+w(r)}return w(v.relative(e,v.resolve(e,i,t)))}function Z(e,i){const n={};for(const r of e){const l=v.dirname(r.relativePathFromDirectory),g=r.version?M+r.version:"",s=v.basename(r.relativePathFromDirectory)+g;d(l,r,s)}const t=f(a(n));return $(t,i);function a(r){const l=[];for(const g of Object.keys(r)){const s=r[g];l.push({...s,items:s.items?a(s.items):void 0})}return l}function f(r){return r.sort((l,g)=>{const s=typeof l=="string"?l.toLowerCase():l.relativePathFromDirectory||l.label||"",u=typeof g=="string"?g.toLowerCase():g.relativePathFromDirectory||g.label||"";return s.startsWith("index.")?-1:u.startsWith("index.")?1:s.localeCompare(u,void 0,{numeric:!0})})}function d(r,l,g){r==="."&&(r="");const s=r.split("/").filter(Boolean);let u=n;for(const o of s){const p=o+(l?.version||"");u[p]||(u[p]={type:"group",version:l?.version,label:o,isDefault:l?.isDefault,versionFolderId:l.versionFolderId,items:{}}),u=u[p].items}u[g]=l}}function $(e,i){return e.flatMap(n=>n?.sidebarItems?i.groupCustomSidebars?{...n,items:n.sidebarItems,sidebarItems:void 0,relativePathFromDirectory:void 0}:n.sidebarItems:{...n,items:n.items?$(n.items,i):void 0})}function k(e,i,n,t){return e.map(a=>({...a,...i,[h]:a[h]||n,[b]:a[b]||t,items:a.type==="group"&&a.items?k(a.items,i,n):a.items}))}function ee(e){return e.replace(/@(?<!@[^/]*?@)[^/]+\//,"")}async function ye(e,i,n,t){const a=(e?.items||[]).filter(r=>r.linkedSidebars?.length).map(r=>({...r,items:void 0})),f=await N(a,i.contentDir,i,n,t),d=new Map;for(const r of f)if(r.linkedSidebars?.length)for(const l of r.linkedSidebars){if(d.has(l)){A.warn(`Only one navbar item can belong to sidebar. "${l}" on 'linkedSidebars' property on "${r.label}" will be ignored.`);continue}d.set(l,{label:r.label,link:r.link})}return d}export{ye as collectItemsLinkedToSidebars,D as normalizeItems,K as resolveItem,I as resolveItems,N as resolveLinksFromConfig};
|