@redocly/realm 0.130.0-custom.2 → 0.130.0-custom.20
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 +116 -0
- package/dist/bin.js +1 -1
- package/dist/cli/develop.js +1 -1
- package/dist/cli/eject/resolveTheme.d.ts +1 -1
- package/dist/cli/eject/resolveTheme.js +1 -1
- package/dist/cli/prepare/copy-env-files.js +1 -1
- package/dist/cli/prepare/index.js +1 -1
- package/dist/cli/stats/collectors/openapi.js +1 -1
- package/dist/cli/telemetry/index.js +1 -1
- package/dist/client/App.js +1 -1
- package/dist/client/ErrorBoundary.js +1 -1
- package/dist/client/app/DevModeFloatingBar/index.d.ts +3 -0
- package/dist/client/app/DevModeFloatingBar/index.js +43 -0
- package/dist/client/app/Feedback/useSubmitFeedback.js +1 -1
- package/dist/client/app/Sidebar/InstancePicker.d.ts +10 -0
- package/dist/client/app/Sidebar/InstancePicker.js +48 -0
- package/dist/client/app/Sidebar/Sidebar.js +11 -3
- package/dist/client/app/Sidebar/useBreadcrumbs.js +1 -1
- package/dist/client/app/Sidebar/useSidebarItems.js +1 -1
- package/dist/client/app/hooks/catalog/useCatalogClassic.js +1 -1
- package/dist/client/app/hooks/useAutoScroll.js +1 -1
- package/dist/client/app/hooks/useRouteChangeTracker.js +1 -1
- package/dist/client/app/hooks/utils/pathname-matches-active-section.d.ts +6 -0
- package/dist/client/app/hooks/utils/pathname-matches-active-section.js +1 -0
- package/dist/client/app/markdoc/custom-components/html-script.js +1 -0
- package/dist/client/app/markdoc/custom-components/openapi/openapi-code-sample.js +1 -0
- package/dist/client/app/markdoc/custom-components/openapi/openapi-response-sample.js +1 -0
- package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -0
- package/dist/client/app/markdoc/hooks/use-store.js +1 -0
- package/dist/client/browser-entry.js +5 -5
- package/dist/client/constants/common.d.ts +2 -0
- package/dist/client/constants/common.js +1 -0
- package/dist/client/providers/hooks.js +1 -1
- package/dist/client/runtime/loader.js +1 -1
- package/dist/client/runtime/useSocketMessages.js +1 -1
- package/dist/{server/plugins/asyncapi-docs/template → client/templates/asyncapi-docs}/helpers.d.ts +3 -3
- package/dist/client/templates/asyncapi-docs/helpers.js +1 -0
- package/dist/{server/plugins/asyncapi-docs/template/AsyncApiDocs.d.ts → client/templates/asyncapi-docs/template.d.ts} +1 -1
- package/dist/{server/plugins/asyncapi-docs/template/AsyncApiDocs.js → client/templates/asyncapi-docs/template.js} +1 -1
- package/dist/{server/plugins/openapi-docs/template → client/templates/openapi-docs}/helpers.d.ts +14 -1
- package/dist/client/templates/openapi-docs/helpers.js +5 -0
- package/dist/{server/plugins/openapi-docs/template/OpenAPIDocs.d.ts → client/templates/openapi-docs/template.d.ts} +1 -1
- package/dist/{server/plugins/openapi-docs/template/OpenAPIDocs.js → client/templates/openapi-docs/template.js} +1 -1
- package/dist/client/utils/catalog/inject-catalog-items.d.ts +1 -1
- package/dist/client/utils/catalog/inject-catalog-items.js +1 -1
- package/dist/constants/catalog-entities.d.ts +12 -0
- package/dist/constants/catalog-entities.js +1 -0
- package/dist/constants/common.d.ts +2 -2
- 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/plugins/markdown/markdoc → markdoc}/helpers/get-inner-text.d.ts +1 -1
- package/dist/markdoc/helpers/get-inner-text.js +2 -0
- package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/get-variable.d.ts +2 -2
- package/dist/markdoc/helpers/get-variable.js +1 -0
- package/dist/markdoc/nodes/fence/index.js +1 -0
- package/dist/markdoc/nodes/heading.js +1 -0
- package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/index.d.ts +6 -6
- package/dist/markdoc/tags/json-example.d.ts +3 -0
- package/dist/markdoc/tags/json-schema.d.ts +3 -0
- package/dist/markdoc/tags/openapi-code-sample.d.ts +3 -0
- package/dist/markdoc/tags/openapi-example.d.ts +3 -0
- package/dist/markdoc/tags/openapi-response-sample.d.ts +3 -0
- package/dist/markdoc/tags/replay-openapi.d.ts +3 -0
- package/dist/markdoc/types.d.ts +8 -0
- package/dist/markdoc/types.js +0 -0
- package/dist/server/api-routes/import-api-routes-handlers.js +1 -1
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-config.js +1 -0
- package/dist/{config → server/config}/env-schema.d.ts +6 -3
- package/dist/{config → server/config}/env-schemas/database.d.ts +1 -1
- package/dist/server/config/env-schemas/database.js +1 -0
- package/dist/{config → server/config}/env-schemas/organization-project.d.ts +3 -0
- package/dist/{config → server/config}/env-schemas/organization-project.js +1 -1
- package/dist/server/constants/common.d.ts +3 -0
- package/dist/server/constants/common.js +1 -1
- package/dist/server/constants/feedback.d.ts +6 -0
- package/dist/server/constants/feedback.js +1 -0
- package/dist/server/constants/plugins/catalog-entities.d.ts +0 -11
- package/dist/server/constants/plugins/catalog-entities.js +1 -1
- package/dist/server/entitlements/entitlements-provider.js +1 -1
- package/dist/server/esbuild/esbuild-logger.js +1 -1
- package/dist/server/esbuild/esbuild.js +1 -1
- package/dist/server/esbuild/plugins/assets-resolver.js +1 -1
- package/dist/server/esbuild/plugins/esbuild-compile-resolver.js +1 -1
- package/dist/server/esbuild/plugins/styled-components-ssr.js +1 -1
- package/dist/server/esbuild/plugins/themes-resolver.js +2 -2
- package/dist/server/{config/external-plugins.d.ts → external-plugins/resolve-external-plugins.d.ts} +2 -2
- package/dist/server/external-plugins/resolve-external-plugins.js +1 -0
- package/dist/server/fs/cache.js +1 -1
- package/dist/server/fs/fast-mtime.js +3 -3
- package/dist/server/fs/last-modified-tracker.js +1 -1
- package/dist/server/fs/utils/is-loader-cache-enabled.js +1 -1
- package/dist/server/node-bundle-entry.js +1 -1
- package/dist/server/plugins/analytics/adobe/index.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/index.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/asyncapi-docs/index.js +1 -1
- package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.js +27 -27
- package/dist/server/plugins/catalog-classic/get-server-props.js +1 -1
- package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +2 -2
- package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-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/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.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
- package/dist/server/plugins/catalog-entities/plugin.js +1 -1
- package/dist/server/plugins/config-parser/loaders/redocly-config-loader.js +1 -1
- package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
- package/dist/server/plugins/default-theme/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/lifecycle.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/code-walkthrough/filesets-resolver.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-code-snippet-from-file.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-href.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-html-source-attribute.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src-set.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-image-src.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-json-schema-ref.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-native-md-link.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-nav-links.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-parsed-yaml.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-raw-content.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-or-cdn-icon.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-relative-path.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-sample-from-json-schema.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-svg-content.js +1 -1
- package/dist/server/plugins/markdown/markdoc/import-user-tags.js +1 -1
- package/dist/server/plugins/markdown/markdoc/markdoc-options.js +1 -1
- package/dist/server/plugins/markdown/markdoc/partials.js +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/headings.js +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/render-mermaid.js +1 -1
- package/dist/server/plugins/markdown/markdoc/plugins/utils.js +1 -1
- package/dist/server/plugins/markdown/runtime-transform.js +1 -1
- package/dist/server/plugins/markdown/search/get-ai-search-documents.js +1 -1
- package/dist/server/plugins/markdown/search/get-search-documents.js +2 -2
- package/dist/server/plugins/markdown/search/nodes/section-node.js +1 -1
- package/dist/server/plugins/markdown/search/search-resolver.js +1 -1
- package/dist/server/plugins/markdown/search/to-markdown.js +17 -13
- package/dist/server/plugins/markdown/search/walk-sections.js +1 -1
- package/dist/server/plugins/markdown/utils/stringify-tag-children-objects.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.d.ts +5 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
- package/dist/server/plugins/mcp/docs-mcp/tools/search.d.ts +3 -2
- package/dist/server/plugins/mcp/docs-mcp/tools/search.js +6 -1
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +9 -2
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/types.d.ts +20 -1
- package/dist/server/plugins/openapi-docs/decorators.js +1 -1
- package/dist/server/plugins/openapi-docs/get-server-props-custom-fields.js +1 -1
- package/dist/server/plugins/openapi-docs/index.js +1 -1
- package/dist/server/plugins/openapi-docs/instances.d.ts +33 -0
- package/dist/server/plugins/openapi-docs/instances.js +1 -0
- package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +20 -20
- package/dist/server/plugins/openapi-docs/search-indexer.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/scorecard-classic/lint.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/Grid/Grid.d.ts +2 -1
- package/dist/server/plugins/scorecard-classic/template/Grid/Grid.js +3 -3
- package/dist/server/plugins/scorecard-classic/template/Grid/GridHeader.js +15 -9
- package/dist/server/plugins/scorecard-classic/template/Grid/GridRow.js +1 -1
- package/dist/server/plugins/scorecard-classic/template/index.styles.js +5 -6
- package/dist/server/plugins/scorecard-classic/template/views.js +1 -1
- package/dist/server/plugins/scorecards/database/scorecards-config-service.js +1 -1
- package/dist/server/plugins/scorecards/plugin.js +1 -1
- package/dist/server/plugins/scorecards/workers/run-scorecards-worker.js +1 -1
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.d.ts +11 -0
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +1 -0
- package/dist/server/plugins/search/documents/search-documents.js +1 -1
- package/dist/server/plugins/search/engines/flexsearch/index.js +1 -1
- package/dist/server/plugins/search/engines/typesense/index.js +1 -1
- package/dist/server/plugins/search/index.js +1 -1
- package/dist/server/plugins/search/llmstxt/index.js +1 -1
- package/dist/server/plugins/search/utils.d.ts +2 -0
- package/dist/server/plugins/search/utils.js +2 -2
- package/dist/server/plugins/sidebars/index.js +2 -2
- package/dist/server/plugins/sso/index.js +1 -1
- package/dist/server/providers/database/base-repository.js +1 -1
- package/dist/server/providers/database/database-connection-factory.js +1 -1
- package/dist/server/providers/database/database-preconnect-service.js +1 -1
- package/dist/server/providers/database/databases/sqld-sqlite/drizzle.config.js +1 -1
- package/dist/server/ssr/render.js +1 -1
- package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.js +1 -1
- package/dist/server/ssr/utils.js +1 -1
- package/dist/server/store.d.ts +3 -1
- package/dist/server/store.js +1 -1
- package/dist/server/telemetry/index.js +1 -1
- package/dist/server/tools/notifiers/formatter.js +1 -1
- package/dist/server/tools/notifiers/helpers/colors.js +1 -1
- package/dist/server/tools/notifiers/logger.js +1 -1
- package/dist/server/tools/notifiers/reporter.js +1 -1
- package/dist/server/tools/notifiers/terminal-manager.js +1 -1
- package/dist/server/types/plugins/common.d.ts +1 -0
- package/dist/server/types/plugins/markdown.d.ts +0 -7
- package/dist/server/utils/ai-agent-detection.d.ts +16 -0
- package/dist/server/utils/ai-agent-detection.js +1 -0
- package/dist/server/utils/envs/load-env-variables.js +1 -1
- package/dist/server/utils/fs.js +1 -1
- package/dist/server/utils/index.d.ts +2 -2
- package/dist/server/utils/index.js +1 -1
- package/dist/server/utils/is-catalog-entities-enabled.js +1 -1
- package/dist/server/utils/is-scorecards-enabled.js +1 -1
- package/dist/server/utils/report-all-errors.js +1 -1
- package/dist/server/version.js +1 -1
- package/dist/server/web-server/auth.d.ts +2 -0
- package/dist/server/web-server/auth.js +4 -4
- package/dist/server/web-server/handle-api-route-request.js +1 -1
- package/dist/server/web-server/http.js +2 -2
- 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/corsMiddleware.js +1 -1
- package/dist/server/web-server/middleware/dynamic-middleware/dynamic-middleware.js +1 -1
- package/dist/server/web-server/middleware/idleTimeoutMiddleware.js +1 -1
- package/dist/server/web-server/middleware/responseHeadersMiddleware.js +1 -1
- package/dist/server/web-server/mime-types.js +1 -1
- package/dist/server/web-server/routes/auth.js +1 -1
- package/dist/server/web-server/routes/cors-proxy.d.ts +5 -0
- package/dist/server/web-server/routes/cors-proxy.js +2 -0
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/error.js +1 -1
- package/dist/server/web-server/routes/feedback.js +1 -1
- package/dist/server/web-server/routes/helpers/get-md-asset-pathname.d.ts +2 -0
- package/dist/server/web-server/routes/helpers/get-md-asset-pathname.js +1 -0
- package/dist/server/web-server/routes/index.js +1 -1
- package/dist/server/web-server/routes/info.js +1 -1
- package/dist/server/web-server/routes/mcp-oauth.js +1 -1
- package/dist/server/web-server/routes/otel/otel.js +1 -1
- package/dist/server/web-server/routes/page-data.js +1 -1
- package/dist/server/web-server/routes/path-prefix-redirect.js +1 -1
- package/dist/server/web-server/routes/resolve-route.js +1 -1
- package/dist/server/web-server/routes/semantic-search.d.ts +4 -0
- package/dist/server/web-server/routes/semantic-search.js +1 -0
- package/dist/server/workers/worker-pool.js +1 -1
- package/dist/{server/utils → utils}/slugger.d.ts +13 -0
- package/package.json +11 -11
- package/dist/client/app/ErrorBubble/index.d.ts +0 -3
- package/dist/client/app/ErrorBubble/index.js +0 -59
- package/dist/client/app/PageCounter/index.d.ts +0 -3
- package/dist/client/app/PageCounter/index.js +0 -64
- package/dist/config/env-config.js +0 -1
- package/dist/config/env-schemas/database.js +0 -1
- package/dist/server/config/external-plugins.js +0 -1
- package/dist/server/plugins/asyncapi-docs/template/helpers.js +0 -1
- package/dist/server/plugins/markdown/markdoc/custom-components/html-script.js +0 -1
- package/dist/server/plugins/markdown/markdoc/custom-components/openapi/openapi-code-sample.js +0 -1
- package/dist/server/plugins/markdown/markdoc/custom-components/openapi/openapi-response-sample.js +0 -1
- package/dist/server/plugins/markdown/markdoc/custom-components/openapi/replay-openapi.js +0 -1
- package/dist/server/plugins/markdown/markdoc/helpers/get-inner-text.js +0 -2
- package/dist/server/plugins/markdown/markdoc/helpers/get-variable.js +0 -1
- package/dist/server/plugins/markdown/markdoc/hooks/use-store.js +0 -1
- package/dist/server/plugins/markdown/markdoc/nodes/fence/index.js +0 -1
- package/dist/server/plugins/markdown/markdoc/nodes/heading.js +0 -1
- package/dist/server/plugins/markdown/markdoc/tags/json-example.d.ts +0 -3
- package/dist/server/plugins/markdown/markdoc/tags/json-schema.d.ts +0 -3
- package/dist/server/plugins/markdown/markdoc/tags/openapi-code-sample.d.ts +0 -3
- package/dist/server/plugins/markdown/markdoc/tags/openapi-example.d.ts +0 -3
- package/dist/server/plugins/markdown/markdoc/tags/openapi-response-sample.d.ts +0 -3
- package/dist/server/plugins/markdown/markdoc/tags/replay-openapi.d.ts +0 -3
- package/dist/server/plugins/openapi-docs/template/helpers.js +0 -5
- package/dist/server/plugins/search/ai-indexer/prepare-ai-search-documents.d.ts +0 -6
- package/dist/server/plugins/search/ai-indexer/prepare-ai-search-documents.js +0 -1
- /package/dist/client/app/{ErrorBubble → DevModeFloatingBar}/DetailedErrors.d.ts +0 -0
- /package/dist/client/app/{ErrorBubble → DevModeFloatingBar}/DetailedErrors.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/html-script.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/index.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/explain-step.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/explain-step.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation-info-by-id.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation-info-by-id.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation-info-by-pointer.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation-info-by-pointer.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/get-operation.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/index.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/index.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-identifier.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-identifier.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-info.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-info.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-parameters.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/get-operation/types/operation-parameters.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/index.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/json-example.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/json-example.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/json-schema.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/json-schema.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/openapi-code-sample.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/openapi-example.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/openapi-example.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/openapi-response-sample.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/replay-openapi.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/step-by-step-wrapper.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/openapi/step-by-step-wrapper.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/styled.elements.d.ts +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/custom-components/styled.elements.js +0 -0
- /package/dist/{server/plugins/markdown → client/app}/markdoc/hooks/use-store.d.ts +0 -0
- /package/dist/{server/plugins/openapi-docs/template → client/templates/openapi-docs}/mock-server-config.d.ts +0 -0
- /package/dist/{server/plugins/openapi-docs/template → client/templates/openapi-docs}/mock-server-config.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/definition-path.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/definition-path.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/index.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/json-example-ref.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/json-example-ref.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/json-schema-ref.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/json-schema-ref.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/parsed-yaml.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/parsed-yaml.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/raw-content.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/raw-content.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/sample-from-json-schema.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/attributes/sample-from-json-schema.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/extract-rbac-from-condition-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/extract-rbac-from-condition-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/get-node-attribute.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/get-node-attribute.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-code-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-code-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-conditional-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-conditional-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-content-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-content-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-example-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-example-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-fence-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-fence-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-function.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-function.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-list-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-list-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-string-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-string-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-tag.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-tag.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-text-node.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-text-node.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-variable.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/guards/is-variable.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/remove-markdoc-tags.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/remove-markdoc-tags.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/set-node-attribute-value.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/helpers/set-node-attribute-value.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/fence/escape-html.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/fence/escape-html.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/fence/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/gfm-list-item.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/gfm-list-item.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/heading.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/index.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/index.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/table.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/table.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/text.d.ts +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/nodes/text.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/index.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/json-example.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/json-schema.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/openapi-code-sample.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/openapi-example.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/openapi-response-sample.js +0 -0
- /package/dist/{server/plugins/markdown/markdoc → markdoc}/tags/replay-openapi.js +0 -0
- /package/dist/{config → server/config}/env-config.d.ts +0 -0
- /package/dist/{config → server/config}/env-schema.js +0 -0
- /package/dist/{config → server/config}/env-schemas/api-urls.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/api-urls.js +0 -0
- /package/dist/{config → server/config}/env-schemas/auth.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/auth.js +0 -0
- /package/dist/{config → server/config}/env-schemas/catalog.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/catalog.js +0 -0
- /package/dist/{config → server/config}/env-schemas/environment-detection.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/environment-detection.js +0 -0
- /package/dist/{config → server/config}/env-schemas/feature-flags.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/feature-flags.js +0 -0
- /package/dist/{config → server/config}/env-schemas/scorecards.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/scorecards.js +0 -0
- /package/dist/{config → server/config}/env-schemas/search.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/search.js +0 -0
- /package/dist/{config → server/config}/env-schemas/server-config.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/server-config.js +0 -0
- /package/dist/{config → server/config}/env-schemas/site.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/site.js +0 -0
- /package/dist/{config → server/config}/env-schemas/ssr.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/ssr.js +0 -0
- /package/dist/{config → server/config}/env-schemas/telemetry.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/telemetry.js +0 -0
- /package/dist/{config → server/config}/env-schemas/test.d.ts +0 -0
- /package/dist/{config → server/config}/env-schemas/test.js +0 -0
- /package/dist/server/{config → external-plugins}/resolve-module.d.ts +0 -0
- /package/dist/server/{config → external-plugins}/resolve-module.js +0 -0
- /package/dist/{server/utils → utils}/conflict-resolvers.d.ts +0 -0
- /package/dist/{server/utils → utils}/conflict-resolvers.js +0 -0
- /package/dist/{server/utils → utils}/slugger.js +0 -0
package/dist/server/store.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export declare class Store {
|
|
|
57
57
|
templates: Map<string, string>;
|
|
58
58
|
browserPlugins: Set<string>;
|
|
59
59
|
apiRoutesRequestHandlers: Map<string, string>;
|
|
60
|
+
mcpToolRequestHandlerIds: Map<string, true>;
|
|
60
61
|
serverPropsGetters: Map<string, string>;
|
|
61
62
|
pagePropsGetters: Map<string, string>;
|
|
62
63
|
listeners: Map<string, Set<(...args: any[]) => void>>;
|
|
@@ -108,12 +109,12 @@ export declare class Store {
|
|
|
108
109
|
} | undefined;
|
|
109
110
|
} | undefined;
|
|
110
111
|
variables?: Record<string, any> | undefined;
|
|
112
|
+
tags?: any;
|
|
111
113
|
validation?: {
|
|
112
114
|
parents?: Node[];
|
|
113
115
|
validateFunctions?: boolean;
|
|
114
116
|
environment?: string;
|
|
115
117
|
};
|
|
116
|
-
tags?: any;
|
|
117
118
|
nodes?: any;
|
|
118
119
|
functions?: Record<string, import("@markdoc/markdoc").ConfigFunction> | undefined;
|
|
119
120
|
};
|
|
@@ -168,6 +169,7 @@ export declare class Store {
|
|
|
168
169
|
createTemplate: (id: string, importPath: string) => string;
|
|
169
170
|
addBrowserPlugin: (importPath: string) => void;
|
|
170
171
|
createRequestHandler: (id: string, importPath: string) => string;
|
|
172
|
+
addMcpTool: (importPath: string) => string;
|
|
171
173
|
registerServerPropsGetter: (id: string, importPath: string) => string;
|
|
172
174
|
registerPagePropsGetter: (id: string, importPath: string) => void;
|
|
173
175
|
writeRouteStaticData(route: RouteDetails, context: LifecycleContext): Promise<void>;
|
package/dist/server/store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import b from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as C}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as T}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as M}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as L}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as k}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{envConfig as B}from"../config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{writeSharedData as G}from"./utils/index.js";import{renderComponents as I}from"./ssr/render.js";import{readStaticData as N,writeStaticData as V}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as H}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as w}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as U}from"./utils/globs.js";import{replaceEnvVariablesDeep as x}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as J}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as q}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",bt="markdown/partials-deps",v="PLAN_GATES",W=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],At="userDefinedApiFunctions";class E{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;routesByDir=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=w.instance(),e=await H(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await j(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=y(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=x(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!w.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&q(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return J(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??k(r);return this.#t[t]===a||(this.#t[t]=a,await G(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=M(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=A(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!L(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{if(!this.lifecycleContext?.fs?.isL10nEnabled)return Array.from(this.routesBySlug.values());const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!K(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getRoutesByDir=t=>this.routesByDir.get(t)||[];getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&V(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return N(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:C,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):I(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=B.PLAN_GATES,e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=z(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=y(t,r);if(c||!O(o)&&!Array.isArray(o)){await S.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!W.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await S.panicOnBuildContentError(e)}}function z(P){return T(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,bt as MARKDOC_PARTIALS_DEPS_KEY,E as Store,At as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
1
|
+
import A from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as h}from"../constants/common.js";import{DEFAULT_TITLE as T}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as M}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as L}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as k}from"../utils/path/is-local-link.js";import{reporter as R}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as S}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{envConfig as I}from"./config/env-config.js";import{KvService as B}from"./persistence/kv/services/kv-service.js";import{writeSharedData as F}from"./utils/index.js";import{renderComponents as G}from"./ssr/render.js";import{readStaticData as N,writeStaticData as H}from"./utils/static-data.js";import{parseAndResolveMarkdoc as V}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as j}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as w}from"./entitlements/entitlements-provider.js";import{isL10nPath as q}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as K}from"./utils/globs.js";import{replaceEnvVariablesDeep as U}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as J}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const v={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",mcpToolRequestHandlerIds:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",W="markdown/partials-deps",E="PLAN_GATES",z=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],At="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;routesByDir=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolRequestHandlerIds=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=w.instance(),e=await j(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>B.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:n}=await V(t,this.markdocOptions,{actions:this,context:e});for(const i of r.sharedDataDeps||[]){for(const o of s?.routeSlugs||[])this.addRouteSharedData(o,i,i);for(const o of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(o)||new Set;c.add(i),this.sharedDataDeps.set(o,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const o of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(o)||new Set;c.add(i),this.routesDynamicComponents.set(o,c)}for(const o of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(o)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(o,c)}}if(s?.routeSlugs&&r.partials?.length)for(const i of s.routeSlugs){const o=this.routesPartials.get(i)||[];for(const c of r.partials)o.includes(c)||o.push(c);this.routesPartials.set(i,o)}return{info:r,ast:a,compoundHash:n}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const e=Object.keys(t);for(const n of e)for(const i in this.replacedEnvVars)if(i===n||i.startsWith(`${n}:`)){const o=i.split(":"),{error:c,value:l}=y(t,o);(c||l!==this.replacedEnvVars[i].replaced)&&delete this.replacedEnvVars[i]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=U(t);for(const n of r)this.unsetEnvVars.add(n);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!w.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&J(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??S(r);return this.#t[t]===a||(this.#t[t]=a,await F(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=L(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r=this.getGlobalConfig(W)||{},a=new Set(s),n=Array.from(s);for(let o=0;o<n.length;o++){const c=n[o],l=r[c]?.partials??[];for(const d of l)a.has(d)||(a.add(d),n.push(d))}const i={};for(const o of a)e[o]&&(i[o]=e[o]);return i};addRoute=t=>{const s={...K(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[h,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const n=C(t,h,a.code,r);this.addRouteSharedData(n,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!k(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=h)=>{if(!this.lifecycleContext?.fs?.isL10nEnabled)return Array.from(this.routesBySlug.values());const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===h?!q(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getRoutesByDir=t=>this.routesByDir.get(t)||[];getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);addMcpTool=t=>{const e=`mcp-tool:${S(t)}`;return this.mcpToolRequestHandlerIds.has(e)||(this.createRequestHandler(e,t),this.mcpToolRequestHandlerIds.set(e,!0)),e};registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&H(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return N(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},n=new Set(this.routesDynamicComponents.get(t.slug)),i=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(i)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(u=>n.add(u));const m=this.sharedDataDeps.get(l);m&&m.forEach(u=>this.addRouteSharedData(t.slug,u,u))}const o=this.getGlobalConfig("seo"),c=a?.frontmatter||{};return{...a,frontmatter:{...c,seo:{...c?.seo,title:c?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(n),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:T,...o,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):G(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.mcpToolRequestHandlerIds.clear(),this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[s,r]of Object.entries(v))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[E]=I.PLAN_GATES,e}static fromJson(t,e){const s=new P(e);for(const[a,n]of Object.entries(v))switch(n){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=Y(s.config[g]||{});const r=t[E];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:n,value:i}=y(t,r);if(n||!O(i)&&!Array.isArray(i)){await R.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}i[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!z.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await R.panicOnBuildContentError(e)}}function Y(b){return M(b,t=>A.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,W as MARKDOC_PARTIALS_DEPS_KEY,P as Store,At as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AsyncApiRealmAPI as
|
|
1
|
+
import{AsyncApiRealmAPI as o}from"@redocly/realm-asyncapi-sdk";import{envConfig as e}from"../config/env-config.js";import{PACKAGE_NAME as t}from"../../config/product-gates.js";import{OTEL_TRACES_DEV_URL as i,TELEMETRY_ENABLED as s}from"../constants/common.js";class l extends o.Telemetry{constructor(){super(),this.updateCloudEventData(()=>({organizationId:e.ORGANIZATION_ID||"",organizationSlug:e.ORGANIZATION_SLUG||"",projectId:e.PROJECT_ID||"",projectSlug:"",origin:"realmApi",actor:{id:"Anonymous",object:"user",uri:""},source:"server"}))}initialize(r=!1){this.init({otel:{serviceName:"realm-server",serviceVersion:`${t}@${e.REDOCLY_PORTAL_VERSION||""}`,collectorTraceUrl:r?i:e.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",isProd:e.isProductionEnv,version:"1.0",tracerName:"server-telemetry",delayMillis:100},disabled:r?e.TELEMETRY_DEV_DEBUG!=="true":!s})}}const A=new l;export{A as telemetry};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import*as g from"node:path";import{envConfig as R}from"
|
|
1
|
+
import*as g from"node:path";import{envConfig as R}from"../../config/env-config.js";import{maskEmail as T}from"./helpers/privacy/mask-email.js";import{maskSubject as E}from"./helpers/privacy/mask-subject.js";import{removePii as A}from"./helpers/privacy/remove-pii.js";import{removePiiFromUrl as C}from"./helpers/privacy/remove-pii-from-url.js";import{red as $,green as x,bold as j,blue as p,gray as i,yellow as P,cyan as w}from"./helpers/colors.js";var n;(function(e){e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.SUCCESS="SUCCESS",e.VERBOSE="VERBOSE",e.HTTP="HTTP"})(n||(n={}));const b={[n.VERBOSE]:0,[n.HTTP]:1,[n.INFO]:2,[n.SUCCESS]:2,[n.WARN]:3,[n.ERROR]:4};function W(e,s){return b[e]>=b[s]}function L(e){if(!e)return;const s=e.toUpperCase();if(s in n)return s}const F={[n.INFO]:p,[n.SUCCESS]:x,[n.WARN]:P,[n.ERROR]:$,[n.HTTP]:w,[n.VERBOSE]:i},I={"%ap":e=>p(g.resolve(e)),"%rp":e=>p(g.relative(process.cwd(),e)),"%s":e=>e?.toString(),"%c":e=>p(e)},v={format(e){switch(R.PORTAL_LOG_FORMAT){case"JSON":return M(e);default:return H(e)}},interpolate(e,...s){const a=Object.keys(I).map(t=>`(${t})`).join("|"),m=new RegExp(a,"g");let o,u=e;for(;(o=m.exec(e))!==null;){o.index===m.lastIndex&&m.lastIndex++;const t=s.shift();if(t===void 0)break;const r=o[0];u=u.replace(r,I[r](t))}return u}};var z=v;const H=e=>{const{level:s,message:a,duration:m,context:o}=e,u=R.isRuntimeMode,t=[F[s](j(`[${s.toLowerCase()}]`))];if(u&&t.push(i(`time="${N()}"`)),o){const{email:r,ipAddress:f,subject:l,method:d,pathname:c,statusCode:S,teams:h,apiFunction:O}=o;O&&t.push(p(`fn="${O}"`)),S&&t.push(U(S)),e.level===n.HTTP&&(d&&t.push(i(`method="${d}"`)),c&&t.push(i(`path="${C(c)}"`))),f&&t.push(i(`ip="${f}"`)),r&&t.push(i(`email="${T(r)}"`)),l&&t.push(i(`sub="${E(l)}"`)),h?.length&&t.push(i(`teams="${h.join(", ")}"`))}if(a){const r=u?`msg="${String(A(a)).replaceAll?.('"','\\"')}"`:String(a);t.push(r)}return e.level===n.HTTP&&o?.userAgent&&t.push(i(`agent="${o.userAgent}"`)),m&&t.push(y(m)),t.join(" ")+`
|
|
2
2
|
`},M=({context:e,message:s,...a})=>{const{method:m,pathname:o,statusCode:u,userAgent:t,subject:r,email:f,teams:l,apiFunction:d}=e||{},c={...a,email:f&&T(f),subject:r&&E(r),teams:l,apiFunction:d,...a.level===n.HTTP?{method:m,pathname:String(C(o)),statusCode:u,userAgent:t}:{message:String(A(s))}};return R.isRuntimeMode&&(c.time=N()),JSON.stringify(c,["time","level","scope","message","duration","method","pathname","statusCode","userAgent","subject","ipAddress","email","apiFunction"])+`
|
|
3
3
|
`},U=e=>(e%500<100?$:e%400<100?P:x)(`status="${e}"`),N=()=>{let e=new Date().getTimezoneOffset()*6e4;return new Date(Date.now()-e).toISOString().slice(0,-1)},y=e=>i(`dur="${Math.round(e)}ms"`);export{n as LogLevel,z as default,L as parseLogLevel,W as shouldLog};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createColors as e}from"colorette";import{envConfig as l}from"
|
|
1
|
+
import{createColors as e}from"colorette";import{envConfig as l}from"../../../config/env-config.js";const r=l.PORTAL_LOG_FORMAT!=="JSON",{red:s,green:t,bold:c,blue:n,gray:a,yellow:g,cyan:d}=e({useColor:r}),f=o=>typeof o=="string"?o.replace(/\x1B[[(?);]{0,2}(;?\d)*./g,""):o;export{n as blue,c as bold,r as colorsAreEnabled,d as cyan,a as gray,t as green,s as red,f as stripColors,g as yellow};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{telemetry as c}from"../../telemetry/index.js";import{envConfig as l}from"
|
|
1
|
+
import{telemetry as c}from"../../telemetry/index.js";import{envConfig as l}from"../../config/env-config.js";import h,{LogLevel as r,shouldLog as m,parseLogLevel as u}from"./formatter.js";import{isVirtualFile as f}from"../../fs/utils/isVirtualFile.js";import{TerminalManager as g}from"./terminal-manager.js";class p{#e;#l;#i;#n;#r=new Map;#o=new Map;constructor({context:t,forceNonInteractive:e,minLogLevel:i}={}){this.#e=t,this.#l=l.isProductionEnv,this.#i=new g(e),this.#n=i??u(l.REDOCLY_LOG_LEVEL)??(l.isDevelopMode?r.INFO:r.HTTP)}shouldLog(t){return m(t,this.#n)}info(t,...e){this.#t({level:r.INFO,message:t,args:e})}infoTime(t,e,...i){return this.#s(r.INFO,e,t,...i)}success(t,...e){this.#t({level:r.SUCCESS,message:t,args:e})}logInFooter(t,e,...i){const o=h.interpolate(e,...i)+`
|
|
2
2
|
`;this.isInteractive()||this.#i.isFooterChanged(t,o)&&this.#t({level:r.INFO,message:e,args:i}),this.#i.updateFooter(t,o)}successTime(t,e,...i){return this.#s(r.SUCCESS,e,t,...i)}warn(t,...e){this.#t({level:r.WARN,message:t,args:e})}warnProd(t,...e){this.#l?this.warn(t,...e):this.verbose(t,...e)}error(t,...e){this.#t({level:r.ERROR,message:t,args:e})}contentError(t,...e){this.#t({level:r.ERROR,message:t,scope:"content",args:e})}verbose(t,...e){this.#t({level:r.VERBOSE,message:t,args:e})}verboseTime(t,e,...i){return this.#s(r.VERBOSE,e,t,...i)}httpTime(t){return this.#s(r.HTTP,"",t)}startTiming(t){const e=t||Symbol();this.#r.set(e,performance.now());const i=setTimeout(()=>{this.#r.delete(e),this.#o.delete(e)},500*1e3);return this.#o.set(e,i),e}updateContext(t){this.#e={...this.#e,...t}}clearAllTimeouts(){for(const t of this.#o.values())clearTimeout(t);this.#o.clear()}isInteractive(){return this.#i.isInteractive()}warnForRealFile(t,e,i,...o){f(e,i)||this.warn(t,e,...o)}#s(t,e,i,...o){const n=this.#r.get(i);if(!n)return;const s=Math.round(performance.now()-n);return this.#r.delete(i),this.#t({level:t,message:e,duration:s,args:o}),{message:e,timeMs:s}}#t({level:t,message:e,duration:i,scope:o,args:n}){if(!m(t,this.#n))return;let s=e&&h.interpolate(e,...n);s&&i!=null&&t!==r.VERBOSE&&c.sendTimingPerformedMessage([{object:"timing",timeMs:i,message:s}]);const a={level:t,message:s,duration:i,scope:o,context:this.#e};process.stderr.write(h.format(a))}}const R=new p;export{p as Logger,R as logger};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{envConfig as h}from"
|
|
1
|
+
import{envConfig as h}from"../../config/env-config.js";import{logger as e}from"../../tools/notifiers/logger.js";import P from"./formatter.js";import{blue as g,gray as p,red as c}from"./helpers/colors.js";import{isVirtualFile as b}from"../../fs/utils/isVirtualFile.js";import{telemetry as u}from"../../telemetry/index.js";import{shutdowner as f}from"../shutdowner.js";const a=30;class C{#r=[];#o=[];#e=new Map;#t=[];pushError(r,t,...o){const i=P.interpolate(r,...o);this.#r.push({severity:t,message:i,type:"ERROR"})}reportBrokenLink(r){this.#r.push(r)}reportCompilationError(r){const t=`${r.message}::${r.sourceFileRelativePath}::${r?.sourceFileLocation?.line}`;this.#e.has(t)||this.#e.set(t,r)}reportPageRenderError(r){this.#t.push(r)}async panicOnBuild(r,...t){r instanceof Error&&(r=r.message+`
|
|
2
2
|
`+r.stack),h.isBuildMode?await this.panic(r,...t):this.pushError(r,"PANIC",...t)}async panicOnBuildContentErrorForRealFile(r,t,o,...i){b(t,o)||await this.panicOnBuildContentError(r,...i)}async panicOnBuildContentError(r,...t){r instanceof Error&&(r=r.message+`
|
|
3
3
|
`+r.stack),h.isBuildMode?await this.panicOnContentError(r,...t):this.pushError(r,"PANIC",...t)}async panic(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
|
|
4
4
|
`+r.stack):o=new Error(r),e.error(r,...t),u.sendCliErrorCaughtMessage([{object:"cli",message:r}]),await f.exitWithCode(1,o)}async panicOnContentError(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{envConfig as h}from"
|
|
1
|
+
import{envConfig as h}from"../../config/env-config.js";import{gray as p}from"./helpers/colors.js";const t="\x1B[",i=`${t}s`,o=`${t}u`,d=`${t}J`,a=c=>`${t}1;${c}r`,f=`${t}r`,w=`${t}?25h`,R=`${t}?25l`,l=()=>`${p("\u2500".repeat(process.stderr.columns||80))}
|
|
2
2
|
|
|
3
3
|
`,u=3;class I{#r=new Map;#s=process.stderr.rows;#e=0;#t=!1;#i=!1;constructor(r=!1){this.#i=r}isInteractive(){return!!(!this.#i&&process.stderr&&process.stderr.isTTY&&h.TERM!=="dumb"&&!("CI"in process.env)&&h.isDevelopMode)}isFooterChanged(r,s){return this.#r.get(r)!==s}updateFooter(r,s){const e=!this.#r.has(r);this.#r.set(r,s),this.isInteractive()&&(e?this.#n():this.#c())}get#o(){if(this.#r.size===0)return 0;let r=u;for(const s of this.#r.values())r+=(s.match(/\n/g)||[]).length;return r}#c(){if(!this.isInteractive()||this.#r.size===0)return;this.#h();const r=this.#o,s=process.stderr.rows;if(!(r>s)){process.stderr.write(i),process.stderr.cursorTo(0,s-r+1),process.stderr.write(l());for(const e of this.#r.values())process.stderr.write(e);process.stderr.write(o)}}#n(r=0){if(!this.isInteractive())return;const s=process.stderr.rows;let e=this.#o;e>s&&(e=0);const n=e-this.#e;this.#e=e,n>0&&(process.stderr.write(i),process.stderr.write(`
|
|
4
4
|
`.repeat(n)),process.stderr.write(o)),process.stderr.write(i),process.stderr.write(d),r<0&&process.stderr.write(`
|
|
@@ -143,6 +143,7 @@ export type ProcessContentActions = {
|
|
|
143
143
|
addRoute: (route: PageRouteInit) => void;
|
|
144
144
|
addApiRoute: (route: ApiRoute) => void;
|
|
145
145
|
createRequestHandler: (id: string, importPath: string) => void;
|
|
146
|
+
addMcpTool: (importPath: string) => string;
|
|
146
147
|
addRedirect: (from: string, to: RedirectConfig) => void;
|
|
147
148
|
createTemplate: (id: string, importPath: string) => string;
|
|
148
149
|
addBrowserPlugin: (importPath: string) => void;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Schema } from '@markdoc/markdoc';
|
|
2
1
|
import type { PageStaticData, REDOCLY_ROUTE_RBAC, REDOCLY_TEAMS_RBAC, RbacScopeItems } from '@redocly/config';
|
|
3
2
|
import type { PluginDefaultOptions, PageRouteDetails, LifecycleContext, AfterRoutesCreatedActions } from '../../types';
|
|
4
3
|
import type { LINK_ORIGINAL_ATTR_NAME } from '../../constants/common';
|
|
@@ -34,12 +33,6 @@ export type MdPageStaticData = {
|
|
|
34
33
|
fsPath?: string;
|
|
35
34
|
};
|
|
36
35
|
} & PageStaticData;
|
|
37
|
-
export type CustomMarkdocTag = {
|
|
38
|
-
schema: Schema & {
|
|
39
|
-
dynamicComponentLib: string;
|
|
40
|
-
};
|
|
41
|
-
tagName: string;
|
|
42
|
-
};
|
|
43
36
|
export type WithOriginalAttr<T, P = string> = T & {
|
|
44
37
|
[K in `${typeof LINK_ORIGINAL_ATTR_NAME}:${string}`]?: P | null;
|
|
45
38
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type AiAgentRequestHeaders = {
|
|
2
|
+
accept?: string;
|
|
3
|
+
signatureAgent?: string;
|
|
4
|
+
signature?: string;
|
|
5
|
+
signatureInput?: string;
|
|
6
|
+
userAgent?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Returns true if the request appears to be from an AI agent or a client that
|
|
10
|
+
* should receive the markdown representation when llms.txt is enabled.
|
|
11
|
+
* Uses Accept header, HTTP Message Signatures (Signature-Agent), and a
|
|
12
|
+
* known list of AI agent User-Agent substrings defined in code.
|
|
13
|
+
* Agents may send both User-Agent and Signature-Agent; any matching signal is enough.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isAiAgentRequest(headers: AiAgentRequestHeaders): boolean;
|
|
16
|
+
//# sourceMappingURL=ai-agent-detection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const u=new Set(["https://chatgpt.com","https://anthropic.com","https://gemini.google.com","https://perplexity.ai"]),p=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","anthropic-ai","Google-Extended","Gemini-Deep-Research","Google-CloudVertexBot","PerplexityBot","Perplexity-User","Meta-ExternalAgent","Meta-ExternalFetcher","meta-webindexer","CrawlBot","CCBot","Bytespider","DuckAssistBot","Cursor"];function l(t,e,n){return Math.min(n,Math.max(e,t))}function m(t){if(!t?.trim())return[];const e=[],n=t.split(",").map(o=>o.trim());for(const o of n){if(!o)continue;const[r,...s]=o.split(";").map(a=>a.trim().toLowerCase());if(!r.includes("/"))continue;let i=1;for(const a of s)if(a.startsWith("q=")){const c=parseFloat(a.slice(2));i=Number.isFinite(c)?l(c,0,1):1;break}e.push({type:r,q:i})}return e}function f(t){const e=m(t),n=Math.max(0,...e.filter(r=>r.type==="text/html").map(r=>r.q)),o=Math.max(0,...e.filter(r=>r.type==="text/markdown").map(r=>r.q));return o>=n&&o>0}function h(t){if(!t||!t.trim().length)return!1;const e=t.trim().toLowerCase().replace(/\/$/,"");return u.has(e)}function d(t){if(!t)return!1;const e=t.toLowerCase();return p.some(n=>e.includes(n.toLowerCase()))}function g(t){const{accept:e,signatureAgent:n,signature:o,signatureInput:r,userAgent:s}=t;return!!(f(e??"")||h(n)&&(o!==void 0||r!==void 0)||d(s))}export{g as isAiAgentRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as n from"dotenv";import*as a from"path";import{simpleGit as s}from"simple-git";import{envConfig as o}from"
|
|
1
|
+
import*as n from"dotenv";import*as a from"path";import{simpleGit as s}from"simple-git";import{envConfig as o}from"../../config/env-config.js";import{sanitizeBranchName as v}from"../../utils/envs/sanitize-branch-name.js";async function p(e){try{return(await s(e??process.cwd()).revparse(["--abbrev-ref","HEAD"])).trim()}catch{return""}}async function m(e){n.config({path:a.resolve(e??"",".env")});const t=o.PUBLIC_REDOCLY_BRANCH_NAME||await p(e);if(t){const c=v(t);n.config({path:a.resolve(e??"",`.env.branch.${c}`),override:!0})}const i=o.redoclyEnv;let r;switch(i){case"production":r=".env.production";break;case"preview":r=".env.preview";break;case"development":default:r=".env.development";break}n.config({path:a.resolve(e??"",r),override:!0})}m();export{m as loadEnvVariables};
|
package/dist/server/utils/fs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as c,readdirSync as l,lstatSync as f,mkdirSync as u,copyFileSync as p,lstat as x}from"fs";import{join as s,extname as S,basename as F,dirname as h,resolve as E}from"path";import{withPathPrefix as w}from"@redocly/theme/core/utils";import{PUBLIC_ASSETS_FOLDER as a}from"../constants/common.js";import{reporter as P}from"../tools/notifiers/reporter.js";import{logger as D}from"../tools/notifiers/logger.js";import{shaDirPathShort as b}from"../utils/crypto/sha-dir-path-short.js";import{shaFileHex as N}from"../utils/crypto/sha-file-hex.js";import{slug as $}from"
|
|
1
|
+
import{existsSync as c,readdirSync as l,lstatSync as f,mkdirSync as u,copyFileSync as p,lstat as x}from"fs";import{join as s,extname as S,basename as F,dirname as h,resolve as E}from"path";import{withPathPrefix as w}from"@redocly/theme/core/utils";import{PUBLIC_ASSETS_FOLDER as a}from"../constants/common.js";import{reporter as P}from"../tools/notifiers/reporter.js";import{logger as D}from"../tools/notifiers/logger.js";import{shaDirPathShort as b}from"../utils/crypto/sha-dir-path-short.js";import{shaFileHex as N}from"../utils/crypto/sha-file-hex.js";import{slug as $}from"../../utils/slugger.js";function I(r){if(!c(r))return[];const e=[];return o(r),e;function o(t){try{l(t).forEach(n=>{let i=s(t,n);f(i).isDirectory()?o(i):e.push(i)})}catch(n){D.error(`Error reading all file names in ${t}: `+n.message)}}}async function T(r,e,o){const t=E(r,e);if(!c(t))throw new v(`File not found at ${t}`,e);c(s(o,a))||u(s(o,a),{recursive:!0});const n=S(t),i=[$(F(t,n)),N(t),b(h(e))].join(".").concat(n),m=s(o,a,i),y=s(a,i);try{if(p(t,m),!c(m))throw new Error(`Cannot copy file ${e}`);return w(y)}catch(d){await P.panicOnBuild(d.message)}}function g(r,e){let o=[];if(c(r)){if(c(e)||u(e,{recursive:!0}),!f(r).isDirectory())throw new Error(`Source path must be a directory, but ${r} provided`);o=l(r),o.forEach(t=>{const n=s(r,t);if(f(n).isDirectory())g(n,s(e,t));else{const i=s(e,t);p(n,i)}})}}function U(r){return u(h(r),{recursive:!0}),r}async function q(r){return new Promise(e=>{x(r,(o,t)=>{e(o==null&&t.isFile())})})}class v extends Error{filePath;constructor(e,o){super(e),this.name="FileNotFoundError",this.filePath=o}}export{v as FileNotFoundError,g as copyFolderRecursiveSync,T as copyStaticFile,U as ensureDir,q as fileExistsAsync,I as readFileNames};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export * from './fs.js';
|
|
2
2
|
export * from './paths.js';
|
|
3
3
|
export * from './rbac.js';
|
|
4
|
-
export
|
|
4
|
+
export { slugger, slug, GithubSlugger } from '../../utils/slugger.js';
|
|
5
5
|
export * from './attribute-parser.js';
|
|
6
6
|
export * from './resolve-src-set.js';
|
|
7
7
|
export * from './shared-data.js';
|
|
8
8
|
export * from './globs.js';
|
|
9
9
|
export * from './billing.js';
|
|
10
10
|
export * from './resolve-asset-path.js';
|
|
11
|
-
export
|
|
11
|
+
export { UniqueKeyResolver } from '../../utils/conflict-resolvers.js';
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./fs.js";export*from"./paths.js";export*from"./rbac.js";
|
|
1
|
+
export*from"./fs.js";export*from"./paths.js";export*from"./rbac.js";import{slugger as m,slug as p,GithubSlugger as x}from"../../utils/slugger.js";export*from"./attribute-parser.js";export*from"./resolve-src-set.js";export*from"./shared-data.js";export*from"./globs.js";export*from"./billing.js";export*from"./resolve-asset-path.js";import{UniqueKeyResolver as n}from"../../utils/conflict-resolvers.js";export{x as GithubSlugger,n as UniqueKeyResolver,p as slug,m as slugger};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as t}from"
|
|
1
|
+
import{envConfig as t}from"../config/env-config.js";function e(){return t.NEW_CATALOG_ENABLED==="true"}export{e as isCatalogEntitiesEnabled};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as e}from"
|
|
1
|
+
import{envConfig as e}from"../config/env-config.js";import{isCatalogEntitiesEnabled as o}from"./is-catalog-entities-enabled.js";function s(r){return o()&&e.NEW_SCORECARDS_ENABLED==="true"&&Array.isArray(r.scorecards)&&r.scorecards.length>0}export{s as isScorecardsEnabled};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as p}from"
|
|
1
|
+
import{envConfig as p}from"../config/env-config.js";import{reporter as r}from"../tools/notifiers/reporter.js";import{isMarkdocError as d}from"../plugins/markdown/errors.js";import{telemetryTraceStep as m}from"../../cli/telemetry/helpers/trace-step.js";async function k(i){await m("build.validation_errors",async n=>{let e=0;for(const[a,c]of i.cache.errors.entries()){const f=a.split(":")[1];for(const o of c)d(o)?(r.reportMarkdocProblem(o),o.type!=="BROKEN_LINK"&&e++):await r.panicOnBuild(o.message,f)}const s=await i.getConfig();if(!p.isBuildMode)return;const t=r.getPageRenderProblems().length;n?.setAttribute("markdocErrors",e.toString()),n?.setAttribute("pageRenderErrors",t.toString()),e>0&&!s?.reunite?.ignoreMarkdocErrors?(r.printErrors(),await r.panic(`Need to fix ${e} Markdoc issue(s) or set the \`ignoreMarkdocErrors\` option to \`true\` in the \`reunite\` section of your \`redocly.yaml\``)):t>0&&(r.printErrors(),await r.panic(`Need to fix ${t} runtime error(s) in React pages`))})}export{k as reportAllErrors};
|
package/dist/server/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire as o}from"module";import{envConfig as r}from"
|
|
1
|
+
import{createRequire as o}from"module";import{envConfig as r}from"./config/env-config.js";const i=r.REDOCLY_INTERNAL_DEV==="true"?"local":o(import.meta.url)("../../package.json").version;export{i as PORTAL_VERSION};
|
|
@@ -57,11 +57,13 @@ type McpAuthorizationCodePayload = {
|
|
|
57
57
|
client_id: string;
|
|
58
58
|
redirect_uri: string;
|
|
59
59
|
id_token: string;
|
|
60
|
+
idp_access_token?: string;
|
|
60
61
|
iat: number;
|
|
61
62
|
exp: number;
|
|
62
63
|
};
|
|
63
64
|
export declare function createMcpAuthorizationCode(params: {
|
|
64
65
|
idToken: string;
|
|
66
|
+
idpAccessToken?: string;
|
|
65
67
|
clientId: string;
|
|
66
68
|
redirectUri: string;
|
|
67
69
|
ttlSec?: number;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import"../node-crypto-polyfill.js";import{DOMParser as
|
|
1
|
+
import"../node-crypto-polyfill.js";import{DOMParser as b}from"@xmldom/xmldom";import{SignedXml as B}from"xml-crypto";import F from"xpath";import{deflateSync as H,inflateSync as J}from"fflate";import{createHash as q}from"crypto";import{ulid as W}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as K}from"@redocly/config";import{AUTH_URL as Q,JWT_SECRET_KEY as I}from"../constants/common.js";import{getPathPrefix as X,withPathPrefix as Y}from"@redocly/theme/core/utils";import{DEFAULT_AUTHENTICATED_TEAM as G,REQUIRED_OIDC_SCOPES as D,ServerRoutes as N}from"../../constants/common.js";import{appendQueryParams as Z}from"../../utils/url/append-query-params.js";import{logger as ee}from"../tools/notifiers/logger.js";import{randomString as te}from"../utils/crypto/random-string.js";import{randomUUID as P}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as y,JwtTokenExpired as ne}from"./jwt/types.js";import*as p from"./jwt/jwt.js";import{parseTeamClaimToArray as re}from"../utils/index.js";import{arrayBufferToBase64 as ae,decodeBase64 as R,encodeBase64URL as oe,urlSafeBase64 as v}from"./jwt/encode.js";import{formatSamlCertificate as se}from"./utils/format-saml-certificate.js";function j(e){return e?.type===u.OIDC}function ie(e){return e?.type===u.SAML2}async function ze(e,t){if(j(t))return ce(e,t);if(ie(t))return ue(e,t)}async function ce(e,t){const r=await V(e,t),n=new Set((t.scopes||[]).concat(D)),a=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:r.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(n).join(" "),extraParams:a,pkce:t.pkce}}function ue(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}async function Be(e,t,r,n,a={}){const o=new Set((n.scopes||[]).concat(D));return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:n.clientId,scope:Array.from(o).join(" "),code:t,redirect_uri:E(r),grant_type:"authorization_code",...n.clientSecret?{client_secret:n.clientSecret}:{},...a}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function de(e,{authorizationEndpoint:t,clientId:r,responseType:n,scope:a,extraParams:o,idpId:s,pkce:l},m,A,S){if(!t||!r||!n||!a)return{loginUrl:void 0};const c=new URL(t),f=S?.redirectUriOverride??`${e}${Y(N.OIDC_CALLBACK)}`,_={state:P(),idpId:s,redirectUri:f,redirectTo:m,branch:S?.branchOverride??me(e),inviteCode:A,source:S?.sourceOverride??"portal"},h={};if(l){const d=v(te(50)),x=v(q("sha256").update(d).digest("base64")),g="S256";c.searchParams.append("code_challenge",x),c.searchParams.append("code_challenge_method",g),h.code_verifier={value:d,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:X()||"/"}}}c.searchParams.append("client_id",r),c.searchParams.append("scope",a),c.searchParams.append("response_type",n),c.searchParams.append("redirect_uri",E(f)),c.searchParams.append("state",oe(JSON.stringify(_)));for(const d in o)o[d]!==void 0&&c.searchParams.append(d,o[d]);return{loginUrl:c.toString(),cookies:h}}function Fe(e,t,r,n){const a=new URL(e);return a.searchParams.append("post_logout_redirect_uri",t),n&&a.searchParams.append("state",n),a.searchParams.append("id_token_hint",r),a.toString()}async function He(e){const t=Math.floor(Date.now()/1e3),r=t+(e.ttlSec??600);return p.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpAccessToken?{idp_access_token:e.idpAccessToken}:{},iat:t,exp:r},I,y.HS256)}async function Je(e){await p.verify(e,I,y.HS256);const{payload:t}=p.decode(e);if(t.type!=="mcp_auth_code")throw new Error("Invalid authorization code type");if(!t.client_id||!t.redirect_uri)throw new Error("Authorization code missing required claims");if(typeof t.exp=="number"&&Date.now()>=t.exp*1e3)throw new Error("Authorization code expired");return t}function qe(e){const t=e||W(),r=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:r,object:"mcp_session",uri:`urn:redocly:realm:mcp:session:${r}`}}function E(e){return e.match(/^https:\/\/preview-[^\.]+--/)?"https://previewauth--"+e.split("--")[1]:e.match(/^(https:\/\/[^\.]+)--[^\.]+\.preview\./)?e.replace(/^(https:\/\/[^\.]+?)--[^\.]+\.preview\./,"$1.previewauth."):e}function me(e){return e.match(/^(https:\/\/[^\.]+?)--([^\.]+)\.preview\./)?.[2]||void 0}function le(e){return e.type===u.OIDC}function pe(e){return e.type===u.SAML2}function We(e,t,r,n){return le(e)?de(t,e,r,n):pe(e)?fe(t,e,r,n):{}}function fe(e,t,r,n){const o=`<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
|
|
2
2
|
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
|
3
3
|
Version="2.0"
|
|
4
|
-
ID="_${
|
|
4
|
+
ID="_${P()}"
|
|
5
5
|
IssueInstant="${new Date().toISOString()}"
|
|
6
|
-
AssertionConsumerServiceURL="${e}${
|
|
6
|
+
AssertionConsumerServiceURL="${e}${N.SAML_CALLBACK}"
|
|
7
7
|
AttributeConsumingServiceIndex="0">
|
|
8
8
|
<saml:Issuer>${t.entityId}</saml:Issuer>
|
|
9
9
|
<samlp:NameIDPolicy
|
|
10
10
|
AllowCreate="true"
|
|
11
11
|
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
|
|
12
|
-
</samlp:AuthnRequest>`,s=he(o);return{loginUrl:Z(t.ssoUrl,{SAMLRequest:s,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:r,inviteCode:n,source:"portal"})})}}function he(e){return ae(H(new TextEncoder().encode(e)).buffer)}function Ke(e){const t=R(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const r=J(new Uint8Array(atob(e).split("").map(n=>n.charCodeAt(0))));return new TextDecoder().decode(r)}function Qe(e){try{return JSON.parse(R(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function Xe(e){const t=new
|
|
12
|
+
</samlp:AuthnRequest>`,s=he(o);return{loginUrl:Z(t.ssoUrl,{SAMLRequest:s,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:r,inviteCode:n,source:"portal"})})}}function he(e){return ae(H(new TextEncoder().encode(e)).buffer)}function Ke(e){const t=R(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const r=J(new Uint8Array(atob(e).split("").map(n=>n.charCodeAt(0))));return new TextDecoder().decode(r)}function Qe(e){try{return JSON.parse(R(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function Xe(e){const t=new b().parseFromString(e,"application/xml"),n=i(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,o=i(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",s=i(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],l=s&&s.nodeValue||void 0,m=i(t,"//*[local-name(.)='Audience']/text()")[0],A=m&&m.nodeValue||void 0,c=i(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",f=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],_=f&&f.nodeValue||"",h=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],d=h&&h.nodeValue||"",x=i(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],g=ye(x),T={},k=i(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(k.length)for(const C of k){const O=i(C,"./@Name")[0];if(O.nodeValue){const U=i(C,"./*[local-name(.)='AttributeValue']/text()")[0];U?.nodeValue&&(T[O.nodeValue]=U.nodeValue)}}return{uid:_,success:n,expiresAt:g,issuerId:l,entityId:A,attrs:T,cert:c,nameFormat:d,destination:o}}function ye(e){const t=typeof e?.nodeValue=="string"&&L(Date.parse(e.nodeValue)),r=L(Date.now()),n=L(Date.now()+720*60*1e3);return t?t>r&&t<n?n:t:r}function L(e){return Math.floor(e/1e3)}const M={},w={jwks:{}};async function V(e,t){return M[e]||(M[e]=t.configurationUrl?await $(t.configurationUrl):t.configuration),M[e]}async function we(e){for(const t of Object.keys(e)){const r=e[t];if(!j(r))continue;const n=await V(t,r);if(n.jwks_uri){const a=await $(n.jwks_uri);for(const o of a.keys)w.jwks[o.kid]={...o,idpId:t}}}}async function $(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function Ye(e){return fetch(`${Q}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function Ge(e){if(!e.configurationUrl)return!1;const t=new URL(e.configurationUrl);return["localhost","127.0.0.1","blueharvest.cloud","bhstage.cloud","cloud.redocly.com","beta.redocly.com","cloud.eu.redocly.com","beta.eu.redocly.com","cba.au.redocly.com"].some(n=>Se(t.hostname,n))}function Se(e,t){return e===t||e.endsWith(`.${t}`)}async function Ze(e,t){const r=new b().parseFromString(e),n=i(r,"//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];if(!n)throw new Error("Cannot find Signature in the SAML response");const a=se(t),o=new B({publicCert:a});o.loadSignature(n);try{return o.checkSignature(e)}catch{return!1}}function et(e,t,r,n){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=r["http://schemas.microsoft.com/identity/claims/objectidentifier"]);let a;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(a=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(a=e);const o=r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=o?.match(/.+@.+/);return a=a||r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?o:void 0),a=a?.toLowerCase(),{sub:e,given_name:r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:r["http://schemas.microsoft.com/identity/claims/displayname"]||o,email:a,email_verified:!0,teams:n?re(r[n]):[]}}function z(e,t={}){return e.map(r=>t[r]||r)}async function tt(e,t){if(!t)return{};const r=t.authorization;if(!r)return{};try{const n=p.decode(r);if(n.header.alg===y.RS256){w.jwks[n.header.kid]===void 0&&await we(e);const m=w.jwks[n.header.kid];if(!m)return w.jwks[n.header.kid]=null,{};await p.verify(r,m,y.RS256)}else await p.verify(r,I,y.HS256);const a=n.payload.idpId||w.jwks[n.header.kid]?.idpId,o=e[a]||{},s=xe(o),l=_e(o);return{...n.payload,email:n.payload.email?.toLowerCase(),idpId:a,teams:Array.from(new Set([...z(n.payload.teams||[],l),..."defaultTeams"in o&&o.defaultTeams||[],...z("teamsClaimName"in o&&n.payload[s||""]||[],l),G])),name:Ae(n.payload),isAuthenticated:!0,idpAccessToken:n.payload.idp_access_token||t.idp_access_token,federatedAccessToken:t.federated_access_token,federatedIdToken:t.federated_id_token,authCookie:r}}catch(n){n instanceof ne||ee.error("Malformed JWT token: %s",n.message)}return{}}function Ae(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function _e(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function xe(e){switch(e.type){case u.SAML2:return e.teamsAttributeName;case u.OIDC:return e.teamsClaimName;default:return K}}function i(e,t){return F.select(t,e)||[]}export{We as buildLoginUrl,de as buildOidcLoginUrl,Fe as buildOidcLogoutUrl,fe as buildSAML2LoginUrl,He as createMcpAuthorizationCode,qe as createMcpSessionResource,Ke as decodeSamlResponse,he as encodeSAML2,et as extractUserClaims,ze as getAuthProviderLoginParams,ce as getOidcLoginParams,V as getOidcMetadata,Ye as getRedoclyTokenPayload,ue as getSaml2LoginParams,tt as getUserParamsFromCookies,Ae as getUsernameFromPayload,j as isOidcProviderConfig,Ge as isRedoclySso,ie as isSaml2ProviderConfig,Be as oidcExchangeCodeForToken,Qe as parseOidcState,me as parsePreviewBranch,Xe as parseSamlResponse,E as rewritePreviewAuthRedirectUri,Je as verifyMcpAuthorizationCode,Ze as verifySAMLResponse};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{logger as n}from"../tools/notifiers/logger.js";import{envConfig as o}from"
|
|
1
|
+
import{logger as n}from"../tools/notifiers/logger.js";import{envConfig as o}from"../config/env-config.js";import{runApiRoutesWorker as m}from"../api-routes/run-api-routes-worker.js";import{MCP_DOCS_SERVER_HANDLER_ID as i}from"../plugins/mcp/index.js";import{handleMcpRequest as u}from"../plugins/mcp/handlers/handle-mcp-request.js";async function l(r,s,a){try{const e=n.startTiming(),t=r.requestHandlerId===i?await u(r,s,a):await m(r,s,a);return n.infoTime(e,`API request handled "${new URL(s.req.url).pathname}" with status "${t.status}" and content type "${t.headers?.get("content-type")}"`),t.headers.set("X-Source","REALM_API_FUNCTION"),t}catch(e){return n.error(`[${r.requestHandlerId}] ${e.stack}`),e.name==="RequestBodySizeLimitError"?s.json({message:e.message},{status:413}):e.name==="ResponseSizeLimitError"?s.json({message:e.message},{status:500}):e.name==="MemoryUsageLimitError"?s.json({message:e.message},{status:502}):e.name==="TimeoutExceededError"?s.json({message:e.message},{status:504}):o.isDevelopMode?s.json({message:e.message},{status:500}):s.json({message:"Internal server error"},{status:500})}}export{l as handleApiRouteRequest};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import*as
|
|
2
|
-
%s`,e.message,e.stack))}const w=
|
|
1
|
+
import*as b from"node:http";import{AsyncLocalStorage as A}from"node:async_hooks";import{Readable as S,Stream as C}from"node:stream";import{pipeline as H}from"node:stream/promises";import{ReadableStream as k}from"node:stream/web";import{getPathPrefix as u}from"@redocly/theme/core/utils";import{ALLOWED_CORS_ORIGINS as L}from"../constants/common.js";import{logger as d}from"../tools/notifiers/logger.js";import{shutdowner as x}from"../tools/shutdowner.js";import{envConfig as I}from"../config/env-config.js";import{getClientIp as T}from"./utils/get-client-ip.js";import{normalizeIpAddress as O}from"./utils.js";import{CORS_PROXY_STREAM_HEADER as P}from"./routes/cors-proxy.js";const R=new A;globalThis.redoclyCookieStorage=R;function X(n,c=4e3){return new Promise((m,p)=>{const f=b.createServer(async(t,r)=>{const y=t.headers.cookie||"";R.run(y,async()=>{let s;try{const e=new URL(t.url||"",`http://${t.headers.host}`),o=[],l=t.rawHeaders.length;for(let i=0;i<l;i+=2)o.push([t.rawHeaders[i],t.rawHeaders[i+1]]);const a={headers:o,method:t.method};t.method==="GET"||t.method==="HEAD"||(a.body=S.toWeb(t),a.duplex="half");const h=new Request(e.toString(),a),v=T(h)||"127.0.0.1",E=h?.headers?.get("x-forwarded-host")||O(t.socket.remoteAddress);h.context={remoteAddr:{hostname:E,port:t.socket.localPort,ipAddress:v},url:e},s=await n.fetch(h)}catch(e){s=new Response(null,{status:500}),e instanceof Error&&(e.name==="TimeoutError"||e.constructor.name==="TimeoutError"?s=new Response(null,{status:504}):e.code==="ERR_INVALID_URL"&&(s=new Response("Invalid URL",{status:404})),d.error(`Error while handling request: %s
|
|
2
|
+
%s`,e.message,e.stack))}const w=t.headers.origin;w&&L.some(e=>w===e)&&(r.setHeader("Access-Control-Allow-Origin",w),r.setHeader("Access-Control-Allow-Credentials","true"));for(const[e,o]of s.headers||[])try{e==="set-cookie"?r.setHeader(e,s.headers.getSetCookie(e)):r.setHeader(e,o)}catch(l){d.error(`Error while setting header: ${l?.message}`)}if(r.setHeader("Vary","Cookie"),r.statusCode=s.status||500,s.body)try{if(_(s)){const e=new C.Transform({transform(o,l,a){if(r.closed||r.destroyed)return a();r.write(o,l)?process.nextTick(a):r.once("drain",a)},flush(o){if(r.closed||r.destroyed)return o();r.end(),o()}});await H(s.body instanceof k?S.fromWeb(s.body):s.body,e)}else{const e=await s.text();r.setHeader("Content-Length",Buffer.byteLength(e)),r.end(e)}}catch(e){console.error(e);const o=e instanceof Error?e:new Error("unknown error",{cause:e});r.destroy(o)}else r.end()})});x.registerShutdownCallback(()=>new Promise(t=>{d.verbose("Shutting down http server"),f.close(()=>{d.verbose("Http server shut down"),t()})})),f.listen(parseInt(String(c),10)).on("listening",()=>{I.isDevelopMode?d.logInFooter("server",` \u{1F310} Preview URL: http://127.0.0.1:${c}${u()}`):d.logInFooter("server",`Server started at: http://127.0.0.1:${c}${u()}`),m(f)}).on("error",p)})}function _(n){const c=n.headers.get("content-type")||"",m=n.headers.get("x-accel-buffering")||"",p=n.headers.get("content-encoding"),f=n.headers.get("content-length"),t=n.headers.get("transfer-encoding");return n.headers.get(P)==="1"||p||t||f||/^no$/i.test(m)||!/^(text\/(?!event-stream\b))/i.test(c)}export{X as startHttpServer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as o}from"
|
|
1
|
+
import{envConfig as o}from"../../config/env-config.js";const t=(r,e)=>r.secureMethods?.includes(e)??!1;function f(r={}){return async(e,n)=>{const a=e.req.method;if(!t(r,a))return await n();const i=e.req.header("apiKey");if(!i)return e.json({message:"API key is required"},401);try{if(!o.BH_API_URL)return e.json({message:"API key validation service not configured"},500);const s=new URL("api-keys-verify",o.BH_API_URL).toString();if(!(await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:i})})).ok)return e.json({message:"Invalid API key"},401);await n()}catch{return e.json({message:"API key validation failed"},400)}}}export{f as apiKeyMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{KvService as l}from"../../persistence/kv/services/kv-service.js";import{DEFAULT_AUTHENTICATED_TEAM as y}from"../../../constants/common.js";import{envConfig as s}from"
|
|
1
|
+
import{KvService as l}from"../../persistence/kv/services/kv-service.js";import{DEFAULT_AUTHENTICATED_TEAM as y}from"../../../constants/common.js";import{envConfig as s}from"../../config/env-config.js";import{JWT_SECRET_KEY as I}from"../../constants/common.js";import*as m from"../jwt/jwt.js";import{AlgorithmTypes as T}from"../jwt/types.js";const h=60,p=e=>["POST","PUT","DELETE","PATCH"].includes(e),f=e=>["GET"].includes(e);function K({serverOutDir:e,protectReadMethods:t=!0}){return async(r,a)=>await w(r,a,e,t)}const w=async(e,t,r,a=!0)=>{const n=e.req.method,i=p(n)||f(n)&&a,o=e.req.header("apiKey");if(o)return await g(e,t,o,r);const u=e.req.header("authorization")?.replace("Bearer ","");return u?await E(e,t,u):i?e.json({message:"API key is required"},401):await t()},g=async(e,t,r,a)=>{if(!s.BH_API_URL||!s.ORGANIZATION_ID)return e.json({message:"API key validation service not configured"},500);try{const n=await l.getInstance({baseDbDir:a});let i=await _(n,r);if(i)return e.set("apiKeyTeams",i.teams),await t();const o=new URL(`/api/orgs/${s.ORGANIZATION_ID}/session`,s.BH_API_URL).toString(),c=await fetch(o,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!c.ok)return e.json({message:"Invalid API key"},401);const A=(await c.json())?.user?.teams?.[s.ORGANIZATION_ID]??[],d=[y,...A];return e.set("apiKeyTeams",d),await n.set(["api-keys","reunite",r],{valid:!0,teams:d},{ttlInSeconds:h}),await t()}catch{return e.json({message:"API key validation failed"},400)}},E=async(e,t,r)=>{try{const a=await m.verify(r,I,T.HS256),n=m.decode(r).payload.isInternalConnection;return!a||!n?e.json({message:"API key is required"},401):await t()}catch{return e.json({message:"API key validation failed"},400)}},_=async(e,t)=>{try{return await e.get(["api-keys","reunite",t])}catch{return null}};export{K as catalogAuthMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cors as o}from"hono/cors";import{envConfig as r}from"
|
|
1
|
+
import{cors as o}from"hono/cors";import{envConfig as r}from"../../config/env-config.js";function n(e){return r.PROJECT_URL?o({origin:r.PROJECT_URL,allowMethods:e.allowMethods}):o()}export{n as corsMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{pathToFileURL as l}from"url";import{isDefined as m}from"../../../../utils/guards/is-defined.js";import{slash as s}from"../../../../utils/path/slash.js";import{envConfig as o}from"
|
|
1
|
+
import{pathToFileURL as l}from"url";import{isDefined as m}from"../../../../utils/guards/is-defined.js";import{slash as s}from"../../../../utils/path/slash.js";import{envConfig as o}from"../../../config/env-config.js";import{compose as w}from"./hono-compose.js";function D(i){return async(e,a)=>{await i.waitForPluginsLifecycle();const n=await f(i.serverOutDir),d=(await Promise.all(i.getAllMiddleware().map(({id:t})=>n[t]).map(async t=>typeof t=="function"?(await t()).default:void 0))).filter(m),r=await w(d)(e,a,i);if(!r.finalized)throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return r.res}}async function f(i){try{let e;return o.isRuntimeMode?e=await import("@portal/middleware"):e=await import(l(`${s(i)}/middleware-entry.js`)+"?"+new Date),e.middleware}catch(e){if(o.isDevelopMode)return{};throw e}}export{D as dynamicMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{envConfig as o}from"
|
|
1
|
+
import{envConfig as o}from"../../config/env-config.js";import{shutdowner as r}from"../../tools/shutdowner.js";import{logger as n}from"../../tools/notifiers/logger.js";let t=null;const e=o.WEB_SERVER_IDLE_TIMEOUT;function m(){if(e){if(isNaN(+e))throw new Error(`IDLE_TIMEOUT must be a number, got ${e}`);t&&clearTimeout(t),t=setTimeout(()=>{n.info("Server is idle, stopping..."),r.exitWithCode(0)},+e)}}function T(){return async(u,i)=>{m(),await i()}}export{T as idleTimeoutMiddleware,m as startIdleTimeout};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{minimatch as p}from"minimatch";import{withoutPathPrefix as c}from"@redocly/theme/core/utils";import{removeTrailingSlash as l}from"../../../utils/url/remove-trailing-slash.js";import{SERVER_EDITOR_APP_URL as d}from"
|
|
1
|
+
import{minimatch as p}from"minimatch";import{withoutPathPrefix as c}from"@redocly/theme/core/utils";import{removeTrailingSlash as l}from"../../../utils/url/remove-trailing-slash.js";import{SERVER_EDITOR_APP_URL as d}from"../../constants/common.js";function y(n){return async(e,i)=>{try{await i()}finally{const r=n.getConfig();if(r.responseHeaders){const a=c(new URL(e.req.url).pathname),t=Object.keys(r.responseHeaders);for(const s of t)if(p(a,s))for(const{name:f,value:m}of r.responseHeaders[s])e.header(f,m)}const o=e.req.header("referer");o&&l(o)===d&&e.header("Cross-Origin-Resource-Policy","cross-origin")}}}export{y as responseHeadersMiddleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const i={".aac":"audio/aac",".abw":"application/x-abiword",".arc":"application/x-freearc",".avif":"image/avif",".avi":"video/x-msvideo",".azw":"application/vnd.amazon.ebook",".bin":"application/octet-stream",".bmp":"image/bmp",".bz":"application/x-bzip",".bz2":"application/x-bzip2",".cda":"application/x-cdf",".csh":"application/x-csh",".css":"text/css",".csv":"text/csv",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".eot":"application/vnd.ms-fontobject",".epub":"application/epub+zip",".gz":"application/gzip",".gif":"image/gif",".htm":"text/html",".html":"text/html",".ico":"image/vnd.microsoft.icon",".ics":"text/calendar",".jar":"application/java-archive",".jpeg":"image/jpeg",".jpg":"image/jpeg",".js":"application/javascript",".json":"application/json",".jsonld":"application/ld+json",".mid":"audio/x-midi",".midi":"audio/x-midi",".mjs":"text/javascript",".mp3":"audio/mpeg",".mp4":"video/mp4",".mpeg":"video/mpeg",".mpkg":"application/vnd.apple.installer+xml",".odp":"application/vnd.oasis.opendocument.presentation",".ods":"application/vnd.oasis.opendocument.spreadsheet",".odt":"application/vnd.oasis.opendocument.text",".oga":"audio/ogg",".ogv":"video/ogg",".ogx":"application/ogg",".opus":"audio/opus",".otf":"font/otf",".png":"image/png",".pdf":"application/pdf",".php":"application/x-httpd-php",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".rar":"application/vnd.rar",".rtf":"application/rtf",".sh":"application/x-sh",".svg":"image/svg+xml",".tar":"application/x-tar",".tif":"image/tiff",".tiff":"image/tiff",".ts":"video/mp2t",".ttf":"font/ttf",".txt":"text/plain",".vsd":"application/vnd.visio",".wav":"audio/wav",".weba":"audio/webm",".webm":"video/webm",".webp":"image/webp",".woff":"font/woff",".woff2":"font/woff2",".xhtml":"application/xhtml+xml",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".xml":"application/xml",".xul":"application/vnd.mozilla.xul+xml",".zip":"application/zip",".3gp":"video/3gpp",".3g2":"video/3gpp2",".7z":"application/x-7z-compressed"},a={"font/otf":365*24*60*60,"font/ttf":365*24*60*60,"font/woff":365*24*60*60,"font/woff2":365*24*60*60,"application/vnd.ms-fontobject":365*24*60*60};export{a as DEFAULT_MAX_AGE_FOR_MIME_TYPE,i as MIME_TYPES};
|
|
1
|
+
const i={".aac":"audio/aac",".abw":"application/x-abiword",".arc":"application/x-freearc",".avif":"image/avif",".avi":"video/x-msvideo",".azw":"application/vnd.amazon.ebook",".bin":"application/octet-stream",".bmp":"image/bmp",".bz":"application/x-bzip",".bz2":"application/x-bzip2",".cda":"application/x-cdf",".csh":"application/x-csh",".css":"text/css",".csv":"text/csv",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".eot":"application/vnd.ms-fontobject",".epub":"application/epub+zip",".gz":"application/gzip",".gif":"image/gif",".htm":"text/html",".html":"text/html",".ico":"image/vnd.microsoft.icon",".ics":"text/calendar",".jar":"application/java-archive",".jpeg":"image/jpeg",".jpg":"image/jpeg",".js":"application/javascript",".json":"application/json",".jsonld":"application/ld+json",".mid":"audio/x-midi",".midi":"audio/x-midi",".md":"text/markdown",".mjs":"text/javascript",".mp3":"audio/mpeg",".mp4":"video/mp4",".mpeg":"video/mpeg",".mpkg":"application/vnd.apple.installer+xml",".odp":"application/vnd.oasis.opendocument.presentation",".ods":"application/vnd.oasis.opendocument.spreadsheet",".odt":"application/vnd.oasis.opendocument.text",".oga":"audio/ogg",".ogv":"video/ogg",".ogx":"application/ogg",".opus":"audio/opus",".otf":"font/otf",".png":"image/png",".pdf":"application/pdf",".php":"application/x-httpd-php",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".rar":"application/vnd.rar",".rtf":"application/rtf",".sh":"application/x-sh",".svg":"image/svg+xml",".tar":"application/x-tar",".tif":"image/tiff",".tiff":"image/tiff",".ts":"video/mp2t",".ttf":"font/ttf",".txt":"text/plain",".vsd":"application/vnd.visio",".wav":"audio/wav",".weba":"audio/webm",".webm":"video/webm",".webp":"image/webp",".woff":"font/woff",".woff2":"font/woff2",".xhtml":"application/xhtml+xml",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".xml":"application/xml",".xul":"application/vnd.mozilla.xul+xml",".zip":"application/zip",".3gp":"video/3gpp",".3g2":"video/3gpp2",".7z":"application/x-7z-compressed"},a={"font/otf":365*24*60*60,"font/ttf":365*24*60*60,"font/woff":365*24*60*60,"font/woff2":365*24*60*60,"application/vnd.ms-fontobject":365*24*60*60};export{a as DEFAULT_MAX_AGE_FOR_MIME_TYPE,i as MIME_TYPES};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{setCookie as _,deleteCookie as q}from"hono/cookie";import{AuthProviderType as W}from"@redocly/config";import{withPathPrefix as I,getPathPrefix as R}from"@redocly/theme/core/utils";import{compareURIs as Y}from"../../../utils/url/compare-uris.js";import{ensureArray as b}from"../../../utils/array/ensure-array.js";import{ALTERNATIVE_AUD_CLAIM_NAME as F,JWT_SECRET_KEY as v,ORG_SLUG as Q,ORG_ID as Z}from"../../constants/common.js";import{DEFAULT_COOKIE_EXPIRATION as B,ServerRoutes as S}from"../../../constants/common.js";import{sanitizeRedirectPathname as z}from"../../../utils/url/sanitize-redirect-pathname.js";import{telemetry as M}from"../../telemetry/index.js";import{envConfig as H}from"../../../config/env-config.js";import{getAuthProviderLoginParams as x,isOidcProviderConfig as $,isSaml2ProviderConfig as ee,oidcExchangeCodeForToken as re,buildLoginUrl as oe,decodeSamlResponse as ne,extractUserClaims as te,parseSamlResponse as ie,parseOidcState as se,verifySAMLResponse as ae,getUsernameFromPayload as de,buildOidcLogoutUrl as ce,getOidcMetadata as j,getRedoclyTokenPayload as le,isRedoclySso as ue,rewritePreviewAuthRedirectUri as pe,parsePreviewBranch as N,buildOidcLoginUrl as ge,createMcpSessionResource as k}from"../auth.js";import*as O from"../jwt/jwt.js";import{AlgorithmTypes as P}from"../jwt/types.js";import{handleErrorPageRender as fe}from"../utils.js";import{encodeBase64URL as me}from"../jwt/encode.js";async function ve(i){if(H.isProductionEnv)return i.newResponse(null,404,{});const{password:e,...r}=await i.req.json(),a=await O.sign({...r,name:r.username||r.email||"Unknown"},v,P.HS256);return _(i,"authorization",a,{path:R()||"/",httpOnly:!0,secure:!0,sameSite:"none"}),i.newResponse(null,200,{})}function $e(){return async i=>{const e=i.get("logger"),r=encodeURIComponent(i.req.query("message")||"");e.error(`Login error: ${r}`);const a=`${S.LOGIN}/?error=${encodeURIComponent(r)}`;return i.newResponse(null,301,{Location:a})}}function K(i){if(!i||!i.includes(S.MCP_CALLBACK))return null;try{const e=i.split("/"),r=e[e.length-1];if(r){const a=Buffer.from(r,"base64url").toString("utf-8");return JSON.parse(a).mcpSessionId||null}}catch{}return null}function Ue(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=se(e.req.query("state")),f=n.idpId,t=n.source==="mcp"||n.redirectTo&&typeof n.redirectTo=="string"&&n.redirectTo.includes(S.MCP_CALLBACK),c=t?K(typeof n.redirectTo=="string"?n.redirectTo:void 0):null,s=a?.[f];if(!$(s))return r.error("OIDC login error: missing OIDC provider config"),e.text("Forbidden",403);const d=await j(f,s);if(a&&!d.token_endpoint){const p="Invalid OIDC configuration: token_endpoint is required";return r.error(`OIDC login error: ${p}`),e.text(p,500)}try{const p=d.token_endpoint,l=e.req.query("code"),m=e.req.query("error");if(m)return t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:`OIDC error: ${m}`,error_details:e.req.query("error_description")||null}]),fe(e,i,{slug:"/"},403,"403OIDC");if(!l){const w="Code is expected but not present";return r.error(`OIDC login error: ${w}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const h=e.req.header("x-forwarded-host"),g=e.req.header("x-forwarded-proto")||"https",A=t&&typeof n.redirectUri=="string"?n.redirectUri:new URL(I(S.OIDC_CALLBACK),h?`${g}://${h}`:e.req.url).toString(),C=e.get("cookies")?.code_verifier,u=await re(p,l,A,s,{...s.tokenRequestCustomParams,...C?{code_verifier:C}:{}});if(u.error)return r.error(`Error from OIDC provider: "${u.error}"`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:`Token exchange error: ${u.error}`,error_details:u.error_description||null}]),e.text(`Forbidden: ${u.error_description||u.error}`,403);if(!u?.id_token){const w="No id_token, please, add openid to scopes";return r.error(`OIDC login error: ${w}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const{payload:o,header:U}=O.decode(u.id_token),J=U.alg===P.RS256;if(s.audience?.length&&![...b(o.aud||[]),...b(o[F]||[])].some(L=>s.audience?.includes(L))){const L="No valid audience found in id_token";return r.error(`OIDC login error: ${L}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:L,error_details:null}]),new Response(`Forbidden: ${L}`)}const E=J?u.id_token:await O.sign({...o,idpId:f},v,P.HS256);de(o)||r.warn("To display your username, the required 'email' or 'full_profile' scope must be added to the identity provider configuration");const D=s?.tokenExpirationTime?Date.now()+s.tokenExpirationTime*1e3:o.exp*1e3||Date.now()+B*1e3;if(s.introspectEndpoint){const w=await fetch(s.introspectEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({access_token:u.access_token})});if(w.ok){const T=(await w.json()).ext?.federatedIdentity;T&&(_(e,"federated_access_token",T.access_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}),_(e,"federated_id_token",T.id_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}))}else r.warn(`OIDC introspect error: ${w.statusText}`)}if(_(e,"authorization",E,{path:R()||"/",httpOnly:!0,expires:new Date(D)}),E!==u.id_token&&_(e,"idp_id_token",u.id_token||"",{path:R()||"/",httpOnly:!0,expires:new Date(D)}),_(e,"idp_access_token",u.access_token||"",{path:R()||"/",httpOnly:!0,expires:new Date(D)}),q(e,"code_verifier",{path:R()||"/"}),t&&n.redirectTo&&typeof n.redirectTo=="string"&&n.redirectTo.includes(S.MCP_CALLBACK)){const L=`${e.req.url.split("?")[0].replace(S.OIDC_CALLBACK,"")}${n.redirectTo}`;return e.newResponse(null,302,{Location:L})}const G=typeof n.redirectTo=="string"?n.redirectTo:void 0;let V=z(new URL(G||"/",e.req.url).pathname);const X=e.newResponse(null,302,{Location:V});return r.updateContext({email:o.email,subject:o.sub}),r.info("OIDC login successful"),X}catch(p){const l=p instanceof Error?p.message:String(p),m=p instanceof Error?p.stack:String(p);if(r.error(`OIDC login error: ${l}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:l,error_details:m}]),p.error==="access_denied")return r.info("Access denied"),e.text("Forbidden",403)}const y="Something went wrong";return r.error(`OIDC login error: ${y}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:y,error_details:null}]),e.text(y,500)}}function Te(i){return async e=>{const r=e.get("logger"),n=e.get("auth").claims?.idpId,t=i.getConfig().ssoDirect?.[n];if(e.req.method==="POST")return $(t)||q(e,"authorization",{path:R()||"/"}),r.info("Logout successful"),e.newResponse(null,200,{});let c;if($(t)){const s=(await j(n,t)).end_session_endpoint;if(s){const d=new URL(e.req.url),y=e.req.header("x-forwarded-proto")||d.protocol.slice(0,-1)||"https",p=e.req.header("x-forwarded-host")||d.host,l=`${y}://${p}`,m=N(l),h=m?me(JSON.stringify({branch:N(l)})):void 0,g=m?`${pe(l)}/_auth/logout`:`${l}/post-logout`;c=ce(s,g,e.get("cookies")?.idp_id_token||e.get("cookies")?.authorization||"",h)}}return r.info("Logout successful"),q(e,"authorization",{path:R()||"/"}),e.newResponse(null,302,{Location:c||I("/")})}}function qe(i){return async e=>{const r=i.getConfig().logoutReturnUrl,a=r||I("/");return e.newResponse(null,302,{Location:a})}}function be(i){return async e=>{const r=e.get("logger"),a=e.req.param("code"),n=H.BH_API_URL,f=(t,c,s)=>t&&c?`${t} ${c.charAt(0)}`:s;try{if(!n)throw new Error("BH_API_URL is not set");const t=i.getConfig().ssoDirect;if(!t||!Object.keys(t).length)return r.warn("Invite no sso configured to handle"),e.redirect(I("/"));const c=await fetch(`${n}/user-invites/public/${a}`);if(!c.ok)return c.status===404?(r.warn(`Invite ${a} not found redirect to homepage`),e.redirect(I("/"))):(r.error("Invite error",await c.text()),e.redirect(I("/")));const s=await c.json(),d=new URL(I("/invite"),e.req.url);return d.searchParams.set("code",a),d.searchParams.set("org",s.organization.name),d.searchParams.set("invitedBy",f(s.invitedBy.firstName,s.invitedBy.lastName,s.invitedBy.name)),e.newResponse(null,302,{Location:d.toString()})}catch(t){return r.error("Error processing invite",{error:t,inviteCode:a}),e.text(t.message||"Failed to process invite",400)}}}function Ee(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=new URL(e.req.url),f=e.req.query("inviteCode"),t=e.req.header("x-forwarded-proto")||n.protocol.slice(0,-1)||"https",c=e.req.header("x-forwarded-host")||n.host,s=`${t}://${c}`;let d=n.searchParams.get("idpId");const y=n.searchParams.get("redirectTo"),p=Object.keys(a||{})[0];d=d||p;const l=n.searchParams.get("mcp_redirect_uri"),m=!!l;if(!a?.[d]){const o="Invalid idpId";if(r.error(`IdP login error: ${o}`),m){const U=K(y||void 0);M.sendMcpAuthorizationFailedMessage([{...k(U),error:o,error_details:null}])}return e.text(`Forbidden: ${o}`,403)}const g=d&&a?await x(d,a[d]):void 0,A={};for(const o of Object.keys(g?.extraParams||{}))A[o]=n.searchParams.get(o)||g?.extraParams?.[o]||void 0;let C,u={};if(m&&l&&g&&g.type===W.OIDC){r.info(`Building MCP OAuth login URL with redirect_uri: ${l}`);const o=ge("",{...g,extraParams:A},y,f,{redirectUriOverride:l,sourceOverride:"mcp",branchOverride:void 0});C=o.loginUrl,u=o.cookies||{}}else if(g){const o=oe({...g,extraParams:A},s,y,f);C=o.loginUrl,u=o.cookies||{}}return Object.keys(u).forEach(o=>{_(e,o,u[o].value,u[o].options)}),r.info(`IdP login initiated for ID '${d}'`),e.newResponse(null,302,{Location:C||new URL(e.req.url).pathname})}}function Fe(i){return async e=>{const r=e.get("logger"),a=await e.req.formData(),n=a.get("SAMLResponse"),f=a.get("RelayState");if(typeof n!="string"||typeof f!="string"){const o="SAMLResponse is required";return r.error(`SAML2 login error: ${o}`),e.text(`Bad request: ${o}`,400)}const t=ne(n),{success:c,uid:s,nameFormat:d,attrs:y,issuerId:p,expiresAt:l}=ie(t),{idpId:m,redirectTo:h}=JSON.parse(f);if(!c){const o="SAML2 assertion is not successful";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!l||Math.ceil(Date.now()/1e3)>=l){const o="SAML2 Token Expired";return r.error(`SAML2 login error: ${o}`),e.text(o,401)}const g=i.getConfig().ssoDirect?.[m];if(!g||!ee(g)){const o="Cannot find valid IdP";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!(g.issuerId&&p&&Y(g.issuerId,p))){const o="IssuerID is misconfigured or untrusted assertions issuer received";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!await ae(t,g.x509PublicCert)){const o="SAMLResponse signature invalid";return r.error(`SAML2 login error: ${o}`),e.text(o,401)}const C=te(s,d,y,g.teamsAttributeName);if(!C.sub){const o="The provider did not return a valid user identity.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}if(!C.email){const o="The provider did not return a valid user email.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}const u=await O.sign({...C,idpId:m},v,P.HS256);return _(e,"authorization",u,{path:R()||"/",httpOnly:!0,expires:new Date(l*1e3)}),r.updateContext({email:C.email,subject:C.sub}),r.info("SAML2 login successful"),e.newResponse(null,302,{Location:h||"/"})}}function Be(i){return async e=>{const r=e.get("logger"),a=new URL(e.req.query("redirectTo")||"/",e.req.url),n=I(z(a.pathname)),f=i.getConfig().ssoDirect,t=Object.entries(f||{}).find(([,h])=>$(h)&&ue(h));if(!(f&&t))return e.newResponse(null,302,{Location:n});const s=e.req.query("token"),d=s&&await le(s);if(!d)return e.newResponse(null,302,{Location:n});if(!b(d[F]||[]).some(h=>h===Q||h===Z))return e.newResponse(null,302,{Location:n});const l=await O.sign({...d,idpId:t?.at(0)},v,P.HS256),m=Date.now()+B*1e3;return _(e,"authorization",l,{path:R()||"/",httpOnly:!0,expires:new Date(m),sameSite:"None",secure:!0}),r.info("Token login successful"),e.newResponse(null,302,{Location:n})}}export{ve as authorizeHandler,Ee as idpLoginHandler,be as inviteHandler,Te as logoutHandler,Ue as oidcCallbackHandler,qe as postLogoutHandler,$e as redoclyLoginCallbackHandler,Be as redoclyTokenLoginHandler,Fe as samlCallbackHandler};
|
|
1
|
+
import{setCookie as _,deleteCookie as q}from"hono/cookie";import{AuthProviderType as W}from"@redocly/config";import{withPathPrefix as I,getPathPrefix as R}from"@redocly/theme/core/utils";import{compareURIs as Y}from"../../../utils/url/compare-uris.js";import{ensureArray as b}from"../../../utils/array/ensure-array.js";import{ALTERNATIVE_AUD_CLAIM_NAME as F,JWT_SECRET_KEY as v,ORG_SLUG as Q,ORG_ID as Z}from"../../constants/common.js";import{DEFAULT_COOKIE_EXPIRATION as B,ServerRoutes as S}from"../../../constants/common.js";import{sanitizeRedirectPathname as z}from"../../../utils/url/sanitize-redirect-pathname.js";import{telemetry as M}from"../../telemetry/index.js";import{envConfig as H}from"../../config/env-config.js";import{getAuthProviderLoginParams as x,isOidcProviderConfig as $,isSaml2ProviderConfig as ee,oidcExchangeCodeForToken as re,buildLoginUrl as oe,decodeSamlResponse as ne,extractUserClaims as te,parseSamlResponse as ie,parseOidcState as se,verifySAMLResponse as ae,getUsernameFromPayload as de,buildOidcLogoutUrl as ce,getOidcMetadata as j,getRedoclyTokenPayload as le,isRedoclySso as ue,rewritePreviewAuthRedirectUri as pe,parsePreviewBranch as N,buildOidcLoginUrl as ge,createMcpSessionResource as k}from"../auth.js";import*as O from"../jwt/jwt.js";import{AlgorithmTypes as P}from"../jwt/types.js";import{handleErrorPageRender as fe}from"../utils.js";import{encodeBase64URL as me}from"../jwt/encode.js";async function ve(i){if(H.isProductionEnv)return i.newResponse(null,404,{});const{password:e,...r}=await i.req.json(),a=await O.sign({...r,name:r.username||r.email||"Unknown"},v,P.HS256);return _(i,"authorization",a,{path:R()||"/",httpOnly:!0,secure:!0,sameSite:"none"}),i.newResponse(null,200,{})}function $e(){return async i=>{const e=i.get("logger"),r=encodeURIComponent(i.req.query("message")||"");e.error(`Login error: ${r}`);const a=`${S.LOGIN}/?error=${encodeURIComponent(r)}`;return i.newResponse(null,301,{Location:a})}}function K(i){if(!i||!i.includes(S.MCP_CALLBACK))return null;try{const e=i.split("/"),r=e[e.length-1];if(r){const a=Buffer.from(r,"base64url").toString("utf-8");return JSON.parse(a).mcpSessionId||null}}catch{}return null}function Ue(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=se(e.req.query("state")),f=n.idpId,t=n.source==="mcp"||n.redirectTo&&typeof n.redirectTo=="string"&&n.redirectTo.includes(S.MCP_CALLBACK),c=t?K(typeof n.redirectTo=="string"?n.redirectTo:void 0):null,s=a?.[f];if(!$(s))return r.error("OIDC login error: missing OIDC provider config"),e.text("Forbidden",403);const d=await j(f,s);if(a&&!d.token_endpoint){const p="Invalid OIDC configuration: token_endpoint is required";return r.error(`OIDC login error: ${p}`),e.text(p,500)}try{const p=d.token_endpoint,l=e.req.query("code"),m=e.req.query("error");if(m)return t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:`OIDC error: ${m}`,error_details:e.req.query("error_description")||null}]),fe(e,i,{slug:"/"},403,"403OIDC");if(!l){const w="Code is expected but not present";return r.error(`OIDC login error: ${w}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const h=e.req.header("x-forwarded-host"),g=e.req.header("x-forwarded-proto")||"https",A=t&&typeof n.redirectUri=="string"?n.redirectUri:new URL(I(S.OIDC_CALLBACK),h?`${g}://${h}`:e.req.url).toString(),C=e.get("cookies")?.code_verifier,u=await re(p,l,A,s,{...s.tokenRequestCustomParams,...C?{code_verifier:C}:{}});if(u.error)return r.error(`Error from OIDC provider: "${u.error}"`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:`Token exchange error: ${u.error}`,error_details:u.error_description||null}]),e.text(`Forbidden: ${u.error_description||u.error}`,403);if(!u?.id_token){const w="No id_token, please, add openid to scopes";return r.error(`OIDC login error: ${w}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const{payload:o,header:U}=O.decode(u.id_token),J=U.alg===P.RS256;if(s.audience?.length&&![...b(o.aud||[]),...b(o[F]||[])].some(L=>s.audience?.includes(L))){const L="No valid audience found in id_token";return r.error(`OIDC login error: ${L}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:L,error_details:null}]),new Response(`Forbidden: ${L}`)}const E=J?u.id_token:await O.sign({...o,idpId:f},v,P.HS256);de(o)||r.warn("To display your username, the required 'email' or 'full_profile' scope must be added to the identity provider configuration");const D=s?.tokenExpirationTime?Date.now()+s.tokenExpirationTime*1e3:o.exp*1e3||Date.now()+B*1e3;if(s.introspectEndpoint){const w=await fetch(s.introspectEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({access_token:u.access_token})});if(w.ok){const T=(await w.json()).ext?.federatedIdentity;T&&(_(e,"federated_access_token",T.access_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}),_(e,"federated_id_token",T.id_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}))}else r.warn(`OIDC introspect error: ${w.statusText}`)}if(_(e,"authorization",E,{path:R()||"/",httpOnly:!0,expires:new Date(D)}),E!==u.id_token&&_(e,"idp_id_token",u.id_token||"",{path:R()||"/",httpOnly:!0,expires:new Date(D)}),_(e,"idp_access_token",u.access_token||"",{path:R()||"/",httpOnly:!0,expires:new Date(D)}),q(e,"code_verifier",{path:R()||"/"}),t&&n.redirectTo&&typeof n.redirectTo=="string"&&n.redirectTo.includes(S.MCP_CALLBACK)){const L=`${e.req.url.split("?")[0].replace(S.OIDC_CALLBACK,"")}${n.redirectTo}`;return e.newResponse(null,302,{Location:L})}const G=typeof n.redirectTo=="string"?n.redirectTo:void 0;let V=z(new URL(G||"/",e.req.url).pathname);const X=e.newResponse(null,302,{Location:V});return r.updateContext({email:o.email,subject:o.sub}),r.info("OIDC login successful"),X}catch(p){const l=p instanceof Error?p.message:String(p),m=p instanceof Error?p.stack:String(p);if(r.error(`OIDC login error: ${l}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:l,error_details:m}]),p.error==="access_denied")return r.info("Access denied"),e.text("Forbidden",403)}const y="Something went wrong";return r.error(`OIDC login error: ${y}`),t&&M.sendMcpAuthorizationFailedMessage([{...k(c),error:y,error_details:null}]),e.text(y,500)}}function Te(i){return async e=>{const r=e.get("logger"),n=e.get("auth").claims?.idpId,t=i.getConfig().ssoDirect?.[n];if(e.req.method==="POST")return $(t)||q(e,"authorization",{path:R()||"/"}),r.info("Logout successful"),e.newResponse(null,200,{});let c;if($(t)){const s=(await j(n,t)).end_session_endpoint;if(s){const d=new URL(e.req.url),y=e.req.header("x-forwarded-proto")||d.protocol.slice(0,-1)||"https",p=e.req.header("x-forwarded-host")||d.host,l=`${y}://${p}`,m=N(l),h=m?me(JSON.stringify({branch:N(l)})):void 0,g=m?`${pe(l)}/_auth/logout`:`${l}/post-logout`;c=ce(s,g,e.get("cookies")?.idp_id_token||e.get("cookies")?.authorization||"",h)}}return r.info("Logout successful"),q(e,"authorization",{path:R()||"/"}),e.newResponse(null,302,{Location:c||I("/")})}}function qe(i){return async e=>{const r=i.getConfig().logoutReturnUrl,a=r||I("/");return e.newResponse(null,302,{Location:a})}}function be(i){return async e=>{const r=e.get("logger"),a=e.req.param("code"),n=H.BH_API_URL,f=(t,c,s)=>t&&c?`${t} ${c.charAt(0)}`:s;try{if(!n)throw new Error("BH_API_URL is not set");const t=i.getConfig().ssoDirect;if(!t||!Object.keys(t).length)return r.warn("Invite no sso configured to handle"),e.redirect(I("/"));const c=await fetch(`${n}/user-invites/public/${a}`);if(!c.ok)return c.status===404?(r.warn(`Invite ${a} not found redirect to homepage`),e.redirect(I("/"))):(r.error("Invite error",await c.text()),e.redirect(I("/")));const s=await c.json(),d=new URL(I("/invite"),e.req.url);return d.searchParams.set("code",a),d.searchParams.set("org",s.organization.name),d.searchParams.set("invitedBy",f(s.invitedBy.firstName,s.invitedBy.lastName,s.invitedBy.name)),e.newResponse(null,302,{Location:d.toString()})}catch(t){return r.error("Error processing invite",{error:t,inviteCode:a}),e.text(t.message||"Failed to process invite",400)}}}function Ee(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=new URL(e.req.url),f=e.req.query("inviteCode"),t=e.req.header("x-forwarded-proto")||n.protocol.slice(0,-1)||"https",c=e.req.header("x-forwarded-host")||n.host,s=`${t}://${c}`;let d=n.searchParams.get("idpId");const y=n.searchParams.get("redirectTo"),p=Object.keys(a||{})[0];d=d||p;const l=n.searchParams.get("mcp_redirect_uri"),m=!!l;if(!a?.[d]){const o="Invalid idpId";if(r.error(`IdP login error: ${o}`),m){const U=K(y||void 0);M.sendMcpAuthorizationFailedMessage([{...k(U),error:o,error_details:null}])}return e.text(`Forbidden: ${o}`,403)}const g=d&&a?await x(d,a[d]):void 0,A={};for(const o of Object.keys(g?.extraParams||{}))A[o]=n.searchParams.get(o)||g?.extraParams?.[o]||void 0;let C,u={};if(m&&l&&g&&g.type===W.OIDC){r.info(`Building MCP OAuth login URL with redirect_uri: ${l}`);const o=ge("",{...g,extraParams:A},y,f,{redirectUriOverride:l,sourceOverride:"mcp",branchOverride:void 0});C=o.loginUrl,u=o.cookies||{}}else if(g){const o=oe({...g,extraParams:A},s,y,f);C=o.loginUrl,u=o.cookies||{}}return Object.keys(u).forEach(o=>{_(e,o,u[o].value,u[o].options)}),r.info(`IdP login initiated for ID '${d}'`),e.newResponse(null,302,{Location:C||new URL(e.req.url).pathname})}}function Fe(i){return async e=>{const r=e.get("logger"),a=await e.req.formData(),n=a.get("SAMLResponse"),f=a.get("RelayState");if(typeof n!="string"||typeof f!="string"){const o="SAMLResponse is required";return r.error(`SAML2 login error: ${o}`),e.text(`Bad request: ${o}`,400)}const t=ne(n),{success:c,uid:s,nameFormat:d,attrs:y,issuerId:p,expiresAt:l}=ie(t),{idpId:m,redirectTo:h}=JSON.parse(f);if(!c){const o="SAML2 assertion is not successful";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!l||Math.ceil(Date.now()/1e3)>=l){const o="SAML2 Token Expired";return r.error(`SAML2 login error: ${o}`),e.text(o,401)}const g=i.getConfig().ssoDirect?.[m];if(!g||!ee(g)){const o="Cannot find valid IdP";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!(g.issuerId&&p&&Y(g.issuerId,p))){const o="IssuerID is misconfigured or untrusted assertions issuer received";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!await ae(t,g.x509PublicCert)){const o="SAMLResponse signature invalid";return r.error(`SAML2 login error: ${o}`),e.text(o,401)}const C=te(s,d,y,g.teamsAttributeName);if(!C.sub){const o="The provider did not return a valid user identity.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}if(!C.email){const o="The provider did not return a valid user email.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}const u=await O.sign({...C,idpId:m},v,P.HS256);return _(e,"authorization",u,{path:R()||"/",httpOnly:!0,expires:new Date(l*1e3)}),r.updateContext({email:C.email,subject:C.sub}),r.info("SAML2 login successful"),e.newResponse(null,302,{Location:h||"/"})}}function Be(i){return async e=>{const r=e.get("logger"),a=new URL(e.req.query("redirectTo")||"/",e.req.url),n=I(z(a.pathname)),f=i.getConfig().ssoDirect,t=Object.entries(f||{}).find(([,h])=>$(h)&&ue(h));if(!(f&&t))return e.newResponse(null,302,{Location:n});const s=e.req.query("token"),d=s&&await le(s);if(!d)return e.newResponse(null,302,{Location:n});if(!b(d[F]||[]).some(h=>h===Q||h===Z))return e.newResponse(null,302,{Location:n});const l=await O.sign({...d,idpId:t?.at(0)},v,P.HS256),m=Date.now()+B*1e3;return _(e,"authorization",l,{path:R()||"/",httpOnly:!0,expires:new Date(m),sameSite:"None",secure:!0}),r.info("Token login successful"),e.newResponse(null,302,{Location:n})}}export{ve as authorizeHandler,Ee as idpLoginHandler,be as inviteHandler,Te as logoutHandler,Ue as oidcCallbackHandler,qe as postLogoutHandler,$e as redoclyLoginCallbackHandler,Be as redoclyTokenLoginHandler,Fe as samlCallbackHandler};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Context } from 'hono';
|
|
2
|
+
export declare function corsProxyHandler(proxyBasePath?: string): (ctx: Context) => Promise<Response>;
|
|
3
|
+
export declare function resolveCorsProxyTarget(requestUrl: string, proxyBasePath: string): URL | null;
|
|
4
|
+
export declare const CORS_PROXY_STREAM_HEADER = "x-redocly-proxy-streaming";
|
|
5
|
+
//# sourceMappingURL=cors-proxy.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{withPathPrefix as O}from"@redocly/theme/core/utils";import{ServerRoutes as _}from"../../../constants/common.js";import{getRequestOrigin as q}from"../utils/get-request-origin.js";const C=new Set(["connection","keep-alive","proxy-authenticate","proxy-connection","proxy-authorization","te","trailer","transfer-encoding","upgrade","host"]),P=new Set(["cookie","cookie2"]),T=new Set(["set-cookie","set-cookie2"]),E="x-redocly-proxy-streaming",H="x-http-method-override",w="x-redocly-cookie";function x(o=O(_.CORS_PROXY)){return async e=>{const r=new URL(e.req.url).pathname;if(r===o||r===`${o}/`)return e.text(`Realm CORS proxy endpoint.
|
|
2
|
+
Usage: ${o}/https://api.example.com/path`);const n=L(e.req.url,o);if(!n)return e.text("Invalid proxied URL",400);const i=q(e),c=n.origin===i,h=n.pathname===o||n.pathname.startsWith(`${o}/`);if(c&&!h)return new Response("Please use a direct request",{status:308,headers:{Location:n.toString(),Vary:"origin","Cache-Control":"private"}});const s=new Headers,f=S(e.req.raw.headers);for(const[t,y]of e.req.raw.headers)f.has(t.toLowerCase())||P.has(t.toLowerCase())||s.append(t,y);const d=s.get(w);if(d){const t=e.req.raw.headers.get("cookie")||"";s.set("cookie",t?`${t}; ${d}`:d),s.delete(w)}const u=e.req.raw.headers.get("origin")||"";A(u)&&s.delete("origin");let p=e.req.method;const m=s.get(H);m&&(p=m.toUpperCase(),s.delete(H));const R={method:p,headers:s,redirect:"follow"};p!=="GET"&&p!=="HEAD"&&e.req.raw.body&&(R.body=e.req.raw.body,R.duplex="half");let a;try{a=await fetch(n,R)}catch(t){return e.text(`Failed to proxy request: ${t instanceof Error?t.message:"unknown error"}`,502)}const l=new Headers(a.headers),g=S(a.headers);for(const t of g)l.delete(t);for(const t of T)l.delete(t);return l.set(E,"1"),new Response(a.body,{status:a.status,statusText:a.statusText,headers:l})}}function k(o){try{return decodeURIComponent(o)}catch{return o}}function D(o){return o.replace(/^(https?):\/(?!\/)/i,"$1://")}function $(o,e){return e?o.includes("?")?e==="?"?o:`${o.endsWith("?")||o.endsWith("&")?o:`${o}&`}${e.slice(1)}`:`${o}${e}`:o}function S(o){const e=new Set(C),r=o.get("connection");if(!r)return e;for(const n of r.split(",")){const i=n.trim().toLowerCase();i&&e.add(i)}return e}function A(o){const e=o.toLowerCase();return e.includes(".redocly.app")||e.includes("localhost")}function L(o,e){const r=new URL(o),n=r.pathname===e,i=r.pathname.startsWith(`${e}/`);if(!n&&!i)return null;const c=r.pathname.slice(e.length).replace(/^\/+/,"");if(!c)return null;const h=[c,k(c)];for(const s of h){const f=D(s),d=$(f,r.search);try{const u=new URL(d);if(u.protocol==="http:"||u.protocol==="https:")return u}catch{continue}}return null}const z=E;export{z as CORS_PROXY_STREAM_HEADER,x as corsProxyHandler,L as resolveCorsProxyTarget};
|