@redocly/reef 0.132.0-next.7 → 0.132.0-next.8

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.
@@ -1 +1 @@
1
- const e={"dev.newApp":"\u65B0\u5E94\u7528\u7A0B\u5E8F","dev.newApp.text":"\u521B\u5EFA\u60A8\u7684\u7B2C\u4E00\u4E2A\u5E94\u7528\u7A0B\u5E8F","dev.sidebar.header":"\u6211\u7684\u5E94\u7528\u7A0B\u5E8F","dev.sidebar.footer.text":"\u65B0\u5E94\u7528\u7A0B\u5E8F","dev.create.app.dialog.appName.placeholder":"\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0","dev.create.app.dialog.appName.error":"\u540D\u79F0\u5FC5\u987B\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u5E76\u4E14\u53EA\u80FD\u5305\u542B\uFF1A\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7A7A\u683C\u3001.\u3001_\u3001-\u3001$\u3001%\u3001#","dev.create.app.dialog.selectAPIs":"\u9009\u62E9 API","dev.create.app.dialog.description":"\u63CF\u8FF0","dev.create.app.dialog.description.placeholder":"\u7A7A","dev.create.app.dialog.create":"\u521B\u5EFA\u5E94\u7528\u7A0B\u5E8F","dev.create.app.dialog.cancel":"\u53D6\u6D88","dev.main.tab.appKeys":"API \u5BC6\u94A5","dev.main.tab.logs":"\u65E5\u5FD7","dev.app.description.title":"\u63CF\u8FF0","dev.edit.description.dialog.title":"\u66F4\u6539\u63CF\u8FF0","dev.edit.description.dialog.save":"\u4FDD\u5B58\u66F4\u6539","dev.edit.description.dialog.cancel":"\u53D6\u6D88","dev.edit.apis.dialog.selectedAPIs":"\u9009\u5B9A\u7684 API","dev.app.key.create":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.title":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.create":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.cancel":"\u53D6\u6D88","dev.app.edit":"\u7F16\u8F91","dev.app.delete":"\u5220\u9664","dev.edit.app.dialog.title":"\u66F4\u6539\u663E\u793A\u540D\u79F0","dev.edit.app.dialog.save":"\u4FDD\u5B58\u66F4\u6539","dev.edit.app.dialog.cancel":"\u53D6\u6D88","dev.delete.app.dialog.title":"\u5220\u9664\u5E94\u7528\u7A0B\u5E8F","dev.delete.app.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u5220\u9664\u6B64\u5E94\u7528\u7A0B\u5E8F\u5417\uFF1F","dev.delete.app.dialog.delete":"\u5220\u9664\u5E94\u7528\u7A0B\u5E8F","dev.delete.app.dialog.cancel":"\u53D6\u6D88","dev.app.key.roll":"\u8F6E\u6362 API \u5BC6\u94A5","dev.roll.key.dialog.title":"\u8F6E\u6362 API \u5BC6\u94A5","dev.roll.key.dialog.apiKey":"API key","dev.roll.key.dialog.expires":"\u5230\u671F","dev.roll.key.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u8F6E\u6362\u6B64 API \u5BC6\u94A5\u5417\uFF1F","dev.roll.key.dialog.cancel":"\u53D6\u6D88","dev.roll.key.dialog.roll":"\u8F6E\u6362 API \u5BC6\u94A5","dev.update.key.dialog.title":"\u66F4\u65B0\u5BC6\u94A5","dev.update.key.dialog.update":"\u66F4\u65B0\u5BC6\u94A5","dev.update.key.dialog.cancel":"\u53D6\u6D88","dev.app.key.api.name":"API \u540D\u79F0","dev.app.key.api.status":"\u72B6\u6001","dev.app.key.api.edit":"\u7F16\u8F91 API","dev.edit.apis.dialog.title":"\u7F16\u8F91 API","dev.edit.apis.dialog.apiKey":"API key","dev.edit.apis.dialog.save":"\u4FDD\u5B58","dev.edit.apis.dialog.cancel":"\u53D6\u6D88","dev.select.placeholder":"\u7A7A","dev.app.overview.status.pending":"\u5F85\u5904\u7406","dev.app.overview.status.approved":"\u5DF2\u6279\u51C6","dev.app.overview.status.revoked":"\u5DF2\u64A4\u9500","dev.app.overview.status":"\u72B6\u6001","dev.app.overview.non-production":"\u6D4B\u8BD5","dev.app.overview.production":"\u751F\u4EA7","dev.app.overview.clientId":"\u5BC6\u94A5","dev.app.overview.apiKey":"API key","dev.app.key.revoke":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.title":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.apiKey":"API key","dev.revoke.key.dialog.expires":"\u5230\u671F","dev.revoke.key.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u64A4\u9500\u6B64 API \u5BC6\u94A5\u5417\uFF1F","dev.revoke.key.dialog.revoke":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.cancel":"\u53D6\u6D88","dev.app.overview.expires":"\u5230\u671F","dev.app.overview.created":"\u5DF2\u521B\u5EFA","dev.app.overview.visibilityToggle.hide":"\u9690\u85CF","dev.app.overview.visibilityToggle.show":"\u663E\u793A","search.loading":"\u52A0\u8F7D\u4E2D...","search.noResults.title":"\u65E0\u7ED3\u679C","search.keys.navigate":"\u5BFC\u822A","search.keys.select":"\u9009\u62E9","search.keys.exit":"\u9000\u51FA","search.searchItem.deprecated":"\u5DF2\u5F03\u7528","search.label":"\u641C\u7D22\u6587\u6863...","search.cancel":"\u53D6\u6D88","search.recent":"\u6700\u8FD1\u641C\u7D22","search.navbar.label":"\u641C\u7D22","search.suggested":"\u5EFA\u8BAE\u9875\u9762","search.groups.all":"\u5168\u90E8","search.showMore":"\u663E\u793A\u66F4\u591A","search.filter.title":"\u9AD8\u7EA7\u7B5B\u9009","search.filter.reset":"\u91CD\u7F6E\u7B5B\u9009","search.filter.field.reset":"\u91CD\u7F6E","search.filter.field.footer":"\u641C\u7D22\u4EE5\u663E\u793A\u66F4\u591A\u9879\u76EE...","search.ai.newConversation":"\u65B0\u5BF9\u8BDD","search.ai.welcomeText":"\u6B22\u8FCE\u4F7F\u7528 AI \u641C\u7D22\uFF01\u60A8\u53EF\u4EE5\u95EE\u6211\u4EFB\u4F55\u95EE\u9898\u3002\u6211\u80FD\u4E3A\u60A8\u63D0\u4F9B\u4EC0\u4E48\u5E2E\u52A9\uFF1F","search.ai.placeholder":"\u63D0\u95EE...","search.ai.back":"\u8FD4\u56DE","search.ai.generatingResponse":"\u6B63\u5728\u751F\u6210\u56DE\u590D...","search.ai.followUpQuestion":"\u63D0\u51FA\u540E\u7EED\u95EE\u9898\uFF1F","search.ai.suggestionsTitle":"\u5EFA\u8BAE","search.ai.thinkingText":"\u601D\u8003\u4E2D...","search.ai.resourcesFound":"\u627E\u5230\u8D44\u6E90","search.ai.resourcesFound.basedOn":"\u57FA\u4E8E","search.ai.resourcesFound.resources":"\u8D44\u6E90","search.ai.toolCall.executed":"\u5DF2\u6267\u884C","search.ai.toolCall.executing":"\u6267\u884C\u4E2D","search.ai.toolCall.withArgs":"\u5E26\u53C2\u6570","search.ai.feedback.title":"\u60A8\u4E0D\u559C\u6B22\u6B64\u56DE\u590D\u7684\u54EA\u4E9B\u65B9\u9762\uFF1F","search.ai.feedback.detailsPlaceholder":"\u6DFB\u52A0\u5177\u4F53\u7EC6\u8282","search.ai.feedback.thanks":"\u611F\u8C22\u60A8\u7684\u53CD\u9988\uFF01","search.ai.feedback.more":"\u66F4\u591A...","search.ai.label":"\u8BE2\u95EE AI \u52A9\u624B","search.ai.button":"\u4F7F\u7528 AI \u641C\u7D22","search.ai.backToSearch":"\u8FD4\u56DE\u641C\u7D22","search.ai.assistant":"\u52A9\u624B","search.ai.disclaimer":"AI \u641C\u7D22\u53EF\u80FD\u63D0\u4F9B\u4E0D\u5B8C\u6574\u6216\u4E0D\u6B63\u786E\u7684\u7ED3\u679C\u3002\u8BF7\u6838\u5B9E\u91CD\u8981\u4FE1\u606F\u3002","search.ai.error.description":"\u6211\u4EEC\u5728\u5904\u7406\u60A8\u7684\u641C\u7D22\u65F6\u9047\u5230\u95EE\u9898\u3002\u8BF7\u7A0D\u540E\u518D\u8BD5\u6216\u4F18\u5316\u60A8\u7684\u67E5\u8BE2\u3002\u5982\u679C\u95EE\u9898\u4ECD\u7136\u5B58\u5728\uFF0C\u8BF7\u8054\u7CFB Redocly \u652F\u6301\u3002","search.ai.error.description.forbidden":"AI \u641C\u7D22\u5F53\u524D\u4E0D\u53EF\u7528\u3002","search.ai.error.description.unauthorized":"\u60A8\u65E0\u6743\u4F7F\u7528 AI \u641C\u7D22\u3002","search.ai.error.header":"\u54CE\u5440\uFF01\u51FA\u9519\u4E86\u3002","search.ai.error.header.forbidden":"\u529F\u80FD\u4E0D\u53EF\u7528","search.ai.error.header.unauthorized":"\u9700\u8981\u8EAB\u4EFD\u9A8C\u8BC1","aiAssistant.trigger":"\u8BE2\u95EE AI","toc.header":"\u5728\u672C\u9875","footer.copyrightText":"","page.homeButton":"\u8FD4\u56DE\u9996\u9875","page.forbidden.title":"\u7981\u6B62\u8BBF\u95EE","page.forbidden.description":"\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6B64\u9875\u9762\u3002\u5982\u679C\u60A8\u8BA4\u4E3A\u8FD9\u662F\u4E00\u4E2A\u9519\u8BEF\uFF0C\u8054\u7CFB\u60A8\u7684\u7BA1\u7406\u5458\u6216\u8FD4\u56DE\u9996\u9875\u3002","page.notFound.title":"\u5185\u5BB9\u4E22\u5931\u4E86...","page.notFound.description":"\u60A8\u5C1D\u8BD5\u8BBF\u95EE\u7684\u9875\u9762\u4E0D\u5B58\u5728\u6216\u53EF\u80FD\u5DF2\u88AB\u79FB\u52A8\u3002\u60A8\u53EF\u4EE5\u8FD4\u56DE\u4E0A\u4E00\u9875\u3001\u8FD4\u56DE\u9996\u9875\u6216\u4F7F\u7528\u641C\u7D22\u680F\u67E5\u627E\u6240\u9700\u5185\u5BB9\u3002","page.lastUpdated.timeago":"\u6700\u540E\u66F4\u65B0\u4E8E","page.lastUpdated.on":"\u6700\u540E\u66F4\u65B0\u4E8E","catalog.filters.title":"\u7B5B\u9009\u5668","catalog.filters.add":"\u6DFB\u52A0\u7B5B\u9009\u5668","catalog.filters.placeholder":"\u8F93\u5165\u4EE5\u7B5B\u9009...","catalog.filters.clearAll":"\u6E05\u9664\u6240\u6709\u7B5B\u9009\u5668","catalog.filters.select.addFilter":"\u6DFB\u52A0\u7B5B\u9009\u5668","catalog.filters.select.all":"\u5168\u90E8","catalog.filters.done":"\u5B8C\u6210","filter.dateRange.from":"\u4ECE:","filter.dateRange.to":"\u5230:","sidebar.menu.backLabel":"\u8FD4\u56DE","sidebar.menu.backToLabel":"\u8FD4\u56DE {{value}}","sidebar.actions.show":"\u663E\u793A\u4FA7\u8FB9\u680F","sidebar.actions.hide":"\u9690\u85CF\u4FA7\u8FB9\u680F","sidebar.actions.changeToSingleColumn":"\u5207\u6362\u5230\u5355\u5217","sidebar.actions.changeToTwoColumns":"\u5207\u6362\u5230\u53CC\u5217","sidebar.actions.singleColumn":"\u5355\u5217","sidebar.actions.twoColumns":"\u4E24\u5217","versionPicker.label":"\u7248\u672C\uFF1A","versionPicker.unversioned":"\u6240\u6709\u7248\u672C","codeSnippet.copy.buttonText":"\u5DF2\u590D\u5236\uFF01","codeSnippet.copy.tooltipText":"\u590D\u5236\u5230\u526A\u8D34\u677F","codeSnippet.copy.toasterText":"\u590D\u5236","codeSnippet.expand.tooltipText":"\u5168\u90E8\u5C55\u5F00","codeSnippet.collapse.tooltipText":"\u5168\u90E8\u6298\u53E0","markdown.editPage.text":"\u7F16\u8F91","feedback.settings.comment.submitText":"\u611F\u8C22\u60A8\u5E2E\u52A9\u6539\u8FDB\u6211\u4EEC\u7684\u6587\u6863\uFF01","feedback.settings.comment.label":"\u8BF7\u4E0E\u6211\u4EEC\u5206\u4EAB\u60A8\u7684\u53CD\u9988\u3002","feedback.settings.comment.send":"\u53D1\u9001","feedback.settings.comment.cancel":"\u53D6\u6D88","feedback.settings.comment.maxLength":"\u5DF2\u8FBE\u5230\u5185\u5BB9\u6700\u5927\u957F\u5EA6{{maxLength}}\u4E2A\u5B57\u7B26","feedback.settings.comment.satisfiedLabel":"\u6700\u6709\u5E2E\u52A9\u7684\u662F\u4EC0\u4E48\uFF1F","feedback.settings.comment.neutralLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.settings.comment.dissatisfiedLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.settings.submitText":"\u611F\u8C22\u60A8\u7684\u53CD\u9988\uFF01","feedback.settings.label":"\u8FD9\u6709\u5E2E\u52A9\u5417\uFF1F","feedback.settings.reasons.label":"\u54EA\u9879\u9648\u8FF0\u63CF\u8FF0\u4E86\u60A8\u5BF9\u6B64\u9875\u9762\u7684\u770B\u6CD5\uFF1F","feedback.submit":"\u63D0\u4EA4","feedback.cancel":"\u53D6\u6D88","feedback.settings.comment.likeLabel":"\u6700\u6709\u5E2E\u52A9\u7684\u662F\u4EC0\u4E48\uFF1F","feedback.settings.comment.dislikeLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.sentiment.thumbUp":"\u8D5E","feedback.sentiment.thumbDown":"\u8E29","feedback.settings.leftScaleLabel":"\u5B8C\u5168\u6CA1\u6709\u5E2E\u52A9","feedback.settings.rightScaleLabel":"\u975E\u5E38\u6709\u5E2E\u52A9","feedback.settings.optionalEmail.label":"\u60A8\u7684\u7535\u5B50\u90AE\u4EF6\uFF08\u53EF\u9009\uFF0C\u7528\u4E8E\u8DDF\u8FDB\uFF09","feedback.settings.optionalEmail.placeholder":"yourname@example.com","codeSnippet.report.buttonText":"\u62A5\u544A","codeSnippet.report.tooltipText":"\u62A5\u544A\u95EE\u9898","codeSnippet.report.label":"\u6B64\u4EE3\u7801\u6709\u4EC0\u4E48\u95EE\u9898\uFF1F","userMenu.login":"\u767B\u5F55","userMenu.logout":"\u6CE8\u9500","userMenu.devOnboardingLabel":"\u6211\u7684\u5E94\u7528\u7A0B\u5E8F","mobileMenu.mainMenu":"\u4E3B\u83DC\u5355","mobileMenu.previous":"\u4E0A\u4E00\u6B65","mobileMenu.products":"\u4EA7\u54C1","mobileMenu.version":"\u7248\u672C","page.nextButton":"\u4E0B\u4E00\u9875","page.previousButton":"\u4E0A\u4E00\u9875","page.actions.copyButtonText":"\u590D\u5236","page.actions.copyTitle":"\u4E3A LLM \u590D\u5236","page.actions.copyDescription":"\u5C06\u9875\u9762\u590D\u5236\u4E3A LLM \u7684 Markdown \u683C\u5F0F","page.actions.viewAsMdButtonText":"\u67E5\u770B Markdown","page.actions.viewAsMdTitle":"\u67E5\u770B Markdown","page.actions.viewAsMdDescription":"\u4EE5 Markdown \u683C\u5F0F\u6253\u5F00\u6B64\u9875\u9762","page.actions.chatGptButtonText":"\u5728 ChatGPT \u4E2D\u6253\u5F00","page.actions.chatGptTitle":"\u5728 ChatGPT \u4E2D\u6253\u5F00","page.actions.chatGptDescription":"\u4ECE ChatGPT \u83B7\u53D6\u89C1\u89E3","page.actions.claudeButtonText":"\u5728 Claude \u4E2D\u6253\u5F00","page.actions.claudeTitle":"\u5728 Claude \u4E2D\u6253\u5F00","page.actions.claudeDescription":"\u4ECE Claude \u83B7\u53D6\u89C1\u89E3","page.actions.cursorMcpButtonText":"\u8FDE\u63A5\u5230 Cursor","page.actions.cursorMcpTitle":"\u8FDE\u63A5\u5230 Cursor","page.actions.cursorMcpDescription":"\u5728 Cursor \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp":"\u8FDE\u63A5 MCP","page.actions.connectMcp.cursor":"\u8FDE\u63A5\u5230 Cursor","page.actions.connectMcp.cursorDescription":"\u5728 Cursor \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp.vscode":"\u8FDE\u63A5\u5230 VS Code","page.actions.connectMcp.vscodeDescription":"\u5728 VS Code \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp.copyConfig":"\u590D\u5236 MCP \u914D\u7F6E","page.actions.connectMcp.copyConfigDescription":"\u590D\u5236 MCP JSON \u914D\u7F6E","navbar.products":"\u4EA7\u54C1","openapi.download.description.title":"\u4E0B\u8F7D OpenAPI \u63CF\u8FF0","openapi.info.title":"\u6982\u8FF0","openapi.info.contact.url":"URL","openapi.info.contact.name":"\u7535\u5B50\u90AE\u4EF6","openapi.info.license":"\u8BB8\u53EF\u8BC1","openapi.info.termsOfService":"\u670D\u52A1\u6761\u6B3E","openapi.info.metadata.title":"\u5143\u6570\u636E","button.copy.tooltipText":"\u590D\u5236\u5230\u526A\u8D34\u677F","button.download.tooltipText":"\u4E0B\u8F7D\u63CF\u8FF0","button.externalLink.tooltipText":"\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00","button.email.tooltipText":"\u53D1\u9001\u90AE\u4EF6","openapi.key":"\u952E","openapi.value":"\u503C","openapi.enum":"\u679A\u4E3E","openapi.items":"\u9879","openapi.default":"\u9ED8\u8BA4\u503C","openapi.variable":"\u53D8\u91CF","openapi.variables":"\u53D8\u91CF","openapi.actions.show":"\u663E\u793A","openapi.actions.hide":"\u9690\u85CF","openapi.actions.more":"\u66F4\u591A","openapi.languages.title":"\u8BED\u8A00","openapi.languages.moreButton.tooltipText":"\u67E5\u770B\u66F4\u591A\u8BED\u8A00","openapi.servers.title":"\u670D\u52A1\u5668","openapi.operations":"\u64CD\u4F5C","openapi.webhooks":"Webhook","openapi.description":"\u63CF\u8FF0","openapi.badges.deprecated":"\u5DF2\u5F03\u7528","openapi.badges.required":"\u5FC5\u9700","openapi.badges.webhook":"Webhook","openapi.request":"\u8BF7\u6C42","openapi.path":"\u8DEF\u5F84","openapi.query":"\u67E5\u8BE2","openapi.cookie":"Cookie","openapi.header":"\u6807\u5934","openapi.body":"\u6B63\u6587","openapi.responses":"\u54CD\u5E94","openapi.response":"\u54CD\u5E94","openapi.callbacks":"\u56DE\u8C03","openapi.callbackRequest":"\u56DE\u8C03\u8BF7\u6C42","openapi.callbackResponse":"\u56DE\u8C03\u54CD\u5E94","openapi.payload":"\u8BF7\u6C42\u4F53","openapi.discriminator":"\u9274\u522B\u5668","openapi.contentType":"\u5185\u5BB9\u7C7B\u578B","openapi.tryIt":"\u8BD5\u7528","openapi.loading":"\u52A0\u8F7D\u4E2D...","openapi.example":"\u793A\u4F8B","openapi.examples":"\u793A\u4F8B","openapi.additionalProperties":"\u9644\u52A0\u5C5E\u6027","openapi.patternProperties":"\u6A21\u5F0F\u5C5E\u6027","openapi.required":"\u5FC5\u9700","openapi.recursive":"\u9012\u5F52","openapi.complex":"\u590D\u6742","openapi.hideExample":"\u9690\u85CF\u793A\u4F8B","openapi.showExample":"\u663E\u793A\u793A\u4F8B","openapi.expandAll":"\u5168\u90E8\u5C55\u5F00","openapi.collapseAll":"\u5168\u90E8\u6298\u53E0","openapi.viewSecurityDetails":"\u67E5\u770B\u5B89\u5168\u8BE6\u60C5","openapi.noResponseExample":"\u65E0\u54CD\u5E94\u793A\u4F8B","openapi.discriminator.searchPlaceholder":"\u641C\u7D22\u9879\u76EE","openapi.discriminator.searchNoResults":"\u672A\u627E\u5230\u9879\u76EE","openapi.discriminator.defaultMapping":"\u9ED8\u8BA4\u6620\u5C04","openapi.discriminator.defaultMappingTooltip":"OpenAPI 3.2\uFF1A\u5F53\u5176\u4ED6\u6620\u5C04\u4E0D\u5339\u914D\u65F6\u4F7F\u7528\u9ED8\u8BA4\u6620\u5C04\u3002","openapi.noResponseContent":"\u65E0\u5185\u5BB9","openapi.noRequestPayload":"\u65E0\u8BF7\u6C42\u6709\u6548\u8D1F\u8F7D","openapi.hidePattern":"\u9690\u85CF\u6A21\u5F0F","openapi.showPattern":"\u663E\u793A\u6A21\u5F0F","openapi.authorizationUrl":"\u6388\u6743 URL","openapi.tokenUrl":"\u4EE4\u724C URL","openapi.refreshUrl":"\u5237\u65B0 URL","openapi.showOptionalScopes":"\u663E\u793A\u53EF\u9009\u8303\u56F4","openapi.hideOptionalScopes":"\u9690\u85CF\u53EF\u9009\u8303\u56F4","openapi.security":"\u5B89\u5168","openapi.httpAuthorizationScheme":"HTTP \u6388\u6743\u65B9\u6848","openapi.bearerFormat":"Bearer \u683C\u5F0F","openapi.parameterName":"\u53C2\u6570\u540D\u79F0","openapi.flowType":"\u6D41\u7C7B\u578B","openapi.connectUrl":"\u8FDE\u63A5 URL","openapi.requiredScopes":"\u5FC5\u9700\u8303\u56F4","openapi.unsupportedLanguage":"\u4E0D\u652F\u6301\u8BE5\u8BED\u8A00\u3002","openapi.failedToGenerateCodeSample":"\u65E0\u6CD5\u751F\u6210\u4EE3\u7801\u793A\u4F8B\u3002","openapi.schemaCatalogLink.title":"\u5171\u4EAB\u67B6\u6784","openapi.schemaCatalogLink.copyButtonTooltip":"\u590D\u5236\u5230\u526A\u8D34\u677F","openapi.schemaCatalogLink.copiedTooltip":"\u5DF2\u590D\u5236\uFF01","openapi.mcp.title":"MCP server","openapi.mcp.endpoint":"Endpoint","openapi.mcp.tools":"MCP \u5DE5\u5177","openapi.mcp.protocolVersion":"\u534F\u8BAE\u7248\u672C","openapi.mcp.capabilities":"\u80FD\u529B","openapi.mcp.experimentalCapabilities":"\u5B9E\u9A8C\u6027\u80FD\u529B","openapi.mcp.inputSchema":"\u8F93\u5165\u67B6\u6784","openapi.mcp.inputExample":"\u8F93\u5165\u793A\u4F8B","openapi.mcp.outputSchema":"\u8F93\u51FA\u67B6\u6784","openapi.mcp.outputExample":"\u8F93\u51FA\u793A\u4F8B","asyncapi.download.description.title":"\u4E0B\u8F7D AsyncAPI \u63CF\u8FF0","asyncapi.info.title":"\u6982\u8FF0","graphql.download.description.title":"\u4E0B\u8F7D GraphQL \u67B6\u6784","graphql.info.title":"\u6982\u8FF0","graphql.info.contact.url":"URL","graphql.info.contact.name":"\u7535\u5B50\u90AE\u4EF6","graphql.info.license":"\u8BB8\u53EF\u8BC1","graphql.info.termsOfService":"\u670D\u52A1\u6761\u6B3E","graphql.overview":"GraphQL \u6982\u8FF0","graphql.metadata":"\u5143\u6570\u636E","graphql.key":"\u952E","graphql.value":"\u503C","graphql.queries":"\u67E5\u8BE2","graphql.mutations":"\u53D8\u66F4","graphql.subscriptions":"\u8BA2\u9605","graphql.directives":"\u6307\u4EE4","graphql.objects":"\u5BF9\u8C61","graphql.interfaces":"\u63A5\u53E3","graphql.unions":"\u8054\u5408","graphql.enums":"\u679A\u4E3E","graphql.inputs":"\u8F93\u5165","graphql.scalars":"\u6807\u91CF","graphql.arguments.label":"\u53C2\u6570","graphql.arguments.show":"\u663E\u793A\u53C2\u6570","graphql.arguments.hide":"\u9690\u85CF\u53C2\u6570","graphql.arguments.here":"\u53C2\u6570\u5728\u6B64","graphql.returnTypes.label":"\u7ED3\u679C\u7C7B\u578B","graphql.returnTypes.show":"\u663E\u793A\u7ED3\u679C\u7C7B\u578B","graphql.returnTypes.hide":"\u9690\u85CF\u7ED3\u679C\u7C7B\u578B","graphql.possibleTypes":"\u53EF\u80FD\u7684\u7C7B\u578B","graphql.defaultValue":"\u9ED8\u8BA4\u503C","graphql.deprecationReason":"\u5F03\u7528\u539F\u56E0","graphql.requiredScopes":"\u5FC5\u9700\u8303\u56F4","graphql.viewSecurityDetails":"\u67E5\u770B\u8BE6\u7EC6\u4FE1\u606F","graphql.objectScopes":"\u5BF9\u8C61\u8303\u56F4","graphql.fieldScopes":"\u5B57\u6BB5\u8303\u56F4","graphql.implementedInterfaces":"\u5B9E\u73B0\u7684\u63A5\u53E3","graphql.nonNull":"\u975E\u7A7A","graphql.required":"\u5FC5\u9700","graphql.deprecated":"\u5DF2\u5F03\u7528","graphql.variables":"\u53D8\u91CF","graphql.querySample":"\u67E5\u8BE2\u793A\u4F8B","graphql.mutationSample":"\u53D8\u66F4\u793A\u4F8B","graphql.subscriptionSample":"\u8BA2\u9605\u793A\u4F8B","graphql.responseSample":"\u54CD\u5E94\u793A\u4F8B","graphql.locations":"\u4F4D\u7F6E","graphql.sample":"\u793A\u4F8B","graphql.referenced":"\u5F15\u7528\u4F4D\u7F6E","graphql.content.fragment":"\u7247\u6BB5","codeWalkthrough.preview":"\u9884\u89C8","codeWalkthrough.download":"\u4E0B\u8F7D","time.justNow":"\u521A\u624D","time.past.second":"1 \u79D2\u524D","time.past.seconds":"{{value}} \u79D2\u524D","time.past.minute":"1 \u5206\u949F\u524D","time.past.minutes":"{{value}} \u5206\u949F\u524D","time.past.hour":"1 \u5C0F\u65F6\u524D","time.past.hours":"{{value}} \u5C0F\u65F6\u524D","time.past.day":"1 \u5929\u524D","time.past.days":"{{value}} \u5929\u524D","time.past.week":"1 \u5468\u524D","time.past.weeks":"{{value}} \u5468\u524D","time.past.month":"1 \u4E2A\u6708\u524D","time.past.months":"{{value}} \u4E2A\u6708\u524D","time.past.year":"1 \u5E74\u524D","time.past.years":"{{value}} \u5E74\u524D","page.internalServerError.title":"\u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF","page.internalServerError.description":"\u6211\u4EEC\u7684\u670D\u52A1\u5668\u51FA\u9519\u4E86\u3002\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF0C\u5982\u679C\u95EE\u9898\u4ECD\u7136\u5B58\u5728\uFF0C\u8BF7\u8054\u7CFB\u652F\u6301\u4EBA\u5458\u3002","page.skipToContent.label":"\u8DF3\u8F6C\u5230\u5185\u5BB9","catalog.catalogs.label":"\u76EE\u5F55","catalog.catalogs.all.title":"\u5168\u90E8","catalog.catalogs.all.description":"\u6240\u6709\u5B9E\u4F53","catalog.catalogs.all.switcherLabel":"\u5168\u90E8","catalog.catalogs.service.title":"\u670D\u52A1","catalog.catalogs.service.description":"\u670D\u52A1\u5B9E\u4F53","catalog.catalogs.service.switcherLabel":"\u670D\u52A1","catalog.catalogs.user.title":"\u7528\u6237","catalog.catalogs.user.description":"\u7528\u6237\u5B9E\u4F53","catalog.catalogs.user.switcherLabel":"\u7528\u6237","catalog.catalogs.team.title":"\u56E2\u961F","catalog.catalogs.team.description":"\u56E2\u961F\u5B9E\u4F53","catalog.catalogs.team.switcherLabel":"\u56E2\u961F","catalog.catalogs.domain.title":"\u57DF","catalog.catalogs.domain.description":"\u57DF\u5B9E\u4F53","catalog.catalogs.domain.switcherLabel":"\u57DF","catalog.catalogs.apiDescription.title":"API \u63CF\u8FF0","catalog.catalogs.apiDescription.description":"API \u63CF\u8FF0\u5B9E\u4F53","catalog.catalogs.apiDescription.switcherLabel":"API \u63CF\u8FF0","catalog.catalogs.dataSchema.title":"\u6570\u636E\u6A21\u5F0F","catalog.catalogs.dataSchema.description":"\u6570\u636E\u6A21\u5F0F\u5B9E\u4F53","catalog.catalogs.dataSchema.switcherLabel":"\u6570\u636E\u6A21\u5F0F","catalog.catalogs.apiOperation.title":"API \u64CD\u4F5C","catalog.catalogs.apiOperation.description":"API \u64CD\u4F5C\u5B9E\u4F53","catalog.catalogs.apiOperation.switcherLabel":"API \u64CD\u4F5C","catalog.entity.metadata.title":"\u5143\u6570\u636E","catalog.entity.schema.title":"\u6A21\u5F0F","catalog.entity.properties.apiDescription.title":"API \u63CF\u8FF0","catalog.backToAllLabel":"\u76EE\u5F55","catalog.notConnected":"\u672A\u8FDE\u63A5","catalog.tags.label":"\u6807\u7B7E","catalog.tags.more":"\u66F4\u591A","catalog.owners.label":"\u6240\u6709\u8005","catalog.repositories.label":"\u4ED3\u5E93","catalog.email.label":"\u7535\u5B50\u90AE\u4EF6","catalog.format.label":"\u683C\u5F0F","catalog.entityType.label":"\u5B9E\u4F53\u7C7B\u578B","catalog.domains.label":"\u57DF","catalog.contact.label":"Slack \u9891\u9053","catalog.methodAndPath.label":"\u65B9\u6CD5\u548C\u8DEF\u5F84","catalog.links.label":"\u94FE\u63A5","catalog.metadata.domains":"\u57DF:","catalog.metadata.owners":"\u6240\u6709\u8005:","catalog.sort":"\u6392\u5E8F","catalog.history.button.label":"\u7248\u672C\u5386\u53F2","catalog.history.sidebar.title":"\u7248\u672C\u5386\u53F2","catalog.history.sidebar.close":"\u5173\u95ED\u7248\u672C\u5386\u53F2","catalog.history.version.label":"\u7248\u672C","catalog.filters.close":"\u5173\u95ED","catalog.history.version.notSpecified":"\u672A\u6307\u5B9A","catalog.history.version.default":"\u9ED8\u8BA4","catalog.history.revisions.limitMessage":"\u4E0D\u5B58\u50A8\u8F83\u65E7\u7684\u4FEE\u8BA2\u7248\u672C\u3002","catalog.history.revision.current":"\u5F53\u524D","catalog.history.revisions.showLess":"\u663E\u793A\u66F4\u5C11","catalog.history.revisions.showMore":"\u663E\u793A\u66F4\u591A{{count}}\u9879","select.noResults":"\u65E0\u7ED3\u679C","loaders.loading":"\u52A0\u8F7D\u4E2D...","diagram.openFullscreen":"\u70B9\u51FB\u5168\u5C4F\u67E5\u770B\u56FE\u8868","diagram.zoomIn":"\u653E\u5927","diagram.zoomOut":"\u7F29\u5C0F","diagram.reset":"\u9002\u5E94\u7A97\u53E3","diagram.close":"\u5173\u95ED","diagram.viewer":"\u56FE\u8868\u67E5\u770B\u5668"};export{e as zh};
1
+ const e={"dev.newApp":"\u65B0\u5E94\u7528\u7A0B\u5E8F","dev.newApp.text":"\u521B\u5EFA\u60A8\u7684\u7B2C\u4E00\u4E2A\u5E94\u7528\u7A0B\u5E8F","dev.sidebar.header":"\u6211\u7684\u5E94\u7528\u7A0B\u5E8F","dev.sidebar.footer.text":"\u65B0\u5E94\u7528\u7A0B\u5E8F","dev.create.app.dialog.appName.placeholder":"\u5E94\u7528\u7A0B\u5E8F\u540D\u79F0","dev.create.app.dialog.appName.error":"\u540D\u79F0\u5FC5\u987B\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u5E76\u4E14\u53EA\u80FD\u5305\u542B\uFF1A\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7A7A\u683C\u3001.\u3001_\u3001-\u3001$\u3001%\u3001#","dev.create.app.dialog.selectAPIs":"\u9009\u62E9 API","dev.create.app.dialog.description":"\u63CF\u8FF0","dev.create.app.dialog.description.placeholder":"\u7A7A","dev.create.app.dialog.create":"\u521B\u5EFA\u5E94\u7528\u7A0B\u5E8F","dev.create.app.dialog.cancel":"\u53D6\u6D88","dev.main.tab.appKeys":"API \u5BC6\u94A5","dev.main.tab.logs":"\u65E5\u5FD7","dev.app.description.title":"\u63CF\u8FF0","dev.edit.description.dialog.title":"\u66F4\u6539\u63CF\u8FF0","dev.edit.description.dialog.save":"\u4FDD\u5B58\u66F4\u6539","dev.edit.description.dialog.cancel":"\u53D6\u6D88","dev.edit.apis.dialog.selectedAPIs":"\u9009\u5B9A\u7684 API","dev.app.key.create":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.title":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.create":"\u521B\u5EFA\u5BC6\u94A5","dev.create.key.dialog.cancel":"\u53D6\u6D88","dev.app.edit":"\u7F16\u8F91","dev.app.delete":"\u5220\u9664","dev.edit.app.dialog.title":"\u66F4\u6539\u663E\u793A\u540D\u79F0","dev.edit.app.dialog.save":"\u4FDD\u5B58\u66F4\u6539","dev.edit.app.dialog.cancel":"\u53D6\u6D88","dev.delete.app.dialog.title":"\u5220\u9664\u5E94\u7528\u7A0B\u5E8F","dev.delete.app.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u5220\u9664\u6B64\u5E94\u7528\u7A0B\u5E8F\u5417\uFF1F","dev.delete.app.dialog.delete":"\u5220\u9664\u5E94\u7528\u7A0B\u5E8F","dev.delete.app.dialog.cancel":"\u53D6\u6D88","dev.app.key.roll":"\u8F6E\u6362 API \u5BC6\u94A5","dev.roll.key.dialog.title":"\u8F6E\u6362 API \u5BC6\u94A5","dev.roll.key.dialog.apiKey":"API key","dev.roll.key.dialog.expires":"\u5230\u671F","dev.roll.key.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u8F6E\u6362\u6B64 API \u5BC6\u94A5\u5417\uFF1F","dev.roll.key.dialog.cancel":"\u53D6\u6D88","dev.roll.key.dialog.roll":"\u8F6E\u6362 API \u5BC6\u94A5","dev.update.key.dialog.title":"\u66F4\u65B0\u5BC6\u94A5","dev.update.key.dialog.update":"\u66F4\u65B0\u5BC6\u94A5","dev.update.key.dialog.cancel":"\u53D6\u6D88","dev.app.key.api.name":"API \u540D\u79F0","dev.app.key.api.status":"\u72B6\u6001","dev.app.key.api.edit":"\u7F16\u8F91 API","dev.edit.apis.dialog.title":"\u7F16\u8F91 API","dev.edit.apis.dialog.apiKey":"API key","dev.edit.apis.dialog.save":"\u4FDD\u5B58","dev.edit.apis.dialog.cancel":"\u53D6\u6D88","dev.select.placeholder":"\u7A7A","dev.app.overview.status.pending":"\u5F85\u5904\u7406","dev.app.overview.status.approved":"\u5DF2\u6279\u51C6","dev.app.overview.status.revoked":"\u5DF2\u64A4\u9500","dev.app.overview.status":"\u72B6\u6001","dev.app.overview.non-production":"\u6D4B\u8BD5","dev.app.overview.production":"\u751F\u4EA7","dev.app.overview.clientId":"\u5BC6\u94A5","dev.app.overview.apiKey":"API key","dev.app.key.revoke":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.title":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.apiKey":"API key","dev.revoke.key.dialog.expires":"\u5230\u671F","dev.revoke.key.dialog.confirmation":"\u60A8\u786E\u5B9A\u8981\u64A4\u9500\u6B64 API \u5BC6\u94A5\u5417\uFF1F","dev.revoke.key.dialog.revoke":"\u64A4\u9500 API \u5BC6\u94A5","dev.revoke.key.dialog.cancel":"\u53D6\u6D88","dev.app.overview.expires":"\u5230\u671F","dev.app.overview.created":"\u5DF2\u521B\u5EFA","dev.app.overview.visibilityToggle.hide":"\u9690\u85CF","dev.app.overview.visibilityToggle.show":"\u663E\u793A","search.loading":"\u52A0\u8F7D\u4E2D...","search.noResults.title":"\u65E0\u7ED3\u679C","search.keys.navigate":"\u5BFC\u822A","search.keys.select":"\u9009\u62E9","search.keys.exit":"\u9000\u51FA","search.searchItem.deprecated":"\u5DF2\u5F03\u7528","search.label":"\u641C\u7D22\u6587\u6863...","search.cancel":"\u53D6\u6D88","search.recent":"\u6700\u8FD1\u641C\u7D22","search.navbar.label":"\u641C\u7D22","search.suggested":"\u5EFA\u8BAE\u9875\u9762","search.groups.all":"\u5168\u90E8","search.showMore":"\u663E\u793A\u66F4\u591A","search.filter.title":"\u9AD8\u7EA7\u7B5B\u9009","search.filter.reset":"\u91CD\u7F6E\u7B5B\u9009","search.filter.field.reset":"\u91CD\u7F6E","search.filter.field.footer":"\u641C\u7D22\u4EE5\u663E\u793A\u66F4\u591A\u9879\u76EE...","search.ai.newConversation":"\u65B0\u5BF9\u8BDD","search.ai.welcomeText":"\u6B22\u8FCE\u4F7F\u7528 AI \u641C\u7D22\uFF01\u60A8\u53EF\u4EE5\u95EE\u6211\u4EFB\u4F55\u95EE\u9898\u3002\u6211\u80FD\u4E3A\u60A8\u63D0\u4F9B\u4EC0\u4E48\u5E2E\u52A9\uFF1F","search.ai.placeholder":"\u63D0\u95EE...","search.ai.back":"\u8FD4\u56DE","search.ai.generatingResponse":"\u6B63\u5728\u751F\u6210\u56DE\u590D...","search.ai.followUpQuestion":"\u63D0\u51FA\u540E\u7EED\u95EE\u9898\uFF1F","search.ai.suggestionsTitle":"\u5EFA\u8BAE","search.ai.thinkingText":"\u601D\u8003\u4E2D...","search.ai.resourcesFound":"\u627E\u5230\u8D44\u6E90","search.ai.resourcesFound.basedOn":"\u57FA\u4E8E","search.ai.resourcesFound.resources":"\u8D44\u6E90","search.ai.toolCall.executed":"\u5DF2\u6267\u884C","search.ai.toolCall.executing":"\u6267\u884C\u4E2D","search.ai.toolCall.withArgs":"\u5E26\u53C2\u6570","search.ai.feedback.title":"\u60A8\u4E0D\u559C\u6B22\u6B64\u56DE\u590D\u7684\u54EA\u4E9B\u65B9\u9762\uFF1F","search.ai.feedback.detailsPlaceholder":"\u6DFB\u52A0\u5177\u4F53\u7EC6\u8282","search.ai.feedback.thanks":"\u611F\u8C22\u60A8\u7684\u53CD\u9988\uFF01","search.ai.feedback.more":"\u66F4\u591A...","search.ai.label":"\u8BE2\u95EE AI \u52A9\u624B","search.ai.button":"\u4F7F\u7528 AI \u641C\u7D22","search.ai.backToSearch":"\u8FD4\u56DE\u641C\u7D22","search.ai.assistant":"\u52A9\u624B","search.ai.disclaimer":"AI \u641C\u7D22\u53EF\u80FD\u63D0\u4F9B\u4E0D\u5B8C\u6574\u6216\u4E0D\u6B63\u786E\u7684\u7ED3\u679C\u3002\u8BF7\u6838\u5B9E\u91CD\u8981\u4FE1\u606F\u3002","search.ai.error.description":"\u6211\u4EEC\u5728\u5904\u7406\u60A8\u7684\u641C\u7D22\u65F6\u9047\u5230\u95EE\u9898\u3002\u8BF7\u7A0D\u540E\u518D\u8BD5\u6216\u4F18\u5316\u60A8\u7684\u67E5\u8BE2\u3002\u5982\u679C\u95EE\u9898\u4ECD\u7136\u5B58\u5728\uFF0C\u8BF7\u8054\u7CFB Redocly \u652F\u6301\u3002","search.ai.error.description.forbidden":"AI \u641C\u7D22\u5F53\u524D\u4E0D\u53EF\u7528\u3002","search.ai.error.description.unauthorized":"\u60A8\u65E0\u6743\u4F7F\u7528 AI \u641C\u7D22\u3002","search.ai.error.header":"\u54CE\u5440\uFF01\u51FA\u9519\u4E86\u3002","search.ai.error.header.forbidden":"\u529F\u80FD\u4E0D\u53EF\u7528","search.ai.error.header.unauthorized":"\u9700\u8981\u8EAB\u4EFD\u9A8C\u8BC1","aiAssistant.trigger":"\u8BE2\u95EE AI","toc.header":"\u5728\u672C\u9875","footer.copyrightText":"","page.homeButton":"\u8FD4\u56DE\u9996\u9875","page.forbidden.title":"\u7981\u6B62\u8BBF\u95EE","page.forbidden.description":"\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6B64\u9875\u9762\u3002\u5982\u679C\u60A8\u8BA4\u4E3A\u8FD9\u662F\u4E00\u4E2A\u9519\u8BEF\uFF0C\u8054\u7CFB\u60A8\u7684\u7BA1\u7406\u5458\u6216\u8FD4\u56DE\u9996\u9875\u3002","page.notFound.title":"\u5185\u5BB9\u4E22\u5931\u4E86...","page.notFound.description":"\u60A8\u5C1D\u8BD5\u8BBF\u95EE\u7684\u9875\u9762\u4E0D\u5B58\u5728\u6216\u53EF\u80FD\u5DF2\u88AB\u79FB\u52A8\u3002\u60A8\u53EF\u4EE5\u8FD4\u56DE\u4E0A\u4E00\u9875\u3001\u8FD4\u56DE\u9996\u9875\u6216\u4F7F\u7528\u641C\u7D22\u680F\u67E5\u627E\u6240\u9700\u5185\u5BB9\u3002","page.lastUpdated.timeago":"\u6700\u540E\u66F4\u65B0\u4E8E","page.lastUpdated.on":"\u6700\u540E\u66F4\u65B0\u4E8E","catalog.filters.title":"\u7B5B\u9009\u5668","catalog.filters.add":"\u6DFB\u52A0\u7B5B\u9009\u5668","catalog.filters.placeholder":"\u8F93\u5165\u4EE5\u7B5B\u9009...","catalog.filters.clearAll":"\u6E05\u9664\u6240\u6709\u7B5B\u9009\u5668","catalog.filters.select.addFilter":"\u6DFB\u52A0\u7B5B\u9009\u5668","catalog.filters.select.all":"\u5168\u90E8","catalog.filters.done":"\u5B8C\u6210","filter.dateRange.from":"\u4ECE:","filter.dateRange.to":"\u5230:","sidebar.menu.backLabel":"\u8FD4\u56DE","sidebar.menu.backToLabel":"\u8FD4\u56DE {{value}}","sidebar.actions.show":"\u663E\u793A\u4FA7\u8FB9\u680F","sidebar.actions.hide":"\u9690\u85CF\u4FA7\u8FB9\u680F","sidebar.actions.changeToSingleColumn":"\u5207\u6362\u5230\u5355\u5217","sidebar.actions.changeToTwoColumns":"\u5207\u6362\u5230\u53CC\u5217","sidebar.actions.singleColumn":"\u5355\u5217","sidebar.actions.twoColumns":"\u4E24\u5217","versionPicker.label":"\u7248\u672C\uFF1A","versionPicker.unversioned":"\u6240\u6709\u7248\u672C","codeSnippet.copy.buttonText":"\u5DF2\u590D\u5236\uFF01","codeSnippet.copy.tooltipText":"\u590D\u5236\u5230\u526A\u8D34\u677F","codeSnippet.copy.toasterText":"\u590D\u5236","codeSnippet.expand.tooltipText":"\u5168\u90E8\u5C55\u5F00","codeSnippet.collapse.tooltipText":"\u5168\u90E8\u6298\u53E0","markdown.editPage.text":"\u7F16\u8F91","feedback.settings.comment.submitText":"\u611F\u8C22\u60A8\u5E2E\u52A9\u6539\u8FDB\u6211\u4EEC\u7684\u6587\u6863\uFF01","feedback.settings.comment.label":"\u8BF7\u4E0E\u6211\u4EEC\u5206\u4EAB\u60A8\u7684\u53CD\u9988\u3002","feedback.settings.comment.send":"\u53D1\u9001","feedback.settings.comment.cancel":"\u53D6\u6D88","feedback.settings.comment.maxLength":"\u5DF2\u8FBE\u5230\u5185\u5BB9\u6700\u5927\u957F\u5EA6{{maxLength}}\u4E2A\u5B57\u7B26","feedback.settings.comment.satisfiedLabel":"\u6700\u6709\u5E2E\u52A9\u7684\u662F\u4EC0\u4E48\uFF1F","feedback.settings.comment.neutralLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.settings.comment.dissatisfiedLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.settings.submitText":"\u611F\u8C22\u60A8\u7684\u53CD\u9988\uFF01","feedback.settings.label":"\u8FD9\u6709\u5E2E\u52A9\u5417\uFF1F","feedback.settings.reasons.label":"\u54EA\u9879\u9648\u8FF0\u63CF\u8FF0\u4E86\u60A8\u5BF9\u6B64\u9875\u9762\u7684\u770B\u6CD5\uFF1F","feedback.submit":"\u63D0\u4EA4","feedback.cancel":"\u53D6\u6D88","feedback.settings.comment.likeLabel":"\u6700\u6709\u5E2E\u52A9\u7684\u662F\u4EC0\u4E48\uFF1F","feedback.settings.comment.dislikeLabel":"\u6211\u4EEC\u53EF\u4EE5\u6539\u8FDB\u4EC0\u4E48\uFF1F","feedback.sentiment.thumbUp":"\u8D5E","feedback.sentiment.thumbDown":"\u8E29","feedback.settings.leftScaleLabel":"\u5B8C\u5168\u6CA1\u6709\u5E2E\u52A9","feedback.settings.rightScaleLabel":"\u975E\u5E38\u6709\u5E2E\u52A9","feedback.settings.optionalEmail.label":"\u60A8\u7684\u7535\u5B50\u90AE\u4EF6\uFF08\u53EF\u9009\uFF0C\u7528\u4E8E\u8DDF\u8FDB\uFF09","feedback.settings.optionalEmail.placeholder":"yourname@example.com","codeSnippet.report.buttonText":"\u62A5\u544A","codeSnippet.report.tooltipText":"\u62A5\u544A\u95EE\u9898","codeSnippet.report.label":"\u6B64\u4EE3\u7801\u6709\u4EC0\u4E48\u95EE\u9898\uFF1F","userMenu.login":"\u767B\u5F55","userMenu.logout":"\u6CE8\u9500","userMenu.devOnboardingLabel":"\u6211\u7684\u5E94\u7528\u7A0B\u5E8F","mobileMenu.mainMenu":"\u4E3B\u83DC\u5355","mobileMenu.previous":"\u4E0A\u4E00\u6B65","mobileMenu.products":"\u4EA7\u54C1","mobileMenu.version":"\u7248\u672C","page.nextButton":"\u4E0B\u4E00\u9875","page.previousButton":"\u4E0A\u4E00\u9875","page.actions.copyButtonText":"\u590D\u5236","page.actions.copyTitle":"\u4E3A LLM \u590D\u5236","page.actions.copyDescription":"\u5C06\u9875\u9762\u590D\u5236\u4E3A LLM \u7684 Markdown \u683C\u5F0F","page.actions.viewAsMdButtonText":"\u67E5\u770B Markdown","page.actions.viewAsMdTitle":"\u67E5\u770B Markdown","page.actions.viewAsMdDescription":"\u4EE5 Markdown \u683C\u5F0F\u6253\u5F00\u6B64\u9875\u9762","page.actions.chatGptButtonText":"\u5728 ChatGPT \u4E2D\u6253\u5F00","page.actions.chatGptTitle":"\u5728 ChatGPT \u4E2D\u6253\u5F00","page.actions.chatGptDescription":"\u4ECE ChatGPT \u83B7\u53D6\u89C1\u89E3","page.actions.claudeButtonText":"\u5728 Claude \u4E2D\u6253\u5F00","page.actions.claudeTitle":"\u5728 Claude \u4E2D\u6253\u5F00","page.actions.claudeDescription":"\u4ECE Claude \u83B7\u53D6\u89C1\u89E3","page.actions.cursorMcpButtonText":"\u8FDE\u63A5\u5230 Cursor","page.actions.cursorMcpTitle":"\u8FDE\u63A5\u5230 Cursor","page.actions.cursorMcpDescription":"\u5728 Cursor \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp":"\u8FDE\u63A5 MCP","page.actions.connectMcp.cursor":"\u8FDE\u63A5\u5230 Cursor","page.actions.connectMcp.cursorDescription":"\u5728 Cursor \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp.vscode":"\u8FDE\u63A5\u5230 VS Code","page.actions.connectMcp.vscodeDescription":"\u5728 VS Code \u4E0A\u5B89\u88C5 MCP \u670D\u52A1\u5668","page.actions.connectMcp.copyConfig":"\u590D\u5236 MCP \u914D\u7F6E","page.actions.connectMcp.copyConfigDescription":"\u590D\u5236 MCP JSON \u914D\u7F6E","navbar.products":"\u4EA7\u54C1","openapi.download.description.title":"\u4E0B\u8F7D OpenAPI \u63CF\u8FF0","openapi.info.title":"\u6982\u8FF0","openapi.info.contact.url":"URL","openapi.info.contact.name":"\u7535\u5B50\u90AE\u4EF6","openapi.info.license":"\u8BB8\u53EF\u8BC1","openapi.info.termsOfService":"\u670D\u52A1\u6761\u6B3E","openapi.info.metadata.title":"\u5143\u6570\u636E","button.copy.tooltipText":"\u590D\u5236\u5230\u526A\u8D34\u677F","button.download.tooltipText":"\u4E0B\u8F7D\u63CF\u8FF0","button.externalLink.tooltipText":"\u5728\u65B0\u6807\u7B7E\u9875\u4E2D\u6253\u5F00","button.email.tooltipText":"\u53D1\u9001\u90AE\u4EF6","openapi.key":"\u952E","openapi.value":"\u503C","openapi.enum":"\u679A\u4E3E","openapi.items":"\u9879","openapi.default":"\u9ED8\u8BA4\u503C","openapi.variable":"\u53D8\u91CF","openapi.variables":"\u53D8\u91CF","openapi.actions.show":"\u663E\u793A","openapi.actions.hide":"\u9690\u85CF","openapi.actions.more":"\u66F4\u591A","openapi.languages.title":"\u8BED\u8A00","openapi.languages.moreButton.tooltipText":"\u67E5\u770B\u66F4\u591A\u8BED\u8A00","openapi.servers.title":"\u670D\u52A1\u5668","openapi.operations":"\u64CD\u4F5C","openapi.webhooks":"Webhook","openapi.description":"\u63CF\u8FF0","openapi.badges.deprecated":"\u5DF2\u5F03\u7528","openapi.badges.required":"\u5FC5\u9700","openapi.badges.webhook":"Webhook","openapi.request":"\u8BF7\u6C42","openapi.path":"\u8DEF\u5F84","openapi.query":"\u67E5\u8BE2","openapi.cookie":"Cookie","openapi.header":"\u6807\u5934","openapi.body":"\u6B63\u6587","openapi.responses":"\u54CD\u5E94","openapi.response":"\u54CD\u5E94","openapi.callbacks":"\u56DE\u8C03","openapi.callbackRequest":"\u56DE\u8C03\u8BF7\u6C42","openapi.callbackResponse":"\u56DE\u8C03\u54CD\u5E94","openapi.payload":"\u8BF7\u6C42\u4F53","openapi.discriminator":"\u9274\u522B\u5668","openapi.contentType":"\u5185\u5BB9\u7C7B\u578B","openapi.tryIt":"\u8BD5\u7528","openapi.loading":"\u52A0\u8F7D\u4E2D...","openapi.example":"\u793A\u4F8B","openapi.examples":"\u793A\u4F8B","openapi.additionalProperties":"\u9644\u52A0\u5C5E\u6027","openapi.patternProperties":"\u6A21\u5F0F\u5C5E\u6027","openapi.required":"\u5FC5\u9700","openapi.recursive":"\u9012\u5F52","openapi.complex":"\u590D\u6742","openapi.hideExample":"\u9690\u85CF\u793A\u4F8B","openapi.showExample":"\u663E\u793A\u793A\u4F8B","openapi.expandAll":"\u5168\u90E8\u5C55\u5F00","openapi.collapseAll":"\u5168\u90E8\u6298\u53E0","openapi.viewSecurityDetails":"\u67E5\u770B\u5B89\u5168\u8BE6\u60C5","openapi.noResponseExample":"\u65E0\u54CD\u5E94\u793A\u4F8B","openapi.discriminator.searchPlaceholder":"\u641C\u7D22\u9879\u76EE","openapi.discriminator.searchNoResults":"\u672A\u627E\u5230\u9879\u76EE","openapi.discriminator.defaultMapping":"\u9ED8\u8BA4\u6620\u5C04","openapi.discriminator.defaultMappingTooltip":"OpenAPI 3.2\uFF1A\u5F53\u5176\u4ED6\u6620\u5C04\u4E0D\u5339\u914D\u65F6\u4F7F\u7528\u9ED8\u8BA4\u6620\u5C04\u3002","openapi.noResponseContent":"\u65E0\u5185\u5BB9","openapi.noRequestPayload":"\u65E0\u8BF7\u6C42\u6709\u6548\u8D1F\u8F7D","openapi.hidePattern":"\u9690\u85CF\u6A21\u5F0F","openapi.showPattern":"\u663E\u793A\u6A21\u5F0F","openapi.authorizationUrl":"\u6388\u6743 URL","openapi.tokenUrl":"\u4EE4\u724C URL","openapi.refreshUrl":"\u5237\u65B0 URL","openapi.showOptionalScopes":"\u663E\u793A\u53EF\u9009\u8303\u56F4","openapi.hideOptionalScopes":"\u9690\u85CF\u53EF\u9009\u8303\u56F4","openapi.security":"\u5B89\u5168","openapi.httpAuthorizationScheme":"HTTP \u6388\u6743\u65B9\u6848","openapi.bearerFormat":"Bearer \u683C\u5F0F","openapi.parameterName":"\u53C2\u6570\u540D\u79F0","openapi.flowType":"\u6D41\u7C7B\u578B","openapi.connectUrl":"\u8FDE\u63A5 URL","openapi.requiredScopes":"\u5FC5\u9700\u8303\u56F4","openapi.unsupportedLanguage":"\u4E0D\u652F\u6301\u8BE5\u8BED\u8A00\u3002","openapi.failedToGenerateCodeSample":"\u65E0\u6CD5\u751F\u6210\u4EE3\u7801\u793A\u4F8B\u3002","openapi.schemaCatalogLink.title":"\u5171\u4EAB\u67B6\u6784","openapi.schemaCatalogLink.copyButtonTooltip":"\u590D\u5236\u5230\u526A\u8D34\u677F","openapi.schemaCatalogLink.copiedTooltip":"\u5DF2\u590D\u5236\uFF01","openapi.mcp.title":"MCP server","openapi.mcp.endpoint":"Endpoint","openapi.mcp.tools":"MCP \u5DE5\u5177","openapi.mcp.protocolVersion":"\u534F\u8BAE\u7248\u672C","openapi.mcp.capabilities":"\u80FD\u529B","openapi.mcp.experimentalCapabilities":"\u5B9E\u9A8C\u6027\u80FD\u529B","openapi.mcp.inputSchema":"\u8F93\u5165\u67B6\u6784","openapi.mcp.inputExample":"\u8F93\u5165\u793A\u4F8B","openapi.mcp.outputSchema":"\u8F93\u51FA\u67B6\u6784","openapi.mcp.outputExample":"\u8F93\u51FA\u793A\u4F8B","asyncapi.download.description.title":"\u4E0B\u8F7D AsyncAPI \u63CF\u8FF0","asyncapi.info.title":"\u6982\u8FF0","graphql.download.description.title":"\u4E0B\u8F7D GraphQL \u67B6\u6784","graphql.info.title":"\u6982\u8FF0","graphql.info.contact.url":"URL","graphql.info.contact.name":"\u7535\u5B50\u90AE\u4EF6","graphql.info.license":"\u8BB8\u53EF\u8BC1","graphql.info.termsOfService":"\u670D\u52A1\u6761\u6B3E","graphql.overview":"GraphQL \u6982\u8FF0","graphql.metadata":"\u5143\u6570\u636E","graphql.key":"\u952E","graphql.value":"\u503C","graphql.queries":"\u67E5\u8BE2","graphql.mutations":"\u53D8\u66F4","graphql.subscriptions":"\u8BA2\u9605","graphql.directives":"\u6307\u4EE4","graphql.objects":"\u5BF9\u8C61","graphql.interfaces":"\u63A5\u53E3","graphql.unions":"\u8054\u5408","graphql.enums":"\u679A\u4E3E","graphql.inputs":"\u8F93\u5165","graphql.scalars":"\u6807\u91CF","graphql.arguments.label":"\u53C2\u6570","graphql.arguments.show":"\u663E\u793A\u53C2\u6570","graphql.arguments.hide":"\u9690\u85CF\u53C2\u6570","graphql.arguments.here":"\u53C2\u6570\u5728\u6B64","graphql.returnTypes.label":"\u7ED3\u679C\u7C7B\u578B","graphql.returnTypes.show":"\u663E\u793A\u7ED3\u679C\u7C7B\u578B","graphql.returnTypes.hide":"\u9690\u85CF\u7ED3\u679C\u7C7B\u578B","graphql.possibleTypes":"\u53EF\u80FD\u7684\u7C7B\u578B","graphql.defaultValue":"\u9ED8\u8BA4\u503C","graphql.deprecationReason":"\u5F03\u7528\u539F\u56E0","graphql.requiredScopes":"\u5FC5\u9700\u8303\u56F4","graphql.viewSecurityDetails":"\u67E5\u770B\u8BE6\u7EC6\u4FE1\u606F","graphql.objectScopes":"\u5BF9\u8C61\u8303\u56F4","graphql.fieldScopes":"\u5B57\u6BB5\u8303\u56F4","graphql.implementedInterfaces":"\u5B9E\u73B0\u7684\u63A5\u53E3","graphql.nonNull":"\u975E\u7A7A","graphql.required":"\u5FC5\u9700","graphql.deprecated":"\u5DF2\u5F03\u7528","graphql.variables":"\u53D8\u91CF","graphql.querySample":"\u67E5\u8BE2\u793A\u4F8B","graphql.mutationSample":"\u53D8\u66F4\u793A\u4F8B","graphql.subscriptionSample":"\u8BA2\u9605\u793A\u4F8B","graphql.responseSample":"\u54CD\u5E94\u793A\u4F8B","graphql.locations":"\u4F4D\u7F6E","graphql.sample":"\u793A\u4F8B","graphql.referenced":"\u5F15\u7528\u4F4D\u7F6E","graphql.content.fragment":"\u7247\u6BB5","codeWalkthrough.preview":"\u9884\u89C8","codeWalkthrough.download":"\u4E0B\u8F7D","time.justNow":"\u521A\u624D","time.past.second":"1 \u79D2\u524D","time.past.seconds":"{{value}} \u79D2\u524D","time.past.minute":"1 \u5206\u949F\u524D","time.past.minutes":"{{value}} \u5206\u949F\u524D","time.past.hour":"1 \u5C0F\u65F6\u524D","time.past.hours":"{{value}} \u5C0F\u65F6\u524D","time.past.day":"1 \u5929\u524D","time.past.days":"{{value}} \u5929\u524D","time.past.week":"1 \u5468\u524D","time.past.weeks":"{{value}} \u5468\u524D","time.past.month":"1 \u4E2A\u6708\u524D","time.past.months":"{{value}} \u4E2A\u6708\u524D","time.past.year":"1 \u5E74\u524D","time.past.years":"{{value}} \u5E74\u524D","page.internalServerError.title":"\u5185\u90E8\u670D\u52A1\u5668\u9519\u8BEF","page.internalServerError.description":"\u6211\u4EEC\u7684\u670D\u52A1\u5668\u51FA\u9519\u4E86\u3002\u8BF7\u7A0D\u540E\u518D\u8BD5\uFF0C\u5982\u679C\u95EE\u9898\u4ECD\u7136\u5B58\u5728\uFF0C\u8BF7\u8054\u7CFB\u652F\u6301\u4EBA\u5458\u3002","page.skipToContent.label":"\u8DF3\u8F6C\u5230\u5185\u5BB9","catalog.catalogs.label":"\u76EE\u5F55","catalog.catalogs.all.title":"\u5168\u90E8","catalog.catalogs.all.description":"\u6240\u6709\u5B9E\u4F53","catalog.catalogs.all.switcherLabel":"\u5168\u90E8","catalog.catalogs.service.title":"\u670D\u52A1","catalog.catalogs.service.description":"\u670D\u52A1\u5B9E\u4F53","catalog.catalogs.service.switcherLabel":"\u670D\u52A1","catalog.catalogs.user.title":"\u7528\u6237","catalog.catalogs.user.description":"\u7528\u6237\u5B9E\u4F53","catalog.catalogs.user.switcherLabel":"\u7528\u6237","catalog.catalogs.team.title":"\u56E2\u961F","catalog.catalogs.team.description":"\u56E2\u961F\u5B9E\u4F53","catalog.catalogs.team.switcherLabel":"\u56E2\u961F","catalog.catalogs.domain.title":"\u57DF","catalog.catalogs.domain.description":"\u57DF\u5B9E\u4F53","catalog.catalogs.domain.switcherLabel":"\u57DF","catalog.catalogs.apiDescription.title":"API \u63CF\u8FF0","catalog.catalogs.apiDescription.description":"API \u63CF\u8FF0\u5B9E\u4F53","catalog.catalogs.apiDescription.switcherLabel":"API \u63CF\u8FF0","catalog.catalogs.dataSchema.title":"\u6570\u636E\u6A21\u5F0F","catalog.catalogs.dataSchema.description":"\u6570\u636E\u6A21\u5F0F\u5B9E\u4F53","catalog.catalogs.dataSchema.switcherLabel":"\u6570\u636E\u6A21\u5F0F","catalog.catalogs.apiOperation.title":"API \u64CD\u4F5C","catalog.catalogs.apiOperation.description":"API \u64CD\u4F5C\u5B9E\u4F53","catalog.catalogs.apiOperation.switcherLabel":"API \u64CD\u4F5C","catalog.entity.metadata.title":"\u5143\u6570\u636E","catalog.entity.schema.title":"\u6A21\u5F0F","catalog.entity.properties.apiDescription.title":"API \u63CF\u8FF0","catalog.backToAllLabel":"\u76EE\u5F55","catalog.notConnected":"\u672A\u8FDE\u63A5","catalog.tags.label":"\u6807\u7B7E","catalog.owners.label":"\u6240\u6709\u8005","catalog.repositories.label":"\u4ED3\u5E93","catalog.email.label":"\u7535\u5B50\u90AE\u4EF6","catalog.format.label":"\u683C\u5F0F","catalog.entityType.label":"\u5B9E\u4F53\u7C7B\u578B","catalog.domains.label":"\u57DF","catalog.contact.label":"Slack \u9891\u9053","catalog.methodAndPath.label":"\u65B9\u6CD5\u548C\u8DEF\u5F84","catalog.links.label":"\u94FE\u63A5","catalog.metadata.domains":"\u57DF:","catalog.metadata.owners":"\u6240\u6709\u8005:","catalog.sort":"\u6392\u5E8F","catalog.history.button.label":"\u7248\u672C\u5386\u53F2","catalog.history.sidebar.title":"\u7248\u672C\u5386\u53F2","catalog.history.sidebar.close":"\u5173\u95ED\u7248\u672C\u5386\u53F2","catalog.history.version.label":"\u7248\u672C","catalog.filters.close":"\u5173\u95ED","catalog.history.version.notSpecified":"\u672A\u6307\u5B9A","catalog.history.version.default":"\u9ED8\u8BA4","catalog.history.revisions.limitMessage":"\u4E0D\u5B58\u50A8\u8F83\u65E7\u7684\u4FEE\u8BA2\u7248\u672C\u3002","catalog.history.revision.current":"\u5F53\u524D","catalog.history.revisions.showLess":"\u663E\u793A\u66F4\u5C11","catalog.history.revisions.showMore":"\u663E\u793A\u66F4\u591A{{count}}\u9879","select.noResults":"\u65E0\u7ED3\u679C","loaders.loading":"\u52A0\u8F7D\u4E2D...","diagram.openFullscreen":"\u70B9\u51FB\u5168\u5C4F\u67E5\u770B\u56FE\u8868","diagram.zoomIn":"\u653E\u5927","diagram.zoomOut":"\u7F29\u5C0F","diagram.reset":"\u9002\u5E94\u7A97\u53E3","diagram.close":"\u5173\u95ED","diagram.viewer":"\u56FE\u8868\u67E5\u770B\u5668"};export{e as zh};
@@ -1 +1 @@
1
- import{readEnvVariable as u}from"../utils/envs/read-env-variable.js";import{envSchema as c}from"./env-schema.js";function r(){const n=Object.fromEntries(Object.keys(process.env).map(e=>[e,u(e)]));return n.REDOCLY_PORTAL_VERSION=process.env.REDOCLY_PORTAL_VERSION,c.parse(n)}function o(){return r().REDOCLY_ENV??"development"}function i(){const n=process.env.REDOCLY_EXECUTION_MODE;return n==="build"||n==="develop"||n==="runtime"?n:"develop"}function s(){const e=r().REDOCLY_INTERNAL_DEV;return e==="true"||e==="1"}function v(){return r().REDOCLY_LOG_FORMAT}function d(n){switch(n){case"logFormat":return v();case"redoclyEnv":return o();case"executionMode":return i();case"isProductionEnv":return o()==="production";case"isPreviewEnv":return o()==="preview";case"isReunite":{const e=o(),t=s();return e==="production"||e==="preview"||e==="development"&&!t}case"isBuildMode":return i()==="build";case"isDevelopMode":return i()==="develop";case"isRuntimeMode":return i()==="runtime";default:return n}}const a=new Set(["logFormat","redoclyEnv","executionMode","isProductionEnv","isPreviewEnv","isReunite","isBuildMode","isDevelopMode","isRuntimeMode"]),p=Object.freeze(new Proxy({},{get(n,e){if(typeof e!="string")return;const t=e;return a.has(t)?d(t):r()[e]}}));export{p as envConfig};
1
+ import{readEnvVariable as c}from"../utils/envs/read-env-variable.js";import{envSchema as s}from"./env-schema.js";function t(){const n=Object.fromEntries(Object.keys(process.env).map(e=>[e,c(e)]));return n.REDOCLY_PORTAL_VERSION=process.env.REDOCLY_PORTAL_VERSION,s.parse(n)}function o(){return t().REDOCLY_ENV??"development"}function i(){const n=process.env.REDOCLY_EXECUTION_MODE;return n==="build"||n==="develop"||n==="runtime"?n:"develop"}function v(){const e=t().REDOCLY_INTERNAL_DEV;return e==="true"||e==="1"}function d(){return t().REDOCLY_LOG_FORMAT}function a(n){switch(n){case"logFormat":return d();case"redoclyEnv":return o();case"executionMode":return i();case"isProductionEnv":return o()==="production";case"isPreviewEnv":return o()==="preview";case"isReunite":{const e=o(),r=v(),u=t().REDOCLY_ORG_ID;return e==="production"||e==="preview"||e==="development"&&!r&&!!u}case"isBuildMode":return i()==="build";case"isDevelopMode":return i()==="develop";case"isRuntimeMode":return i()==="runtime";default:return n}}const E=new Set(["logFormat","redoclyEnv","executionMode","isProductionEnv","isPreviewEnv","isReunite","isBuildMode","isDevelopMode","isRuntimeMode"]),R=Object.freeze(new Proxy({},{get(n,e){if(typeof e!="string")return;const r=e;return E.has(r)?a(r):t()[e]}}));export{R as envConfig};
@@ -1 +1 @@
1
- import{normalizeRouteSlug as r}from"../../../utils/path/normalize-route-slug.js";function d(o){const t={};return Object.keys(o).forEach(e=>{const i=(e.endsWith("*")?e:r(e)).toLowerCase(),n=o[e]?.to?.toLowerCase();t[i]={...o[e],to:n}}),t}export{d as normalizeRedirectSources};
1
+ import{normalizeRouteSlug as t}from"../../../utils/path/normalize-route-slug.js";function a(o){const i={};return Object.keys(o).forEach(e=>{const r=(e.endsWith("*")?e:t(e)).toLowerCase();i[r]=o[e]}),i}export{a as normalizeRedirectSources};
@@ -1 +1 @@
1
- import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as F,GRAPHQL_SPEC_SLUG as T,GRAPHQL_TEMPLATE_ID as d,OPENAPI_DOCS_TEMPLATE_ID as v}from"../../../../constants/common.js";import{isLocalLink as U}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as P}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as y}from"../../../../utils/path/remove-fragment.js";import{PUBLIC_API_DEFINITIONS_FOLDER as C,DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as M}from"../../../constants/common.js";import{getInnerText as N}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as W}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{MdResolveError as g}from"./md-resolve-error.js";import{getLinkOriginalAttrName as B}from"./utils.js";import{isOpenApiURL as j}from"../../openapi-docs/is-openapi-doc.js";import{parseBaseName as G}from"../../utils.js";import{isMarkdownPage as $}from"../is-markdown-page.js";import{copyStaticFile as H}from"../../../utils/fs.js";const V=i=>[C,M,T].some(r=>i.startsWith(r));async function lt(i,r,k,{actions:L,context:c}){const{contentDir:w,outdir:D,getRouteByFsPath:A,slugHasRouteOrRedirect:E}=L,_=B(r),s=i[_]||W(i,r);if(i[_]=s,!U(s)||V(s))return;const[b,t="",R,h]=/^([^\?#]+)?([^#]+)?(.+)?/.exec(s)||[],f=i.type==="image"?"IMAGE":"LINK",u=String(i.attributes.title||i.attributes.alt||N([i])||""),n=y(k);if(i.type!=="image"){const{isOpenapiDetected:e,isOpenapiValid:m}=await j(t,n,L,c);if(e&&!m)throw new g(`OpenAPI route ${s} does not exist`,{rawLink:s,link:t,title:u,brokenLinkType:f})}if(o.extname(t)===""){if(t.startsWith("/")){if(!E(P(t)))throw new g(`Route ${t} does not exist`,{rawLink:s,link:t,title:u,brokenLinkType:f});p(i,r,t+(R||"")+(h||""))}if(!s.startsWith("#")&&!t.startsWith("/")&&$(n)){const e=A(n)?.slug;if(!e)return;const{isIndexFile:m}=G(n),I=m?P(o.posix.join(e,t)):P(o.posix.join(e,"../",t));if(!E(P(I)))throw new g(`Route ${t} does not exist`,{rawLink:s,link:I,title:u,brokenLinkType:f});p(i,r,I+(R||"")+(h||""))}return}const a=t.startsWith("/")?t.substring(1):o.posix.join(o.posix.dirname(n),decodeURI(t)),O=t.startsWith("/")?o.posix.join("static",t.substring(1)):"",x=c.fs.exists(a),S=c.fs.exists(O),l=A(a);if(!x&&!l&&!S)throw p(i,r,"#"),new g(`File ${a} does not exist`,{rawLink:s,link:a,title:u,brokenLinkType:f});if(l){const e=[v,d,F].includes(l.templateId);p(i,r,(e?l.baseSlug:l.slug)+(h||""))}else if(x){const e=c.fs.getFileInfo(a);if(!e||e.isVirtual)return;const m=await H(w,e.realRelativePath,D);p(i,r,m)}}export{lt as resolveLink};
1
+ import o from"node:path";import{ASYNC_API_DOCS_TEMPLATE_ID as F,GRAPHQL_SPEC_SLUG as T,GRAPHQL_TEMPLATE_ID as d,OPENAPI_DOCS_TEMPLATE_ID as v}from"../../../../constants/common.js";import{isLocalLink as y}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as P}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as U}from"../../../../utils/path/remove-fragment.js";import{PUBLIC_API_DEFINITIONS_FOLDER as C,DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as B}from"../../../constants/common.js";import{getInnerText as M}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as N}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{MdResolveError as g}from"./md-resolve-error.js";import{getLinkOriginalAttrName as W}from"./utils.js";import{isOpenApiURL as j}from"../../openapi-docs/is-openapi-doc.js";import{parseBaseName as G}from"../../utils.js";import{isMarkdownPage as $}from"../is-markdown-page.js";import{copyStaticFile as V}from"../../../utils/fs.js";const b=i=>[C,B,T].some(r=>i.startsWith(r));async function lt(i,r,k,{actions:L,context:c}){const{contentDir:w,outdir:D,getRouteByFsPath:A,hasRouteOrRedirectBySlug:E}=L,_=W(r),s=i[_]||N(i,r);if(i[_]=s,!y(s)||b(s))return;const[z,t="",R,h]=/^([^\?#]+)?([^#]+)?(.+)?/.exec(s)||[],f=i.type==="image"?"IMAGE":"LINK",u=String(i.attributes.title||i.attributes.alt||M([i])||""),n=U(k);if(i.type!=="image"){const{isOpenapiDetected:e,isOpenapiValid:m}=await j(t,n,L,c);if(e&&!m)throw new g(`OpenAPI route ${s} does not exist`,{rawLink:s,link:t,title:u,brokenLinkType:f})}if(o.extname(t)===""){if(t.startsWith("/")){if(!E(P(t)))throw new g(`Route ${t} does not exist`,{rawLink:s,link:t,title:u,brokenLinkType:f});p(i,r,t+(R||"")+(h||""))}if(!s.startsWith("#")&&!t.startsWith("/")&&$(n)){const e=A(n)?.slug;if(!e)return;const{isIndexFile:m}=G(n),I=m?P(o.posix.join(e,t)):P(o.posix.join(e,"../",t));if(!E(P(I)))throw new g(`Route ${t} does not exist`,{rawLink:s,link:I,title:u,brokenLinkType:f});p(i,r,I+(R||"")+(h||""))}return}const a=t.startsWith("/")?t.substring(1):o.posix.join(o.posix.dirname(n),decodeURI(t)),S=t.startsWith("/")?o.posix.join("static",t.substring(1)):"",x=c.fs.exists(a),O=c.fs.exists(S),l=A(a);if(!x&&!l&&!O)throw p(i,r,"#"),new g(`File ${a} does not exist`,{rawLink:s,link:a,title:u,brokenLinkType:f});if(l){const e=[v,d,F].includes(l.templateId);p(i,r,(e?l.baseSlug:l.slug)+(h||""))}else if(x){const e=c.fs.getFileInfo(a);if(!e||e.isVirtual)return;const m=await V(w,e.realRelativePath,D);p(i,r,m)}}export{lt as resolveLink};
@@ -157,7 +157,7 @@ export declare class Store {
157
157
  getRouteBySlug: (slug: string, opts?: {
158
158
  followRedirect?: boolean;
159
159
  }) => PageRouteDetails | undefined;
160
- slugHasRouteOrRedirect: (slug: string) => boolean;
160
+ hasRouteOrRedirectBySlug: (slug: string) => boolean;
161
161
  getRoutesByTemplateId: (templateId: string) => PageRouteInit[];
162
162
  getAllRoutesForLocale: (locale?: string) => PageRouteDetails[];
163
163
  getAllRoutes: () => PageRouteDetails[];
@@ -1 +1 @@
1
- import A from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}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 h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as S}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as u}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 G}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}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 R}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 J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as q}from"./utils/redirects/find-redirect.js";import{followRedirectChain as x}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as W}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",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map"},m="markdown/partials",z="markdown/partials-deps",E="PLAN_GATES",Y=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Tt="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=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;mcpToolHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},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:s,serverMode:e=!1,serverOutDir:a}){this.#r=s,this.outdir=t,this.serverMode=e,this.serverOutDir=a,this.userCodeReady=new Promise(r=>{this.#a=r})}on(t,s){const e=this.listeners.get(t);e?e.add(s):this.listeners.set(t,new Set([s]))}queueEvent=(t,s,...e)=>{this.#e.set(t+String(s),[t,s,...e])};runListeners=(t,s,...e)=>{for(const a of this.listeners.get(t)||new Set)s?a(s,...e):a(...e)};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=R.instance(),s=await H(this.serverOutDir),e=Object.fromEntries(Object.entries(s.tags).filter(([a])=>D[a]!=null?t.canAccessFeature(D[a]):!0));this.#s={...s,tags:e}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=t=>{const s=this.globalData,e={...this.globalData,...t};this.globalData=e,JSON.stringify(e)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,e)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:t,context:s,deps:e,resource:a})=>{const{data:{info:r,ast:o},compoundHash:l}=await j(t,this.markdocOptions,{actions:this,context:s},a);for(const i of r.sharedDataDeps||[]){for(const n of e?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of e?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const n of e?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of e?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(e?.routeSlugs&&r.partials?.length)for(const i of e.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of r.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:r,ast:o,compoundHash:l}};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 s=Object.keys(t);for(const o of s)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=y(t,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:e,unsetEnvVars:a,replacedValues:r}=J(t);for(const o of a)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,r),Object.assign(this.config,e)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,s,e={})=>{if(!R.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(t).toLowerCase();this.config.redirects[o]=s;const{trackOriginalSource:l=!0}=e,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&W(this.config.wildcardRedirectsTree,o)};getRedirect=t=>{const s=h(t).toLowerCase(),e=q(s,this.config.redirects,this.config.wildcardRedirectsTree);if(!e)return null;if(S(e.to)){const a=h(e.to).toLowerCase();if(!a.endsWith("*")&&x(a,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:e.to,type:e.type}};createSharedData=async(t,s,e)=>{if(e&&this.#t[t]===e)return t;const a=JSON.stringify(s),r=e??k(a);return this.#t[t]===r||(this.#t[t]=r,await B(t,a,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,s,e)=>{const a=L(t),r=this.routesSharedData.get(a)||{};r[s]=e,this.routesSharedData.set(a,r),u.verbose(`Adding shared data to ${t}, ${s}, ${e}`)};getRouteSharedDataByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=t=>{const s=this.getGlobalConfig(m)||{},e=this.routesPartials.get(t);if(!e||e.length===0)return{};const a=this.getGlobalConfig(z)||{},r=new Set(e),o=Array.from(e);for(let i=0;i<o.length;i++){const n=o[i],c=a[n]?.partials??[];for(const d of c)r.has(d)||(r.add(d),o.push(d))}const l={};for(const i of r)s[i]&&(l[i]=s[i]);return l};addRoute=t=>{const e={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:e}),u.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,s,e)=>{const a=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(r=>({code:r,name:r}));for(const r of a){const o=C(t,g,r.code,a);this.addRouteSharedData(o,s,e)}};addApiRoute=t=>{this.apiRoutes.push(t),u.verbose("Created API route %s",t.slug)};addMcpTools=(t,s)=>{for(const e of s)this.mcpToolHandlers.set(e.name,{...e,importPath:t}),u.verbose("Created MCP tool %s",e.name)};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());addMiddleware=t=>{this.middleware.push(t),u.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(t,s={})=>{const{followRedirect:e=!0}=s,a=this.getRedirect(t);return e&&a?this.routesBySlug.get(h(a.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const s=this.getRedirect(t);if(!s)return!1;if(!S(s.to))return!0;const e=h(s.to);return this.routesBySlug.has(e)};getRoutesByTemplateId=t=>this.newRoutes.filter(s=>s.templateId===t);getAllRoutesForLocale=(t=g)=>{const s=Array.from(this.routesBySlug.values()),e=t.toLowerCase();return s.filter(a=>t===g?!K(a.fsPath):a.slug.startsWith(`/${e}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,s)=>(this.templates.set(t,s),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,s)=>(this.apiRoutesRequestHandlers.set(t,s),t);registerServerPropsGetter=(t,s)=>(this.serverPropsGetters.set(t,s),t);registerPagePropsGetter=(t,s)=>{this.pagePropsGetters.set(t,s)};async writeRouteStaticData(t,s){const e=await this.resolveRouteStaticData(t,s,!1);e&&V(t.slug,e,this.outdir)}async resolveRouteStaticData(t,s,e){if(this.serverMode)return N(t.slug,this.outdir);const a={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[t.slug]},resource:f})},r=await t.getStaticData?.(t,a)||{},o=new Set(this.routesDynamicComponents.get(t.slug)),l=this.routesSharedData.get(t.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(t.slug,p,p))}const i=this.getGlobalConfig("seo"),n=r?.frontmatter||{};return{...r,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...r.props,dynamicMarkdocComponents:Array.from(o),metadata:{...r?.props?.metadata,...t.metadata},seo:{title:T,...i,...r.props?.seo},compilationErrors:this.compilationErrors},lastModified:e||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,s){if(!t?.length)return;const e=typeof t[0]=="string"?t.join(""):I(t);e&&(s==="head"?this.ssr.headTags.push(e):s==="preBody"?this.ssr.preBodyTags.push(e):this.ssr.postBodyTags.push(e))}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[e,a]of Object.entries(v))switch(a){case"map":const r=Array.from(this[e].entries());t.push([e,r]);break;case"object":e==="config"&&t.push([e,await this.getConfigWithEnvPlaceholders()]),t.push([e,this[e]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(t);return s[E]=G.PLAN_GATES,s}static fromJson(t,s){const e=new P(s);for(const[r,o]of Object.entries(v))switch(o){case"map":e[r]=new Map(t[r]);break;case"object":if(r==="config"){e.setGlobalConfig(t[r]);break}e[r]=t[r];break;default:throw new Error("Invalid format")}e.config[m]=Z(e.config[m]||{});const a=t[E];return a&&_("PLAN_GATES",a),e}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:e}=this.replacedEnvVars[s],a=s.split(":"),r=a.pop(),{error:o,value:l}=y(t,a);if(o||!O(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[r]=e}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(e=>!Y.includes(e));if(t.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(s)}}function Z(b){return M(b,t=>A.Ast.fromJSON(JSON.stringify(t)))}export{m as MARKDOC_PARTIALS_DATA_KEY,z as MARKDOC_PARTIALS_DEPS_KEY,P as Store,Tt 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 g}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 h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as S}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as u}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 G}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}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 R}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 J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as q}from"./utils/redirects/find-redirect.js";import{followRedirectChain as x}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as W}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",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map"},m="markdown/partials",z="markdown/partials-deps",E="PLAN_GATES",Y=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Tt="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=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;mcpToolHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},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:s,serverMode:e=!1,serverOutDir:a}){this.#r=s,this.outdir=t,this.serverMode=e,this.serverOutDir=a,this.userCodeReady=new Promise(r=>{this.#a=r})}on(t,s){const e=this.listeners.get(t);e?e.add(s):this.listeners.set(t,new Set([s]))}queueEvent=(t,s,...e)=>{this.#e.set(t+String(s),[t,s,...e])};runListeners=(t,s,...e)=>{for(const a of this.listeners.get(t)||new Set)s?a(s,...e):a(...e)};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=R.instance(),s=await H(this.serverOutDir),e=Object.fromEntries(Object.entries(s.tags).filter(([a])=>D[a]!=null?t.canAccessFeature(D[a]):!0));this.#s={...s,tags:e}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=t=>{const s=this.globalData,e={...this.globalData,...t};this.globalData=e,JSON.stringify(e)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,e)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:t,context:s,deps:e,resource:a})=>{const{data:{info:r,ast:o},compoundHash:l}=await j(t,this.markdocOptions,{actions:this,context:s},a);for(const i of r.sharedDataDeps||[]){for(const n of e?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of e?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const n of e?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of e?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(e?.routeSlugs&&r.partials?.length)for(const i of e.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of r.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:r,ast:o,compoundHash:l}};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 s=Object.keys(t);for(const o of s)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=y(t,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:e,unsetEnvVars:a,replacedValues:r}=J(t);for(const o of a)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,r),Object.assign(this.config,e)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,s,e={})=>{if(!R.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(t).toLowerCase();this.config.redirects[o]=s;const{trackOriginalSource:l=!0}=e,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&W(this.config.wildcardRedirectsTree,o)};getRedirect=t=>{const s=h(t).toLowerCase(),e=q(s,this.config.redirects,this.config.wildcardRedirectsTree);if(!e)return null;if(S(e.to)){const a=h(e.to).toLowerCase();if(!a.endsWith("*")&&x(a,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:e.to,type:e.type}};createSharedData=async(t,s,e)=>{if(e&&this.#t[t]===e)return t;const a=JSON.stringify(s),r=e??k(a);return this.#t[t]===r||(this.#t[t]=r,await B(t,a,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,s,e)=>{const a=L(t),r=this.routesSharedData.get(a)||{};r[s]=e,this.routesSharedData.set(a,r),u.verbose(`Adding shared data to ${t}, ${s}, ${e}`)};getRouteSharedDataByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=t=>{const s=this.getGlobalConfig(m)||{},e=this.routesPartials.get(t);if(!e||e.length===0)return{};const a=this.getGlobalConfig(z)||{},r=new Set(e),o=Array.from(e);for(let i=0;i<o.length;i++){const n=o[i],c=a[n]?.partials??[];for(const d of c)r.has(d)||(r.add(d),o.push(d))}const l={};for(const i of r)s[i]&&(l[i]=s[i]);return l};addRoute=t=>{const e={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:e}),u.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,s,e)=>{const a=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(r=>({code:r,name:r}));for(const r of a){const o=C(t,g,r.code,a);this.addRouteSharedData(o,s,e)}};addApiRoute=t=>{this.apiRoutes.push(t),u.verbose("Created API route %s",t.slug)};addMcpTools=(t,s)=>{for(const e of s)this.mcpToolHandlers.set(e.name,{...e,importPath:t}),u.verbose("Created MCP tool %s",e.name)};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());addMiddleware=t=>{this.middleware.push(t),u.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(t,s={})=>{const{followRedirect:e=!0}=s,a=this.getRedirect(t);return e&&a?this.routesBySlug.get(h(a.to)):this.routesBySlug.get(t)};hasRouteOrRedirectBySlug=t=>{if(this.routesBySlug.has(t))return!0;const s=this.getRedirect(t);if(!s)return!1;if(!S(s.to))return!0;const e=h(s.to);return this.routesBySlug.has(e)};getRoutesByTemplateId=t=>this.newRoutes.filter(s=>s.templateId===t);getAllRoutesForLocale=(t=g)=>{const s=Array.from(this.routesBySlug.values()),e=t.toLowerCase();return s.filter(a=>t===g?!K(a.fsPath):a.slug.startsWith(`/${e}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,s)=>(this.templates.set(t,s),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,s)=>(this.apiRoutesRequestHandlers.set(t,s),t);registerServerPropsGetter=(t,s)=>(this.serverPropsGetters.set(t,s),t);registerPagePropsGetter=(t,s)=>{this.pagePropsGetters.set(t,s)};async writeRouteStaticData(t,s){const e=await this.resolveRouteStaticData(t,s,!1);e&&V(t.slug,e,this.outdir)}async resolveRouteStaticData(t,s,e){if(this.serverMode)return N(t.slug,this.outdir);const a={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[t.slug]},resource:f})},r=await t.getStaticData?.(t,a)||{},o=new Set(this.routesDynamicComponents.get(t.slug)),l=this.routesSharedData.get(t.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(t.slug,p,p))}const i=this.getGlobalConfig("seo"),n=r?.frontmatter||{};return{...r,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...r.props,dynamicMarkdocComponents:Array.from(o),metadata:{...r?.props?.metadata,...t.metadata},seo:{title:T,...i,...r.props?.seo},compilationErrors:this.compilationErrors},lastModified:e||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,s){if(!t?.length)return;const e=typeof t[0]=="string"?t.join(""):I(t);e&&(s==="head"?this.ssr.headTags.push(e):s==="preBody"?this.ssr.preBodyTags.push(e):this.ssr.postBodyTags.push(e))}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[e,a]of Object.entries(v))switch(a){case"map":const r=Array.from(this[e].entries());t.push([e,r]);break;case"object":e==="config"&&t.push([e,await this.getConfigWithEnvPlaceholders()]),t.push([e,this[e]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(t);return s[E]=G.PLAN_GATES,s}static fromJson(t,s){const e=new P(s);for(const[r,o]of Object.entries(v))switch(o){case"map":e[r]=new Map(t[r]);break;case"object":if(r==="config"){e.setGlobalConfig(t[r]);break}e[r]=t[r];break;default:throw new Error("Invalid format")}e.config[m]=Z(e.config[m]||{});const a=t[E];return a&&_("PLAN_GATES",a),e}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:e}=this.replacedEnvVars[s],a=s.split(":"),r=a.pop(),{error:o,value:l}=y(t,a);if(o||!O(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[r]=e}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(e=>!Y.includes(e));if(t.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(s)}}function Z(b){return M(b,t=>A.Ast.fromJSON(JSON.stringify(t)))}export{m as MARKDOC_PARTIALS_DATA_KEY,z as MARKDOC_PARTIALS_DEPS_KEY,P as Store,Tt as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -8,7 +8,7 @@ export type RoutesInfoActions = {
8
8
  followRedirect?: boolean;
9
9
  }) => PageRouteDetails | undefined;
10
10
  getAllRoutesForLocale: (locale?: string) => PageRouteDetails[];
11
- slugHasRouteOrRedirect: (slug: string) => boolean;
11
+ hasRouteOrRedirectBySlug: (slug: string) => boolean;
12
12
  buildRevision: number;
13
13
  };
14
14
  export type MarkdocResolveContext = {
@@ -1 +1 @@
1
- import h from"node:path";import{existsSync as R,lstatSync as w,readdirSync as N}from"node:fs";import{CONFIG_FILE_NAME as y}from"../../../constants/common.js";import{PUBLIC_STATIC_FOLDER as F}from"../../constants/common.js";import{normalizeRouteSlug as s}from"../../../utils/path/normalize-route-slug.js";import{isLocalLink as C}from"../../../utils/path/is-local-link.js";import{reporter as T}from"../../tools/notifiers/reporter.js";import{followRedirectChain as k}from"./follow-redirect-chain.js";function D(e){const i=e.getConfig().redirects;if(!i)return;const o=e.getGlobalConfig("wildcardRedirectsTree")??{},c=e.getGlobalConfig("originalRedirectSources");for(const[r,l]of Object.entries(i)){const t=l?.to;if(!t||c&&!c.includes(r))continue;const d=r.toLowerCase(),L=t.toLowerCase(),m=r.endsWith("*"),f=t.endsWith("*");if(f)continue;const u=a=>{T.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",sourceFileRelativePath:y,sourceFileLocation:{line:0},title:r,link:t,rawLink:t,message:a})};if(z(r,t,m,f)){u(`Redirect from "${r}" points to the same page. This causes an infinite redirect loop.`);continue}if(m&&!f&&C(t)){const a=s(r.split("*")[0]).toLowerCase(),p=s(L);if(a===p){u(`Circular redirect: "${r}" points to the same base path "${t}", causing an infinite redirect loop.`);continue}}if(!m&&!f&&C(t)){const a=s(d),p=s(L),g=k(p,[a],i,o,!1);if(g.type==="cycle"&&g.cycle.length>0){u(`Circular redirect: ${g.cycle.join(" \u2192 ")}.`);continue}}C(t)&&I(t,e)&&u(`Redirect target "${t}" does not exist. Check that the page or route exists.`)}}function z(e,n,i,o){if(!i&&!o){const c=s(e).toLowerCase(),r=s(n).toLowerCase();return c===r}return!1}function I(e,n){const i=s(e).toLowerCase();return n.slugHasRouteOrRedirect(i)?!1:!v(e,n)}function v(e,n){const o=decodeURI(e.split("?")[0].split("#")[0]).replace(/^\/+/,"");if(!o)return!1;const c=n.contentDir;return c?S(c,o)||S(h.join(c,F),o):!1}function S(e,n){const i=x(e,n);return i?P(i):!1}function x(e,n){const i=n.split("/").filter(Boolean);let o=e;for(const c of i){const r=h.join(o,c);if(R(r)){o=r;continue}let l;try{l=N(o)}catch{return null}const t=l.find(d=>d.toLowerCase()===c.toLowerCase());if(!t)return null;o=h.join(o,t)}return o}function P(e){if(!R(e))return!1;try{return w(e).isFile()}catch{return!1}}export{D as validateRedirects};
1
+ import h from"node:path";import{existsSync as R,lstatSync as y,readdirSync as N}from"node:fs";import{CONFIG_FILE_NAME as w}from"../../../constants/common.js";import{PUBLIC_STATIC_FOLDER as F}from"../../constants/common.js";import{normalizeRouteSlug as s}from"../../../utils/path/normalize-route-slug.js";import{isLocalLink as C}from"../../../utils/path/is-local-link.js";import{reporter as T}from"../../tools/notifiers/reporter.js";import{followRedirectChain as k}from"./follow-redirect-chain.js";function D(e){const i=e.getConfig().redirects;if(!i)return;const o=e.getGlobalConfig("wildcardRedirectsTree")??{},c=e.getGlobalConfig("originalRedirectSources");for(const[r,l]of Object.entries(i)){const t=l?.to;if(!t||c&&!c.includes(r))continue;const d=r.toLowerCase(),L=t.toLowerCase(),m=r.endsWith("*"),f=t.endsWith("*");if(f)continue;const u=a=>{T.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",sourceFileRelativePath:w,sourceFileLocation:{line:0},title:r,link:t,rawLink:t,message:a})};if(z(r,t,m,f)){u(`Redirect from "${r}" points to the same page. This causes an infinite redirect loop.`);continue}if(m&&!f&&C(t)){const a=s(r.split("*")[0]).toLowerCase(),p=s(L);if(a===p){u(`Circular redirect: "${r}" points to the same base path "${t}", causing an infinite redirect loop.`);continue}}if(!m&&!f&&C(t)){const a=s(d),p=s(L),g=k(p,[a],i,o,!1);if(g.type==="cycle"&&g.cycle.length>0){u(`Circular redirect: ${g.cycle.join(" \u2192 ")}.`);continue}}C(t)&&I(t,e)&&u(`Redirect target "${t}" does not exist. Check that the page or route exists.`)}}function z(e,n,i,o){if(!i&&!o){const c=s(e).toLowerCase(),r=s(n).toLowerCase();return c===r}return!1}function I(e,n){const i=s(e);return n.hasRouteOrRedirectBySlug(i)?!1:!v(e,n)}function v(e,n){const o=decodeURI(e.split("?")[0].split("#")[0]).replace(/^\/+/,"");if(!o)return!1;const c=n.contentDir;return c?S(c,o)||S(h.join(c,F),o):!1}function S(e,n){const i=x(e,n);return i?P(i):!1}function x(e,n){const i=n.split("/").filter(Boolean);let o=e;for(const c of i){const r=h.join(o,c);if(R(r)){o=r;continue}let l;try{l=N(o)}catch{return null}const t=l.find(d=>d.toLowerCase()===c.toLowerCase());if(!t)return null;o=h.join(o,t)}return o}function P(e){if(!R(e))return!1;try{return y(e).isFile()}catch{return!1}}export{D as validateRedirects};
@@ -1 +1 @@
1
- import i from"node:path";import{withPathPrefix as f}from"@redocly/theme/core/utils";import{PUBLIC_STATIC_FOLDER as p}from"../constants/common.js";import{isLocalLink as u}from"../../utils/path/is-local-link.js";import{copyStaticFile as F,FileNotFoundError as d}from"./fs.js";async function h(r,n,o){if(!u(r))return r;const t=r.startsWith("/")?i.posix.join(p,r):void 0;if(t&&await n.exists(t))return f(r);const c=r.startsWith("/")?r.slice(1):i.posix.join(i.dirname(o.fromFileRelativePath),r),m=n.getFileInfo(c);if(!m)throw new d(`Cannot resolve asset path: ${r}`,r);return F(o.contentDir,m.realRelativePath,o.outdir)}export{h as resolveAssetPath};
1
+ import t from"node:path";import{withPathPrefix as f}from"@redocly/theme/core/utils";import{PUBLIC_STATIC_FOLDER as e}from"../constants/common.js";import{isLocalLink as p}from"../../utils/path/is-local-link.js";import{copyStaticFile as u,FileNotFoundError as x}from"./fs.js";async function h(r,o,i){if(!p(r))return r;const n=r.startsWith("/")?t.posix.join(e,r):void 0;if(n&&await o.exists(n))return f(r);const c=r.startsWith("/")?r.slice(1):t.posix.join(t.dirname(i.fromFileRelativePath),r),m=await o.exists(c)?await o.getFileInfo(c):null;if(!m)throw new x(`Cannot resolve asset path: ${r}`,r);return u(i.contentDir,m.realRelativePath,i.outdir)}export{h as resolveAssetPath};
@@ -1,7 +1,7 @@
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"
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 Y,JWT_SECRET_KEY as I}from"../constants/common.js";import{envConfig as Q}from"../config/env-config.js";import{getPathPrefix as X,withPathPrefix as G}from"@redocly/theme/core/utils";import{DEFAULT_AUTHENTICATED_TEAM as Z,REQUIRED_OIDC_SCOPES as R,ServerRoutes as N}from"../../constants/common.js";import{appendQueryParams as ee}from"../../utils/url/append-query-params.js";import{logger as te}from"../tools/notifiers/logger.js";import{randomString as ne}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as y,JwtTokenExpired as re}from"./jwt/types.js";import*as p from"./jwt/jwt.js";import{parseTeamClaimToArray as oe}from"../utils/index.js";import{arrayBufferToBase64 as ae,decodeBase64 as P,encodeBase64URL as se,urlSafeBase64 as v}from"./jwt/encode.js";import{formatSamlCertificate as ie}from"./utils/format-saml-certificate.js";function E(e){return e?.type===u.OIDC}function ce(e){return e?.type===u.SAML2}async function Je(e,t){if(E(t))return ue(e,t);if(ce(t))return de(e,t)}async function ue(e,t){const r=await V(e,t),n=new Set((t.scopes||[]).concat(R)),o=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:o,pkce:t.pkce}}function de(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}async function qe(e,t,r,n,o={}){const a=new Set((n.scopes||[]).concat(R));return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:n.clientId,scope:Array.from(a).join(" "),code:t,redirect_uri:j(r),grant_type:"authorization_code",...n.clientSecret?{client_secret:n.clientSecret}:{},...o}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function me(e,{authorizationEndpoint:t,clientId:r,responseType:n,scope:o,extraParams:a,idpId:s,pkce:l},m,A,S){if(!t||!r||!n||!o)return{loginUrl:void 0};const c=new URL(t),f=S?.redirectUriOverride??`${e}${G(N.OIDC_CALLBACK)}`,_={state:U(),idpId:s,redirectUri:f,redirectTo:m,branch:S?.branchOverride??le(e),inviteCode:A,source:S?.sourceOverride??"portal"},h={};if(l){const d=v(ne(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",o),c.searchParams.append("response_type",n),c.searchParams.append("redirect_uri",j(f)),c.searchParams.append("state",se(JSON.stringify(_)));for(const d in a)a[d]!==void 0&&c.searchParams.append(d,a[d]);return{loginUrl:c.toString(),cookies:h}}function We(e,t,r,n){const o=new URL(e);return o.searchParams.append("post_logout_redirect_uri",t),n&&o.searchParams.append("state",n),o.searchParams.append("id_token_hint",r),o.toString()}async function Ke(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 Ye(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 j(e){return e.match(/^https:\/\/preview-[^\.]+--/)?"https://previewauth--"+e.split("--")[1]:e.match(/^(https:\/\/[^\.]+)--[^\.]+\.preview\./)?e.replace(/^(https:\/\/[^\.]+?)--[^\.]+\.preview\./,"$1.previewauth."):e}function le(e){return e.match(/^(https:\/\/[^\.]+)--([^\.]+)\.preview\./)?.[2]||void 0}function pe(e){return e.type===u.OIDC}function fe(e){return e.type===u.SAML2}function Xe(e,t,r,n){return pe(e)?me(t,e,r,n):fe(e)?he(t,e,r,n):{}}function he(e,t,r,n){const a=`<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="_${P()}"
4
+ ID="_${U()}"
5
5
  IssueInstant="${new Date().toISOString()}"
6
6
  AssertionConsumerServiceURL="${e}${N.SAML_CALLBACK}"
7
7
  AttributeConsumingServiceIndex="0">
@@ -9,4 +9,4 @@ import"../node-crypto-polyfill.js";import{DOMParser as b}from"@xmldom/xmldom";im
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 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,w as oidcJwksCache,M as oidcMetadataCache,Qe as parseOidcState,me as parsePreviewBranch,Xe as parseSamlResponse,E as rewritePreviewAuthRedirectUri,Je as verifyMcpAuthorizationCode,Ze as verifySAMLResponse};
12
+ </samlp:AuthnRequest>`,s=ye(a);return{loginUrl:ee(t.ssoUrl,{SAMLRequest:s,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:r,inviteCode:n,source:"portal"})})}}function ye(e){return ae(H(new TextEncoder().encode(e)).buffer)}function Ge(e){const t=P(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 Ze(e){try{return JSON.parse(P(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function et(e){const t=new b().parseFromString(e,"application/xml"),n=i(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,a=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=we(x),M={},C=i(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(C.length)for(const T of C){const D=i(T,"./@Name")[0];if(D.nodeValue){const O=i(T,"./*[local-name(.)='AttributeValue']/text()")[0];O?.nodeValue&&(M[D.nodeValue]=O.nodeValue)}}return{uid:_,success:n,expiresAt:g,issuerId:l,entityId:A,attrs:M,cert:c,nameFormat:d,destination:a}}function we(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 k={},w={jwks:{}};async function V(e,t){if(!k[e]){const r=t.configurationUrl?await $(t.configurationUrl):t.configuration;k[e]=Se()?Ae(r):r}return k[e]}function Se(){const e=Q.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}function Ae(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const r of Object.keys(t)){const n=t[r];typeof n=="string"&&n.includes("://localhost")&&(t[r]=n.replace("://localhost","://host.docker.internal"))}return t}async function _e(e){for(const t of Object.keys(e)){const r=e[t];if(!E(r))continue;const n=await V(t,r);if(n.jwks_uri){const o=await $(n.jwks_uri);for(const a of o.keys)w.jwks[a.kid]={...a,idpId:t}}}}async function $(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function tt(e){return fetch(`${Y}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function nt(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=>xe(t.hostname,n))}function xe(e,t){return e===t||e.endsWith(`.${t}`)}async function rt(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 o=ie(t),a=new B({publicCert:o});a.loadSignature(n);try{return a.checkSignature(e)}catch{return!1}}function ot(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 o;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(o=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(o=e);const a=r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=a?.match(/.+@.+/);return o=o||r["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?a:void 0),o=o?.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"]||a,email:o,email_verified:!0,teams:n?oe(r[n]):[]}}function z(e,t={}){return e.map(r=>t[r]||r)}async function at(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 _e(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 o=n.payload.idpId||w.jwks[n.header.kid]?.idpId,a=e[o]||{},s=Le(a),l=Ie(a);return{...n.payload,email:n.payload.email?.toLowerCase(),idpId:o,teams:Array.from(new Set([...z(n.payload.teams||[],l),..."defaultTeams"in a&&a.defaultTeams||[],...z("teamsClaimName"in a&&n.payload[s||""]||[],l),Z])),name:ge(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 re||te.error("Malformed JWT token: %s",n.message)}return{}}function ge(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Ie(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Le(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{Xe as buildLoginUrl,me as buildOidcLoginUrl,We as buildOidcLogoutUrl,he as buildSAML2LoginUrl,Ke as createMcpAuthorizationCode,Qe as createMcpSessionResource,Ge as decodeSamlResponse,ye as encodeSAML2,ot as extractUserClaims,Je as getAuthProviderLoginParams,ue as getOidcLoginParams,V as getOidcMetadata,tt as getRedoclyTokenPayload,de as getSaml2LoginParams,at as getUserParamsFromCookies,ge as getUsernameFromPayload,E as isOidcProviderConfig,nt as isRedoclySso,ce as isSaml2ProviderConfig,qe as oidcExchangeCodeForToken,w as oidcJwksCache,k as oidcMetadataCache,Ze as parseOidcState,le as parsePreviewBranch,et as parseSamlResponse,j as rewritePreviewAuthRedirectUri,Ye as verifyMcpAuthorizationCode,rt as verifySAMLResponse};
@@ -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().access?.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 L,deleteCookie as q}from"hono/cookie";import{AuthProviderType as V}from"@redocly/config";import{withPathPrefix as M,getPathPrefix as R}from"@redocly/theme/core/utils";import{compareURIs as X}from"../../../utils/url/compare-uris.js";import{ensureArray as b}from"../../../utils/array/ensure-array.js";import{ALTERNATIVE_AUD_CLAIM_NAME as E,JWT_SECRET_KEY as $,ORG_SLUG as W,ORG_ID as Y}from"../../constants/common.js";import{DEFAULT_COOKIE_EXPIRATION as F,ServerRoutes as S}from"../../../constants/common.js";import{sanitizeRedirectPathname as B}from"../../../utils/url/sanitize-redirect-pathname.js";import{telemetry as k}from"../../telemetry/index.js";import{envConfig as z}from"../../config/env-config.js";import{getAuthProviderLoginParams as Q,isOidcProviderConfig as U,isSaml2ProviderConfig as Z,oidcExchangeCodeForToken as x,buildLoginUrl as ee,decodeSamlResponse as re,extractUserClaims as oe,parseSamlResponse as ne,parseOidcState as te,verifySAMLResponse as ie,getUsernameFromPayload as se,buildOidcLogoutUrl as ae,getOidcMetadata as H,getRedoclyTokenPayload as de,isRedoclySso as ce,rewritePreviewAuthRedirectUri as le,parsePreviewBranch as j,buildOidcLoginUrl as ue,createMcpSessionResource as A}from"../auth.js";import*as O from"../jwt/jwt.js";import{AlgorithmTypes as v}from"../jwt/types.js";import{handleErrorPageRender as pe}from"../utils.js";import{encodeBase64URL as ge}from"../jwt/encode.js";async function Oe(i){if(z.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.HS256);return L(i,"authorization",a,{path:R()||"/",httpOnly:!0,secure:!0,sameSite:"none"}),i.newResponse(null,200,{})}function ve(){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 N(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 Pe(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=te(e.req.query("state")),m=n.idpId,t=n.source==="mcp"||n.redirectTo&&typeof n.redirectTo=="string"&&n.redirectTo.includes(S.MCP_CALLBACK),c=t?N(typeof n.redirectTo=="string"?n.redirectTo:void 0):null,s=a?.[m];if(!U(s))return r.error("OIDC login error: missing OIDC provider config"),e.text("Forbidden",403);const d=await H(m,s);if(a&&!d.token_endpoint){const u="Invalid OIDC configuration: token_endpoint is required";return r.error(`OIDC login error: ${u}`),e.text(u,500)}try{const u=d.token_endpoint,l=e.req.query("code"),h=e.req.query("error");if(h)return t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:`OIDC error: ${h}`,error_details:e.req.query("error_description")||null}]),pe(e,i,{slug:"/"},403,"403OIDC");if(!l){const w="Code is expected but not present";return r.error(`OIDC login error: ${w}`),t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const C=typeof n.redirectUri=="string"?n.redirectUri:new URL(M(S.OIDC_CALLBACK),e.req.url).toString(),p=e.get("cookies")?.code_verifier,g=await x(u,l,C,s,{...s.tokenRequestCustomParams,...p?{code_verifier:p}:{}});if(g.error)return r.error(`Error from OIDC provider: "${g.error}"`),t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:`Token exchange error: ${g.error}`,error_details:g.error_description||null}]),e.text(`Forbidden: ${g.error_description||g.error}`,403);if(!g?.id_token){const w="No id_token, please, add openid to scopes";return r.error(`OIDC login error: ${w}`),t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:w,error_details:null}]),new Response(`Forbidden: ${w}`,{status:403})}const{payload:f,header:_}=O.decode(g.id_token),o=_.alg===v.RS256;if(s.audience?.length&&![...b(f.aud||[]),...b(f[E]||[])].some(I=>s.audience?.includes(I))){const I="No valid audience found in id_token";return r.error(`OIDC login error: ${I}`),t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:I,error_details:null}]),new Response(`Forbidden: ${I}`)}const P=o?g.id_token:await O.sign({...f,idpId:m},$,v.HS256);se(f)||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:f.exp*1e3||Date.now()+F*1e3;if(s.introspectEndpoint){const w=await fetch(s.introspectEndpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({access_token:g.access_token})});if(w.ok){const T=(await w.json()).ext?.federatedIdentity;T&&(L(e,"federated_access_token",T.access_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}),L(e,"federated_id_token",T.id_token||"",{path:R()||"/",httpOnly:!1,expires:new Date(D)}))}else r.warn(`OIDC introspect error: ${w.statusText}`)}if(L(e,"authorization",P,{path:R()||"/",httpOnly:!0,expires:new Date(D)}),P!==g.id_token&&L(e,"idp_id_token",g.id_token||"",{path:R()||"/",httpOnly:!0,expires:new Date(D)}),L(e,"idp_access_token",g.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 I=`${e.req.url.split("?")[0].replace(S.OIDC_CALLBACK,"")}${n.redirectTo}`;return e.newResponse(null,302,{Location:I})}const K=typeof n.redirectTo=="string"?n.redirectTo:void 0;let J=B(new URL(K||"/",e.req.url).pathname);const G=e.newResponse(null,302,{Location:J});return r.updateContext({email:f.email,subject:f.sub}),r.info("OIDC login successful"),G}catch(u){const l=u instanceof Error?u.message:String(u),h=u instanceof Error?u.stack:String(u);if(r.error(`OIDC login error: ${l}`),t&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:l,error_details:h}]),u.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&&k.sendMcpAuthorizationFailedMessage([{...A(c),error:y,error_details:null}]),e.text(y,500)}}function $e(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 U(t)||q(e,"authorization",{path:R()||"/"}),r.info("Logout successful"),e.newResponse(null,200,{});let c;if(U(t)){const s=(await H(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",u=e.req.header("x-forwarded-host")||d.host,l=`${y}://${u}`,h=j(l),C=h?ge(JSON.stringify({branch:j(l)})):void 0,p=h?`${le(l)}/_auth/logout`:`${l}/post-logout`;c=ae(s,p,e.get("cookies")?.idp_id_token||e.get("cookies")?.authorization||"",C)}}return r.info("Logout successful"),q(e,"authorization",{path:R()||"/"}),e.newResponse(null,302,{Location:c||M("/")})}}function Ue(i){return async e=>{const r=i.getConfig().access?.logoutReturnUrl,a=r||M("/");return e.newResponse(null,302,{Location:a})}}function Te(i){return async e=>{const r=e.get("logger"),a=e.req.param("code"),n=z.BH_API_URL,m=(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(M("/"));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(M("/"))):(r.error("Invite error",await c.text()),e.redirect(M("/")));const s=await c.json(),d=new URL(M("/invite"),e.req.url);return d.searchParams.set("code",a),d.searchParams.set("org",s.organization.name),d.searchParams.set("invitedBy",m(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 qe(i){return async e=>{const r=e.get("logger"),a=i.getConfig().ssoDirect,n=new URL(e.req.url),m=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"),u=Object.keys(a||{})[0];d=d||u;const l=n.searchParams.get("mcp_redirect_uri"),h=!!l;if(!a?.[d]){const o="Invalid idpId";if(r.error(`IdP login error: ${o}`),h){const P=N(y||void 0);k.sendMcpAuthorizationFailedMessage([{...A(P),error:o,error_details:null}])}return e.text(`Forbidden: ${o}`,403)}const p=d&&a?await Q(d,a[d]):void 0,g={};for(const o of Object.keys(p?.extraParams||{}))g[o]=n.searchParams.get(o)||p?.extraParams?.[o]||void 0;let f,_={};if(h&&l&&p&&p.type===V.OIDC){r.info(`Building MCP OAuth login URL with redirect_uri: ${l}`);const o=ue("",{...p,extraParams:g},y,m,{redirectUriOverride:l,sourceOverride:"mcp",branchOverride:void 0});f=o.loginUrl,_=o.cookies||{}}else if(p){const o=ee({...p,extraParams:g},s,y,m);f=o.loginUrl,_=o.cookies||{}}return Object.keys(_).forEach(o=>{L(e,o,_[o].value,_[o].options)}),r.info(`IdP login initiated for ID '${d}'`),e.newResponse(null,302,{Location:f||new URL(e.req.url).pathname})}}function be(i){return async e=>{const r=e.get("logger"),a=await e.req.formData(),n=a.get("SAMLResponse"),m=a.get("RelayState");if(typeof n!="string"||typeof m!="string"){const o="SAMLResponse is required";return r.error(`SAML2 login error: ${o}`),e.text(`Bad request: ${o}`,400)}const t=re(n),{success:c,uid:s,nameFormat:d,attrs:y,issuerId:u,expiresAt:l}=ne(t),{idpId:h,redirectTo:C}=JSON.parse(m);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 p=i.getConfig().ssoDirect?.[h];if(!p||!Z(p)){const o="Cannot find valid IdP";return r.error(`SAML2 login error: ${o}`),e.text(`Permission denied: ${o}`,401)}if(!(p.issuerId&&u&&X(p.issuerId,u))){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 ie(t,p.x509PublicCert)){const o="SAMLResponse signature invalid";return r.error(`SAML2 login error: ${o}`),e.text(o,401)}const f=oe(s,d,y,p.teamsAttributeName);if(!f.sub){const o="The provider did not return a valid user identity.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}if(!f.email){const o="The provider did not return a valid user email.";return r.error(`SAML2 login error: ${o}`),e.text(o,400)}const _=await O.sign({...f,idpId:h},$,v.HS256);return L(e,"authorization",_,{path:R()||"/",httpOnly:!0,expires:new Date(l*1e3)}),r.updateContext({email:f.email,subject:f.sub}),r.info("SAML2 login successful"),e.newResponse(null,302,{Location:C||"/"})}}function Ee(i){return async e=>{const r=e.get("logger"),a=new URL(e.req.query("redirectTo")||"/",e.req.url),n=M(B(a.pathname)),m=i.getConfig().ssoDirect,t=Object.entries(m||{}).find(([,C])=>U(C)&&ce(C));if(!(m&&t))return e.newResponse(null,302,{Location:n});const s=e.req.query("token"),d=s&&await de(s);if(!d)return e.newResponse(null,302,{Location:n});if(!b(d[E]||[]).some(C=>C===W||C===Y))return e.newResponse(null,302,{Location:n});const l=await O.sign({...d,idpId:t?.at(0)},$,v.HS256),h=Date.now()+F*1e3;return L(e,"authorization",l,{path:R()||"/",httpOnly:!0,expires:new Date(h),sameSite:"None",secure:!0}),r.info("Token login successful"),e.newResponse(null,302,{Location:n})}}export{Oe as authorizeHandler,qe as idpLoginHandler,Te as inviteHandler,$e as logoutHandler,Pe as oidcCallbackHandler,Ue as postLogoutHandler,ve as redoclyLoginCallbackHandler,Ee as redoclyTokenLoginHandler,be as samlCallbackHandler};
@@ -1,5 +1,6 @@
1
1
  import type { Context } from 'hono';
2
2
  export declare function corsProxyHandler(proxyBasePath?: string): (ctx: Context) => Promise<Response>;
3
+ export declare function isPrivateIp(ip: string): boolean;
3
4
  export declare function resolveCorsProxyTarget(requestUrl: string, proxyBasePath: string): URL | null;
4
5
  export declare const CORS_PROXY_STREAM_HEADER = "x-redocly-proxy-streaming";
5
6
  //# sourceMappingURL=cors-proxy.d.ts.map
@@ -1,2 +1,2 @@
1
- import{withPathPrefix as _}from"@redocly/theme/core/utils";import{ServerRoutes as q}from"../../../constants/common.js";import{getRequestOrigin as C}from"../utils/get-request-origin.js";const P=new Set(["connection","keep-alive","proxy-authenticate","proxy-connection","proxy-authorization","te","trailer","transfer-encoding","upgrade","host"]),$=new Set(["cookie","cookie2","accept-encoding"]),T=new Set(["set-cookie","set-cookie2","content-encoding","content-length"]),g="x-redocly-proxy-streaming",H="x-http-method-override",w="x-redocly-cookie";function z(o=_(q.CORS_PROXY)){return async e=>{const n=new URL(e.req.url).pathname;if(n===o||n===`${o}/`)return e.text(`Realm CORS proxy endpoint.
2
- Usage: ${o}/https://api.example.com/path`);const r=I(e.req.url,o);if(!r)return e.text("Invalid proxied URL",400);const i=C(e),c=r.origin===i,h=r.pathname===o||r.pathname.startsWith(`${o}/`);if(c&&!h)return new Response("Please use a direct request",{status:308,headers:{Location:r.toString(),Vary:"origin","Cache-Control":"private"}});const s=new Headers,f=S(e.req.raw.headers);for(const[t,E]of e.req.raw.headers)f.has(t.toLowerCase())||$.has(t.toLowerCase())||s.append(t,E);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")||"";L(u)&&s.delete("origin");let p=e.req.method;const R=s.get(H);R&&(p=R.toUpperCase(),s.delete(H));const m={method:p,headers:s,redirect:"follow"};p!=="GET"&&p!=="HEAD"&&e.req.raw.body&&(m.body=e.req.raw.body,m.duplex="half");let a;try{a=await fetch(r,m)}catch(t){const E=t instanceof Error?t.message:"unknown error",O=t instanceof Error&&t.cause instanceof Error?`: ${t.cause.message}`:"";return e.text(`Failed to proxy request: ${E}${O}`,502)}const l=new Headers(a.headers),y=S(a.headers);for(const t of y)l.delete(t);for(const t of T)l.delete(t);return l.set(g,"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 A(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(P),n=o.get("connection");if(!n)return e;for(const r of n.split(",")){const i=r.trim().toLowerCase();i&&e.add(i)}return e}function L(o){const e=o.toLowerCase();return e.includes(".redocly.app")||e.includes("localhost")}function I(o,e){const n=new URL(o),r=n.pathname===e,i=n.pathname.startsWith(`${e}/`);if(!r&&!i)return null;const c=n.pathname.slice(e.length).replace(/^\/+/,"");if(!c)return null;const h=[c,k(c)];for(const s of h){const f=D(s),d=A(f,n.search);try{const u=new URL(d);if(u.protocol==="http:"||u.protocol==="https:")return u}catch{continue}}return null}const U=g;export{U as CORS_PROXY_STREAM_HEADER,z as corsProxyHandler,I as resolveCorsProxyTarget};
1
+ import _ from"node:dns";import{isIP as T}from"node:net";import{withPathPrefix as D}from"@redocly/theme/core/utils";import{ServerRoutes as $}from"../../../constants/common.js";import{envConfig as w}from"../../config/env-config.js";import{getRequestOrigin as k}from"../utils/get-request-origin.js";const I=new Set(["connection","keep-alive","proxy-authenticate","proxy-connection","proxy-authorization","te","trailer","transfer-encoding","upgrade","host"]),L=new Set(["cookie","cookie2","accept-encoding"]),A=new Set(["set-cookie","set-cookie2","content-encoding","content-length"]),E="x-redocly-proxy-streaming",H="x-http-method-override",y="x-redocly-cookie";function Q(t=D($.CORS_PROXY)){return async e=>{const o=new URL(e.req.url).pathname;if(o===t||o===`${t}/`)return e.text(`Realm CORS proxy endpoint.
2
+ Usage: ${t}/https://api.example.com/path`);const n=F(e.req.url,t);if(!n)return e.text("Invalid proxied URL",400);const i=k(e),d=n.origin===i,f=n.pathname===t||n.pathname.startsWith(`${t}/`);if(d&&!f)return new Response("Please use a direct request",{status:308,headers:{Location:n.toString(),Vary:"origin","Cache-Control":"private"}});const u=await z(n.hostname);if((!w.isDevelopMode||w.isReunite)&&u&&N(u))return e.text("Requests to private network addresses are not allowed",403);const s=new Headers,h=S(e.req.raw.headers);for(const[r,g]of e.req.raw.headers)h.has(r.toLowerCase())||L.has(r.toLowerCase())||s.append(r,g);const a=s.get(y);if(a){const r=e.req.raw.headers.get("cookie")||"";s.set("cookie",r?`${r}; ${a}`:a),s.delete(y)}const C=e.req.raw.headers.get("origin")||"";W(C)&&s.delete("origin");let p=e.req.method;const R=s.get(H);R&&(p=R.toUpperCase(),s.delete(H));const m={method:p,headers:s,redirect:"manual"};p!=="GET"&&p!=="HEAD"&&e.req.raw.body&&(m.body=e.req.raw.body,m.duplex="half");let c;try{c=await fetch(n,m)}catch(r){const g=r instanceof Error?r.message:"unknown error",P=r instanceof Error&&r.cause instanceof Error?`: ${r.cause.message}`:"";return e.text(`Failed to proxy request: ${g}${P}`,502)}const O=c.headers.get("content-type")||"";if(Y(O)&&e.req.raw.headers.get("sec-fetch-mode")==="navigate")return e.text("Direct browser navigation to proxied HTML or JavaScript content is not allowed",403);const l=new Headers(c.headers),q=S(c.headers);for(const r of q)l.delete(r);for(const r of A)l.delete(r);return l.set(E,"1"),new Response(c.body,{status:c.status,statusText:c.statusText,headers:l})}}function x(t){try{return decodeURIComponent(t)}catch{return t}}function M(t){return t.replace(/^(https?):\/(?!\/)/i,"$1://")}function b(t,e){return e?t.includes("?")?e==="?"?t:`${t.endsWith("?")||t.endsWith("&")?t:`${t}&`}${e.slice(1)}`:`${t}${e}`:t}function S(t){const e=new Set(I),o=t.get("connection");if(!o)return e;for(const n of o.split(",")){const i=n.trim().toLowerCase();i&&e.add(i)}return e}function W(t){const e=t.toLowerCase();return e.includes(".redocly.app")||e.includes("localhost")}async function z(t){if(T(t))return t;try{const{address:e}=await _.promises.lookup(t);return e}catch{return null}}function N(t){const e=t.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);return e?v(e[1]):t.includes(":")?U(t):v(t)}function v(t){const e=t.split(".").map(Number);if(e.length!==4||e.some(i=>isNaN(i)))return!0;const[o,n]=e;return o===0||o===10||o===127||o===172&&n>=16&&n<=31||o===192&&n===168||o===169&&n===254||o===100&&n>=64&&n<=127}function U(t){const e=t.toLowerCase();return e==="::1"||e==="::"||e.startsWith("fc")||e.startsWith("fd")||e.startsWith("fe80")}function Y(t){const e=t.toLowerCase();return e.includes("text/html")||e.includes("javascript")||e.includes("application/xhtml")||e.includes("application/xml")||e.includes("image/svg")}function F(t,e){const o=new URL(t),n=o.pathname===e,i=o.pathname.startsWith(`${e}/`);if(!n&&!i)return null;const d=o.pathname.slice(e.length).replace(/^\/+/,"");if(!d)return null;const f=[d,x(d)];for(const u of f){const s=M(u),h=b(s,o.search);try{const a=new URL(h);if(a.protocol==="http:"||a.protocol==="https:")return a}catch{continue}}return null}const Z=E;export{Z as CORS_PROXY_STREAM_HEADER,Q as corsProxyHandler,N as isPrivateIp,F as resolveCorsProxyTarget};
@@ -1 +1 @@
1
- import{setCookie as A}from"hono/cookie";import{withPathPrefix as f}from"@redocly/theme/core/utils";import{DEV_LOGIN_SLUG as E}from"../../constants/common.js";import{CACHE_CONTROL_NO_CACHE_HEADER_VALUE as b}from"../constants/common.js";import{getAuthProviderLoginParams as w,buildLoginUrl as C}from"./auth.js";import{renderPage as y}from"../ssr/index.js";import{telemetry as _}from"../../cli/telemetry/index.js";async function F(r,t,n,o){const{isAuthenticated:i}=r.get("auth"),e=r.req.raw.headers.get("x-forwarded-host"),a=e?"https://"+e:new URL(r.req.url).origin,c=t.getConfig().ssoDirect,u=Object.keys(c||{}),s=o||u[0],m=c?.[s];if(i)return v(r,t,{slug:n},403);const d=s&&m?await w(s,m):void 0,g=d?{...d,extraParams:{...d.extraParams,prompt:"login"}}:void 0,{loginUrl:P,cookies:h={}}=g&&C(g,a,n)||{},p=t.globalData.auth?.devLogin||u.length>1?z(n):P;return Object.keys(h).forEach(l=>{A(r,l,h[l].value,h[l].options)}),p?r.newResponse(null,302,{Location:p}):r.text("Unauthorized",401)}const L={};async function v(r,t,n,o,i){let e=L[o];if(!e){const a={templateId:String(i||o),fsPath:"/",...n,baseSlug:n.slug};e=(await y(a,{},r,t,_)).html,L[o]=e}return r.html(e,o,{"Cache-Control":b})}function z(r){const t=new URLSearchParams({redirectTo:f(r)});return`${f(E)}?${t}`}async function S(r){return r.text("Forbidden",U(r))}function T(r){return r.json({message:"Forbidden"},U(r))}function U(r){const{isAuthenticated:t}=r.get("auth");return t?403:401}function $(r){const t=r?.match(/(?:^|:)(\d{1,3}(?:\.\d{1,3}){3})$/);return t?t[1]:r}export{z as getLoginUrlWithRedirect,v as handleErrorPageRender,F as handleUnauthorized,T as handleUnauthorizedApiRequest,S as handleUnauthorizedAsset,$ as normalizeIpAddress};
1
+ import{setCookie as A}from"hono/cookie";import{withPathPrefix as f}from"@redocly/theme/core/utils";import{DEV_LOGIN_SLUG as E}from"../../constants/common.js";import{CACHE_CONTROL_NO_CACHE_HEADER_VALUE as b}from"../constants/common.js";import{getAuthProviderLoginParams as C,buildLoginUrl as y}from"./auth.js";import{renderPage as _}from"../ssr/index.js";import{telemetry as v}from"../../cli/telemetry/index.js";async function S(r,t,o,n){const{isAuthenticated:a}=r.get("auth"),e=r.req.raw.headers.get("x-forwarded-host"),i=r.req.raw.headers.get("x-forwarded-proto"),U=e?`${i==="http"||i==="https"?i:"https"}://${e}`:new URL(r.req.url).origin,l=t.getConfig().ssoDirect,u=Object.keys(l||{}),s=n||u[0],p=l?.[s];if(a)return z(r,t,{slug:o},403);const d=s&&p?await C(s,p):void 0,g=d?{...d,extraParams:{...d.extraParams,prompt:"login"}}:void 0,{loginUrl:w,cookies:h={}}=g&&y(g,U,o)||{},m=t.globalData.auth?.devLogin||u.length>1?H(o):w;return Object.keys(h).forEach(c=>{A(r,c,h[c].value,h[c].options)}),m?r.newResponse(null,302,{Location:m}):r.text("Unauthorized",401)}const L={};async function z(r,t,o,n,a){let e=L[n];if(!e){const i={templateId:String(a||n),fsPath:"/",...o,baseSlug:o.slug};e=(await _(i,{},r,t,v)).html,L[n]=e}return r.html(e,n,{"Cache-Control":b})}function H(r){const t=new URLSearchParams({redirectTo:f(r)});return`${f(E)}?${t}`}async function T(r){return r.text("Forbidden",P(r))}function k(r){return r.json({message:"Forbidden"},P(r))}function P(r){const{isAuthenticated:t}=r.get("auth");return t?403:401}function G(r){const t=r?.match(/(?:^|:)(\d{1,3}(?:\.\d{1,3}){3})$/);return t?t[1]:r}export{H as getLoginUrlWithRedirect,z as handleErrorPageRender,S as handleUnauthorized,k as handleUnauthorizedApiRequest,T as handleUnauthorizedAsset,G as normalizeIpAddress};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/reef",
3
- "version": "0.132.0-next.7",
3
+ "version": "0.132.0-next.8",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {