@redocly/redoc-revel 0.133.0-next.5 → 0.133.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # @redocly/redoc-revel
2
2
 
3
+ ## 0.133.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0f097a8536: Added multi-version API support for Docs MCP tools.
8
+ - e2b2f2e27f: Improved visibility and accessibility of Markdown links by adding an underline.
9
+ - 76cad3a2f3: Updated styles for page navigation buttons.
10
+ - b5906fb936: Updated the icon displayed alongside hyperlinks in the project.
11
+ - 0858f54ae5: Added Client ID Metadata Document (CIMD) support to the MCP OAuth flow.
12
+ - f2f525c850: Added support for callback URLs in `developerOnboarding`.
13
+ - 7e407eeb7c: Added `hreflang` alternate links for translated pages.
14
+ - 7e407eeb7c: Improved language picker accessibility by converting menu options to links.
15
+
16
+ ### Patch Changes
17
+
18
+ - e271a42c40: Prevented search engines from indexing Markdown pages generated by the `llms.txt` feature.
19
+ - ba76c06785: Fixed unauthenticated callback execution in the MCP docs server.
20
+ - 3367a23fae: Fixed an issue in OpenAPI docs route resolution where lines not tied to an operation generated incorrect URLs by duplicating the base slug.
21
+ - e13c79eb30: Fixed an issue where searching in projects without searchable content caused a server error.
22
+ - 36c67eafc2: Fixed rendering of non-Latin characters by enforcing UTF-8 encoding.
23
+ - f7725b9cc7: Fixed an issue where login and logout redirects caused 404 and URI mismatch errors in projects with path prefix.
24
+ - eeb767e9b4: Fixed an issue where preview login redirects failed when the branch hostname contained double hyphens.
25
+ - 49d39a0486: Fixed 404 error when opening login from locale-prefixed URLs.
26
+ - fac8607a7b: Fixed an issue where closing the search dialog modal locked page scrolling.
27
+ - 7cd2d9f19e: Fixed an issue in Realm Markdown image handling where inline `data:` image URLs were incorrectly treated as broken local routes.
28
+ - 84838a59f0: Excluded buttons and links from heading content to improve accessibility.
29
+ - 4d93e20695: Fixed an issue where MCP connect actions were hidden for OpenAPI pages excluded from search (`openapi.excludeFromSearch`).
30
+ - c9c36d6ac3: Fixed curation in Typesense search.
31
+ - 7447d30745: Fixed security vulnerabilities `CVE-2026-44455`, `CVE-2026-44456`, `CVE-2026-44457`, `CVE-2026-44458` and `CVE-2026-44459` by upgrading `hono` to version `4.12.18`.
32
+ - a1bb760b29: Fixed an issue where the tooltips in API docs and Replay might partially render outside the viewport.
33
+ - c768a98d39: Fixed an issue where operation-level `x-rbac` rules removed the OpenAPI definition link from `llms.txt`.
34
+ - ba76c06785: Fixed an issue where MCP auth URLs were displayed after MCP docs had been disabled.
35
+ - 46f103f0c4: Updated `@redocly/openapi-core` to version `2.30.5`.
36
+ - 9f60402b86: Fixed an issue where navigating on a code walkthrough page prevented automatic scrolling to the active step.
37
+ - 49d39a0486: Fixed an issue where the login page didn't respect language preferences selected by the user.
38
+ - Updated dependencies [e2b2f2e27f]
39
+ - Updated dependencies [76cad3a2f3]
40
+ - Updated dependencies [3367a23fae]
41
+ - Updated dependencies [b5906fb936]
42
+ - Updated dependencies [36c67eafc2]
43
+ - Updated dependencies [f2f525c850]
44
+ - Updated dependencies [49d39a0486]
45
+ - Updated dependencies [f2a18386e5]
46
+ - Updated dependencies [7e407eeb7c]
47
+ - Updated dependencies [fac8607a7b]
48
+ - Updated dependencies [5e5d990eac]
49
+ - Updated dependencies [84838a59f0]
50
+ - Updated dependencies [4d93e20695]
51
+ - Updated dependencies [7e407eeb7c]
52
+ - Updated dependencies [a1bb760b29]
53
+ - Updated dependencies [ab8c509bb9]
54
+ - Updated dependencies [e5a4a33708]
55
+ - Updated dependencies [4a857b489d]
56
+ - Updated dependencies [46f103f0c4]
57
+ - Updated dependencies [59198fb803]
58
+ - Updated dependencies [9f60402b86]
59
+ - Updated dependencies [4002f20f63]
60
+ - Updated dependencies [62ea0748ec]
61
+ - @redocly/theme@0.65.0
62
+ - @redocly/openapi-docs@3.21.0
63
+ - @redocly/asyncapi-docs@1.10.0
64
+ - @redocly/graphql-docs@1.10.0
65
+ - @redocly/realm-asyncapi-sdk@0.11.0
66
+ - @redocly/portal-plugin-mock-server@0.18.0
67
+ - @redocly/portal-legacy-ui@0.16.0
68
+
69
+ ## 0.133.0-next.6
70
+
71
+ ### Patch Changes
72
+
73
+ - eeb767e9b48: Fixed an issue where preview login redirects failed when the branch hostname contained double hyphens.
74
+ - 7cd2d9f19e6: Fixed an issue in Realm Markdown image handling where inline `data:` image URLs were incorrectly treated as broken local routes.
75
+ - c9c36d6ac34: Fixed an issue where Typesense search didn't resolve types for curation fields.
76
+ - 7447d307450: Fixed security vulnerabilities `CVE-2026-44455`, `CVE-2026-44456`, `CVE-2026-44457`, `CVE-2026-44458` and `CVE-2026-44459` by upgrading `hono` to `4.12.18`.
77
+ - 46f103f0c48: Updated `@redocly/openapi-core` to version `2.30.5`.
78
+ - Updated dependencies [5e5d990eacb]
79
+ - Updated dependencies [46f103f0c48]
80
+ - @redocly/realm-asyncapi-sdk@0.11.0-next.4
81
+ - @redocly/openapi-docs@3.21.0-next.6
82
+ - @redocly/theme@0.65.0-next.5
83
+ - @redocly/portal-plugin-mock-server@0.18.0-next.6
84
+ - @redocly/asyncapi-docs@1.10.0-next.6
85
+ - @redocly/graphql-docs@1.10.0-next.6
86
+
3
87
  ## 0.133.0-next.5
4
88
 
5
89
  ### Minor Changes
@@ -179,7 +263,7 @@
179
263
  - e88064ce2d: Added support for Excalidraw and PlantUML diagrams.
180
264
  Improved dark mode for Mermaid diagrams.
181
265
  - ae3272861b: Added support for `x-badges` in OpenAPI and AsyncAPI parameters and schema properties.
182
- Badges can now be rendered before and after field names.
266
+ Badges can be rendered before and after field names.
183
267
  - ce5a165177: Added support for `or` functions in RBAC conditions within Markdoc content.
184
268
 
185
269
  ### Patch Changes
@@ -396,7 +480,7 @@
396
480
  - 60b9b77bc39: Fixed a bug that caused search result highlighting to break in Flexsearch when the query contained duplicate words.
397
481
  - f1edba375c0: Updated translate memoization to depend on the active language, ensuring hooks recompute and translations update on language switch.
398
482
  - ae3272861b4: Added support for `x-badges` in OpenAPI and AsyncAPI parameters and schema properties.
399
- Badges can now be rendered before and after field names.
483
+ Badges can be rendered before and after field names.
400
484
  - 87a97521127: Fixed an issue where `partial` Markdoc tags in OpenAPI and AsyncAPI `description` fields did not resolve when path separators differed.
401
485
  - Updated dependencies [4003b73d9ca]
402
486
  - Updated dependencies [ae3272861b4]
@@ -489,14 +573,14 @@
489
573
  - f7b6c52055: Improved appearance and deep linking for the `tabs` Markdoc tag.
490
574
  - d0b99c0768: Fixed URL fragment duplication when opening docs for endpoints with path parameters (e.g. `/foo/{id}/bar`).
491
575
  - 2d305eec36: Fixed the built-in CORS proxy failing with "fetch failed" for certain URLs.
492
- Now the browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
576
+ The browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
493
577
  - 1eb287db9f: Fixed code sample generation when path parameter examples contain integer values.
494
578
  - 807547ecbd: Improved build memory usage for large projects.
495
579
  - 7276b4e5d6: Fixed an issue in AI Search where clearing the product tag would still include the product in the search request.
496
580
  - a9a1ee0fe1: Fixed an issue where page actions remained visible even though `search` was disabled.
497
581
  - 9b9b43a1b4: Improved the accessibility of AsyncAPI docs.
498
582
  - 1cc1909566: Fixed an issue where optional properties of API operations were inconsistently displayed between API docs and Replay.
499
- The optional properties are now respect the configuration in `redocly.yaml`.
583
+ The optional properties respect the configuration in `redocly.yaml`.
500
584
  - 130c111688: Fixed security vulnerability `CVE-2026-26996` by upgrading `minimatch` to version `10.2.1`.
501
585
  - 7e3400d4a8: Fixed page actions overlapping the navbar.
502
586
  - d264713872: Fixed an issue where `rbac` configuration ignored versioned content folder paths with leading slashes.
@@ -559,7 +643,7 @@
559
643
  ### Patch Changes
560
644
 
561
645
  - 2d305eec36a: Fixed the built-in CORS proxy failing with "fetch failed" for certain URLs.
562
- Now the browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
646
+ The browser's `accept-encoding` header isn't forwarded and the error message surfaces the underlying cause.
563
647
 
564
648
  ## 0.131.0-next.13
565
649
 
@@ -589,7 +673,7 @@
589
673
  - 43955ab32fd: Improved the accessibility of OpenAPI and GraphQL docs.
590
674
  - 7276b4e5d63: Fixed an issue in AI Search where clearing the product tag would still include the product in the search request.
591
675
  - 1cc1909566f: Fixed an issue where optional properties of API operations were inconsistently displayed between API docs and Replay.
592
- The optional properties are now displayed or hidden according to configuration in `redocly.yaml`.
676
+ The optional properties are displayed or hidden according to configuration in `redocly.yaml`.
593
677
  - d59b5669cea: Updated `@redocly/openapi-core` to version `2.20.4`.
594
678
  - Updated dependencies [43955ab32fd]
595
679
  - Updated dependencies [7276b4e5d63]
@@ -845,7 +929,7 @@
845
929
  - ac12b3523a: Added an interactive lightbox viewer for Mermaid diagrams with zoom, pan, and keyboard navigation.
846
930
  - 85818157d8: Added bundling support for OpenAPI 3.2 `components/mediaTypes` references used in request and response content.
847
931
  - 1ff6da217d: Added support for branch-specific configuration in `redocly.yaml`.
848
- - 12fd642835: Transitioned AI Search to agent mode, now featuring expanded search capabilities and direct integration with the Docs MCP.
932
+ - 12fd642835: Transitioned AI Search to agent mode, featuring expanded search capabilities and direct integration with the Docs MCP.
849
933
  - ec292cdaaa: Made the **403 Forbidden** error page layout ejectable and improved its styling.
850
934
  - f117f86b3b: Added `login-button` Markdoc tag to render a login button on project pages.
851
935
  - 053051e82f: Added `rbac` support for banners to allow conditional visibility based on user team membership.
@@ -913,7 +997,7 @@
913
997
 
914
998
  ### Minor Changes
915
999
 
916
- - 12fd642835: Transitioned AI Search to agent mode, now featuring expanded search capabilities and direct integration with the Docs MCP.
1000
+ - 12fd642835: Transitioned AI Search to agent mode, featuring expanded search capabilities and direct integration with the Docs MCP.
917
1001
  - 053051e82f: Added `rbac` support for banners to allow conditional visibility based on user team membership.
918
1002
 
919
1003
  ### Patch Changes
@@ -3821,25 +3905,25 @@
3821
3905
  - 86f7780631: Added AI conversations UI with follow up questions.
3822
3906
  Added configurable suggestions to AI search.
3823
3907
  - ec9eff8ad9: Added support for partial loading of items included in large OpenAPI descriptions to improve performance.
3824
- Now, if a `tag` has more than 15 operations, the items are loaded quicker.
3908
+ If a `tag` has more than 15 operations, the items are loaded quicker.
3825
3909
 
3826
3910
  ### Patch Changes
3827
3911
 
3828
3912
  - 470c8696d4: Fixed an issue with links inside Markdown files, where links to OpenAPI documents were not resolved properly.
3829
3913
  - 27ac3236e5: Fixed an issue that caused launching with the `redocly preview` command to fail if you installed dependencies using `yarn`.
3830
3914
  - 99358a34e5: Resolved an issue where switching to a product opened a non-priority page instead of an index page.
3831
- Now, if a product has an index page, it is displayed first.
3915
+ If a product has an index page, it is displayed first.
3832
3916
  - 0cbb078d72: Updated version of the `@redocly/openapi-core` dependency to `1.31.1`.
3833
3917
  - 9e76b1f148: Updated version of the `@markdoc/markdoc` from `0.4.0` to `0.5.1`
3834
3918
  - 34a049d3d0: Fixed an issue where Markdown pages with `frontmatter.slug` directed users to a 404 error page when selected in a different language locale.
3835
3919
  - 03608f2a01: Fixed AI search error handling for Unauthorized and Forbidden errors.
3836
3920
  - a85ddf0b86: Resolved an issue with AI search resource styles being overridden by custom styles for `<Tag>` component.
3837
- - 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are now executed on navigation.
3921
+ - 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are executed on navigation.
3838
3922
  - c34c0da390: Fixed an issue where in development mode updates to `redocly.yaml` config were processed much longer than updates to other files.
3839
3923
  - 463b9fb93e: Fixed an issue where the `navigation.nextButton.text` and `navigation.previousButton.text` config properties did not change the text of the navigation buttons.
3840
3924
  - 7e80929731: Fixed an issue where the SEO `meta` tags were not updated during navigation between pages.
3841
3925
  - b74163612d: Resolved an issue where active operation items were incorrectly rendered on the server side.
3842
- - 074dc10262: Improved the check for the `Complex` badge in `openapi-docs`. The badge now appears only when the nesting of `allOf` exceeds 5 levels.
3926
+ - 074dc10262: Improved the check for the `Complex` badge in `openapi-docs`. The badge appears only when the nesting of `allOf` exceeds 5 levels.
3843
3927
  - bcb712fe03: Resolved an issue where the discriminator did not update the property type.
3844
3928
  - 328b992074: Resolved an issue where an additional slash was incorrectly added to the URL in code samples when using server variables.
3845
3929
 
@@ -3908,9 +3992,9 @@
3908
3992
  ### Patch Changes
3909
3993
 
3910
3994
  - 99358a34e5: Resolved an issue where switching to a product opened a non-priority page instead of an index page.
3911
- Now, if a product has an index page, it is displayed first.
3995
+ If a product has an index page, it is displayed first.
3912
3996
  - 34a049d3d0: Fixed an issue where Markdown pages with `frontmatter.slug` directed users to a 404 error page when selected in a different language locale.
3913
- - 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are now executed on navigation.
3997
+ - 6b9933d961: Fixed script handling in single page application (SPA) mode. Inline scripts are executed on navigation.
3914
3998
  - Updated dependencies [bcb712fe03]
3915
3999
  - Updated dependencies [ec9eff8ad9]
3916
4000
  - @redocly/openapi-docs@3.7.0-next.2
@@ -4014,7 +4098,7 @@
4014
4098
  ### Minor Changes
4015
4099
 
4016
4100
  - bc13399880: Enhanced development mode error handling showing compilation errors instead of `Internal Server Error` page.
4017
- CSS errors now display in an a toast message.
4101
+ CSS errors display in an a toast message.
4018
4102
  Pages automatically rebuild after fixing errors without server restart.
4019
4103
 
4020
4104
  ## 0.115.1
@@ -4111,8 +4195,8 @@
4111
4195
  ### Patch Changes
4112
4196
 
4113
4197
  - a058d3103e: Improved the OpenAPI definition bundling error message by including the path to the file, making it easier to identify the location of the error.
4114
- - f08b1cfdd2: Headers are now excluded from page data for anonymous users to prevent potential cache deception attacks.
4115
- - 7a285f0828: Improved AI search dialog: now links opening in new tabs, the search button is always enabled, and the search field label is updated.
4198
+ - f08b1cfdd2: Headers are excluded from page data for anonymous users to prevent potential cache deception attacks.
4199
+ - 7a285f0828: Improved AI search dialog: links opening in new tabs, the search button is always enabled, and the search field label is updated.
4116
4200
  - 44110c4c7c: Changed the text color in the total page counter to improve readability in light mode.
4117
4201
  - 698f536b5c: Updated version of the `@redocly/openapi-core` dependency to `1.26.1`.
4118
4202
  - Updated dependencies [44110c4c7c]
@@ -4184,7 +4268,7 @@
4184
4268
  ### Patch Changes
4185
4269
 
4186
4270
  - 5ffc1db4e8: Updated version of the `@redocly/openapi-core` dependency to `1.26.0`.
4187
- - 001406d157: Improved error handling in the project: project pages that display an error message are now automatically refreshed after the user resolves the error in the editor.
4271
+ - 001406d157: Improved error handling in the project: project pages that display an error message are automatically refreshed after the user resolves the error in the editor.
4188
4272
  This occurs both for Reunite and local projects.
4189
4273
  - Updated dependencies [5ffc1db4e8]
4190
4274
  - Updated dependencies [b6b91308d6]
@@ -4372,7 +4456,7 @@
4372
4456
 
4373
4457
  ### Patch Changes
4374
4458
 
4375
- - ae03d1fc71: Improved the `output` property for `apis` configuration. The property now works as a reference from `openapi` Markdoc tags.
4459
+ - ae03d1fc71: Improved the `output` property for `apis` configuration. The property works as a reference from `openapi` Markdoc tags.
4376
4460
  - be7d2e6286: Fixed an issue where if you set `REDOCLY_PREFIX_PATHS` in the environment variables for a project, the Reunite Webview would stop updating based on the page selected in the editor.
4377
4461
  - Updated dependencies [9574a87b33]
4378
4462
  - Updated dependencies [47065856c6]
@@ -4562,7 +4646,7 @@
4562
4646
 
4563
4647
  ### Patch Changes
4564
4648
 
4565
- - 5e5916b415: Resolved an issue that caused the page to crash when using the OpenAPI Code Sample Markdoc tags if the `descriptionFile` value was an incorrect path. Now if the path is invalid, users are presented with an error directing them to correct it.
4649
+ - 5e5916b415: Resolved an issue that caused the page to crash when using the OpenAPI Code Sample Markdoc tags if the `descriptionFile` value was an incorrect path. If the path is invalid, users are presented with an error directing them to correct it.
4566
4650
 
4567
4651
  ## 0.104.3
4568
4652
 
@@ -4896,8 +4980,8 @@
4896
4980
 
4897
4981
  ### Minor Changes
4898
4982
 
4899
- - 176b280257: Deprecated the `theme.imports` property. Themes and plugins must now be enabled through the `plugins` configuration property. Using the `theme.imports` does not fail the build for now, but produces warnings in the build log.
4900
- - 7e71bf855b: Deprecated the `theme` property of `redocly.yaml` config. All of the configuration properties under `theme` now reside in the root of the config.
4983
+ - 176b280257: Deprecated the `theme.imports` property. Themes and plugins must be enabled through the `plugins` configuration property. Using the `theme.imports` does not fail the build, but produces warnings in the build log.
4984
+ - 7e71bf855b: Deprecated the `theme` property of `redocly.yaml` config. All of the configuration properties under `theme` reside in the root of the config.
4901
4985
 
4902
4986
  ### Patch Changes
4903
4987
 
@@ -4994,13 +5078,13 @@
4994
5078
 
4995
5079
  ### Patch Changes
4996
5080
 
4997
- - ed391e8607: Resolved an issue with audience verification. Users without access permissions to the project are now redirected to the sign up page.
5081
+ - ed391e8607: Resolved an issue with audience verification. Users without access permissions to the project are redirected to the sign up page.
4998
5082
 
4999
5083
  ## 0.92.2
5000
5084
 
5001
5085
  ### Patch Changes
5002
5086
 
5003
- - 8b3aa69af2: Each error in the `redocly.yaml` file is now reported separately. Previously, all validation errors from `redocly.yaml` were bundled and reported as one error.
5087
+ - 8b3aa69af2: Each error in the `redocly.yaml` file is reported separately. Previously, all validation errors from `redocly.yaml` were bundled and reported as one error.
5004
5088
  - Updated dependencies [ac665b40f7]
5005
5089
  - Updated dependencies [a0e2645687]
5006
5090
  - Updated dependencies [c848158ee4]
@@ -5018,7 +5102,7 @@
5018
5102
 
5019
5103
  ### Minor Changes
5020
5104
 
5021
- - 2ad34ae141: **IMPORTANT**: Markdoc errors will now fail a production build.\
5105
+ - 2ad34ae141: **IMPORTANT**: Markdoc errors fail production builds.\
5022
5106
  To make Realm ignore Markdoc errors during production builds, set the `reunite.ignoreMarkdocErrors` property in `redocly.yaml` to `true`.
5023
5107
 
5024
5108
  ### Patch Changes
@@ -5085,7 +5169,7 @@
5085
5169
 
5086
5170
  ### Patch Changes
5087
5171
 
5088
- - 9f25cc7efb: References to partials `@i18n` folder using absolute links must now start with `/@i18n`. Previously, this part was omitted and the path would start from the locale directory name.
5172
+ - 9f25cc7efb: References to partials `@i18n` folder using absolute links must start with `/@i18n`. Previously, this part was omitted and the path would start from the locale directory name.
5089
5173
 
5090
5174
  ## 0.90.0
5091
5175
 
@@ -5140,7 +5224,7 @@
5140
5224
 
5141
5225
  - 0fdd7f22f9: Changed the order of moods in the mood feedback type to "from negative to positive".
5142
5226
  - 67100a3e83: fix(project): Adjusted cache headers to prevent browser caching to ensure users always receive the latest version of the content.
5143
- - fde6bd8184: Improved the default behavior for versioned items in sidebars. When items from different versioned folders are available, the sidebar now prefers and displays items with the same version as the currently active page.
5227
+ - fde6bd8184: Improved the default behavior for versioned items in sidebars. When items from different versioned folders are available, the sidebar prefers and displays items with the same version as the currently active page.
5144
5228
  - Updated dependencies [0fdd7f22f9]
5145
5229
  - Updated dependencies [1b6abdc7af]
5146
5230
  - @redocly/theme@0.38.2
@@ -5200,7 +5284,7 @@
5200
5284
  ### Patch Changes
5201
5285
 
5202
5286
  - e50e90b554: Fixed an issue when versioned content had a separate sidebars.yaml defined for each version, the navbar groups and separators were displayed for all versions of the content.
5203
- Now the navbar groups and separators are displayed only for the corresponding version chosen in the version picker.
5287
+ The navbar groups and separators are displayed only for the corresponding version chosen in the version picker.
5204
5288
 
5205
5289
  ## 0.88.2
5206
5290
 
@@ -1 +1 @@
1
- import{appendFile as E}from"node:fs/promises";import{existsSync as $}from"node:fs";import m from"node:path";import{Client as R}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as T,SEARCH_RBAC_FIELD as b,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as O,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as P,HIGHLIGHTED_TEXT_MAX_LENGTH as F,SEARCH_DATA_EXPORT_FOLDER as S,SEARCH_DOCUMENT_METADATA_KEY as N,SEARCH_GROUP_LIMIT as C,SEARCH_MAX_FACET_VALUES as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as v}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as I}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class Y{#e=null;#r="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:T,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:b,type:"string[]",facet:!0},{name:"metadata_curated",type:"auto",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"auto",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"auto",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#r=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new R({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(O);const{locale:o,outDir:n}=t,s=e.map(a=>{const r={...a},c=a[N];return c&&(c.curated&&(r.metadata_curated=c.curated),c.excludes&&(r.metadata_keywords_excludes=c.excludes),c.includes&&(r.metadata_keywords_includes=c.includes)),r}),i=this.#s.get(o)??[];this.#s.set(o,i.concat(s)),i.length+e.length>=v&&await this.exportDocuments(n)}async search(e){return await I("search",async t=>{const{query:o,locale:n,filter:s,loadMore:i,auth:a}=e,r=this.#c(n),c={collection:r,q:o||"*",query_by:this.#l(),max_facet_values:D};if(t?.setAttribute("collectionName",r),t?.setAttribute("locale",n),this.#e)if(i){const{groupKey:l,offset:u}=i,h={offset:u,filter_by:this.#o(a,s),facet_by:"*"};return t?.setAttribute("isLoadMore",!0),t?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(r).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:C,filter_by:this.#o(a,s)};t?.setAttribute("groups",l.group_by),t?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(a,s)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),s)}else return{facets:{},documents:{}}})}#u(e,t){const o={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const n of e.hits)o.documents[t].push({document:this.#a(n),highlight:this.#i(n)});return o}#f(e,t){const o={facets:{},documents:{}};for(const n of this.#_(t))o.documents[n]=[];if("results"in e)for(const n of e.results){if(n.facet_counts&&n.facet_counts.length)for(const s of n.facet_counts)o.facets[s.field_name]=s.counts.map(i=>({value:i.value,count:i.count}));if(n.grouped_hits&&n.grouped_hits.length)for(const s of n.grouped_hits){const i=s.group_key[0],a=[];for(const r of s.hits)a.push({document:this.#a(r),highlight:this.#i(r)});o.documents[i]=a}}return o}#a(e){return this.#h(e)}#i(e){const t={},o=[];for(const[n,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(n==="path"){const i=s,a=[];for(const r of i)a.push(r.snippet);t.path=a}else if(n==="parameters"){const i=s;for(const a of i){let r=!1;for(const[c,l]of Object.entries(a))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(r=!0);else l.matched_tokens?.length&&(r=!0);if(r){const c={name:a.name?.snippet||"",description:a.description?.snippet||"",place:a.place?.snippet||"",path:a.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[n]=s.snippet,o.push(n);for(const[n,s]of Object.entries(e.document))!o.includes(n)&&typeof s=="string"&&(t[n]=s.length>F?`${s.substring(0,F)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const o=Object.keys(e.highlight);for(const s of P)if(o.some(i=>i===s))return e.document;const n=e.highlight.parameters;if(n){for(const s of n)for(const[i,a]of Object.entries(s))if(i!=="deepLink"){if(Array.isArray(a)){for(const r of a)if(r.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(a.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',o=d(m.join(e,S));for(const[n,s]of this.#s){if(s.length===0)continue;const i=d(m.join(o,`${n}.json`)),a=!$(i),r=JSON.stringify(s).substring(1).slice(0,-1),c=a?t+r:","+r;await E(i,c,{encoding:"utf8"}),this.#s.set(n,[])}}async exportIndexes(e){const t=d(m.join(e,S));for(const o of this.#s.keys()){const n=d(m.join(t,`${o}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await E(n,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await I("search.facets",async o=>{const{locale:n,query:s,facetQuery:i,filter:a,field:r,auth:c}=e,l=this.#c(n),u={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(i,r),filter_by:this.#o(c,a,r),max_facet_values:D};if(o?.setAttribute("collectionName",l),o?.setAttribute("query",u.q),o?.setAttribute("facetQuery",u.facet_query),o?.setAttribute("filter",u.filter_by),this.#e){const h={},_=await this.#e.collections(l).documents().search(u);if(_.facet_counts&&_.facet_counts.length)for(const y of _.facet_counts)h[y.field_name]=y.counts.map(g=>({value:g.value,count:g.count,isCounterVisible:!!s||(a?.length||0)>0}));return h}else return{}})}#c(e){return`${this.#r}${e}`}#p(e){for(const[t,{queryable:o}]of e)this.#t.find(n=>n.name===t)||this.#t.push({queryable:o,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===A).map(e=>e.name).join(",")}#o(e,t,o){const n=`${b}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const i=t.filter(r=>r.field!==o&&r.field!==f).map(r=>{const c=r.values.map(l=>`'${l}'`);return c.length?`${r.field}:[${c.join(", ")}]`:""}).join(" && "),a=t.find(r=>r.field===f);if(a&&a.values.length&&a.values.length===2){const r=a.values[0],c=a.values[1],l=`(${f}.folderId:! ${r} && ${f}.isDefault:true)`,u=`(${f}.folderId:${r} && ${f}.version:${c})`;s=`(${l} || ${u})`}return i?`${n} && ${i} && ${s}`:`${n} && ${s}`}else return`${n} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const o of e)o.field===A&&t.push(...o.values);return t}#y(e,t){const o=[],n=this.#t.filter(s=>s.facet);for(const s of n){const i={facet_by:s.name,filter_by:this.#o(e,t,s.name)};o.push(i)}return o}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(o=>{o.values=[]}),e.setSearchFacets(t)}}export{Y as Typesense};
1
+ import{appendFile as E}from"node:fs/promises";import{existsSync as $}from"node:fs";import m from"node:path";import{Client as R}from"typesense";import{SEARCH_GROUP_FACET_FIELD as A,SEARCH_PRODUCT_FIELD as T,SEARCH_RBAC_FIELD as b,SEARCH_VERSION_FIELD as f}from"../../../../../constants/common.js";import{BASE_SEARCH_DOCUMENT as O,DISABLE_DEEP_LINK_IF_FIELDS_EXIST as P,HIGHLIGHTED_TEXT_MAX_LENGTH as F,SEARCH_DATA_EXPORT_FOLDER as S,SEARCH_DOCUMENT_METADATA_KEY as N,SEARCH_GROUP_LIMIT as C,SEARCH_MAX_FACET_VALUES as D,SEARCH_MAX_INMEMORY_DOCUMENTS_COUNT as v}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as I}from"../../../../telemetry/helpers/trace-step.js";import{envConfig as p}from"../../../../config/env-config.js";import{ensureDir as d}from"../../../../utils/index.js";class Y{#e=null;#o="";#t=[{name:"title",type:"string",facet:!1,optional:!0},{name:"text",type:"string",facet:!1,optional:!0},{name:"path",type:"string[]",facet:!1,optional:!0},{name:"isAdditionalOperation",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"parameters",type:"object[]",facet:!1,optional:!0},{name:T,type:"string",facet:!0,optional:!0},{name:f,type:"object",facet:!0,optional:!0},{name:b,type:"string[]",facet:!0},{name:"metadata_curated",type:"bool",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_excludes",type:"string[]",facet:!1,optional:!0,queryable:!1},{name:"metadata_keywords_includes",type:"string[]",facet:!1,optional:!0,queryable:!1}];#s=new Map;#n={ORGANIZATION_ID:p.ORGANIZATION_ID??"",PROJECT_ID:p.PROJECT_ID??"",TYPESENSE_API_URL:p.TYPESENSE_API_URL??"",TYPESENSE_API_KEY:p.TYPESENSE_API_KEY??""};constructor(){if(!p.isBuildMode){for(const[e,t]of Object.entries(this.#n))if(!t)throw new Error(`Cannot initialize search index. ${e} is not set`);this.#o=`${this.#n.ORGANIZATION_ID}_${this.#n.PROJECT_ID}_`,this.#e=new R({nodes:[{url:this.#n.TYPESENSE_API_URL}],apiKey:this.#n.TYPESENSE_API_KEY,connectionTimeoutSeconds:5})}}async initIndexSchema(e){this.#p(e)}async addDocuments(e,t){e.push(O);const{locale:r,outDir:n}=t,s=e.map(a=>{const o={...a},c=a[N];return c&&(c.curated&&(o.metadata_curated=c.curated),c.excludes&&(o.metadata_keywords_excludes=c.excludes),c.includes&&(o.metadata_keywords_includes=c.includes)),o}),i=this.#s.get(r)??[];this.#s.set(r,i.concat(s)),i.length+e.length>=v&&await this.exportDocuments(n)}async search(e){return await I("search",async t=>{const{query:r,locale:n,filter:s,loadMore:i,auth:a}=e,o=this.#c(n),c={collection:o,q:r||"*",query_by:this.#l(),max_facet_values:D};if(t?.setAttribute("collectionName",o),t?.setAttribute("locale",n),this.#e)if(i){const{groupKey:l,offset:u}=i,h={offset:u,filter_by:this.#r(a,s),facet_by:"*"};return t?.setAttribute("isLoadMore",!0),t?.setAttribute("filter",h.filter_by),this.#u(await this.#e.collections(o).documents().search({...c,...h}),l)}else{const l={group_by:this.#m(),group_limit:C,filter_by:this.#r(a,s)};t?.setAttribute("groups",l.group_by),t?.setAttribute("filter",l.filter_by);const u=[l,...this.#y(a,s)];return this.#f(await this.#e?.multiSearch.perform({searches:u},c),s)}else return{facets:{},documents:{}}})}#u(e,t){const r={facets:{},documents:{[t]:[]}};if(e.hits&&e.hits.length)for(const n of e.hits)r.documents[t].push({document:this.#a(n),highlight:this.#i(n)});return r}#f(e,t){const r={facets:{},documents:{}};for(const n of this.#_(t))r.documents[n]=[];if("results"in e)for(const n of e.results){if(n.facet_counts&&n.facet_counts.length)for(const s of n.facet_counts)r.facets[s.field_name]=s.counts.map(i=>({value:i.value,count:i.count}));if(n.grouped_hits&&n.grouped_hits.length)for(const s of n.grouped_hits){const i=s.group_key[0],a=[];for(const o of s.hits)a.push({document:this.#a(o),highlight:this.#i(o)});r.documents[i]=a}}return r}#a(e){return this.#h(e)}#i(e){const t={},r=[];for(const[n,s]of Object.entries(e.highlight??{}))if(Array.isArray(s)){if(n==="path"){const i=s,a=[];for(const o of i)a.push(o.snippet);t.path=a}else if(n==="parameters"){const i=s;for(const a of i){let o=!1;for(const[c,l]of Object.entries(a))if(c!=="deepLink")if(Array.isArray(l))for(const u of l)u.matched_tokens?.length&&(o=!0);else l.matched_tokens?.length&&(o=!0);if(o){const c={name:a.name?.snippet||"",description:a.description?.snippet||"",place:a.place?.snippet||"",path:a.path?.map(l=>l?.snippet)||[]};t.parameters=[c];break}}}}else t[n]=s.snippet,r.push(n);for(const[n,s]of Object.entries(e.document))!r.includes(n)&&typeof s=="string"&&(t[n]=s.length>F?`${s.substring(0,F)}...`:s);return t.parameters||(t.parameters=[]),t}#h(e){let t;const r=Object.keys(e.highlight);for(const s of P)if(r.some(i=>i===s))return e.document;const n=e.highlight.parameters;if(n){for(const s of n)for(const[i,a]of Object.entries(s))if(i!=="deepLink"){if(Array.isArray(a)){for(const o of a)if(o.matched_tokens?.length){t=s.deepLink.snippet;break}}else if(a.matched_tokens?.length){t=s.deepLink.snippet;break}}}if(t){const s=t.split("#")[1];return{...e.document,url:`${e.document.url}#${s}`}}return e.document}async exportDocuments(e){const t='{"documents":[',r=d(m.join(e,S));for(const[n,s]of this.#s){if(s.length===0)continue;const i=d(m.join(r,`${n}.json`)),a=!$(i),o=JSON.stringify(s).substring(1).slice(0,-1),c=a?t+o:","+o;await E(i,c,{encoding:"utf8"}),this.#s.set(n,[])}}async exportIndexes(e){const t=d(m.join(e,S));for(const r of this.#s.keys()){const n=d(m.join(t,`${r}.json`)),s=`],"schemaFields":${JSON.stringify(this.#t)}}`;await E(n,s,{encoding:"utf8"})}}async import(e){}async countFacets(e,t){return await I("search.facets",async r=>{const{locale:n,query:s,facetQuery:i,filter:a,field:o,auth:c}=e,l=this.#c(n),u={q:s||"*",query_by:this.#l(),facet_by:"*",facet_query:this.#d(i,o),filter_by:this.#r(c,a,o),max_facet_values:D};if(r?.setAttribute("collectionName",l),r?.setAttribute("query",u.q),r?.setAttribute("facetQuery",u.facet_query),r?.setAttribute("filter",u.filter_by),this.#e){const h={},_=await this.#e.collections(l).documents().search(u);if(_.facet_counts&&_.facet_counts.length)for(const y of _.facet_counts)h[y.field_name]=y.counts.map(g=>({value:g.value,count:g.count,isCounterVisible:!!s||(a?.length||0)>0}));return h}else return{}})}#c(e){return`${this.#o}${e}`}#p(e){for(const[t,{queryable:r}]of e)this.#t.find(n=>n.name===t)||this.#t.push({queryable:r,name:t,type:"string",facet:!0,optional:!0})}#l(){return this.#t.filter(e=>e.facet?e.queryable:e.queryable!==!1).map(e=>e.name).join(",")}#m(){return this.#t.filter(e=>e.facet&&e.name===A).map(e=>e.name).join(",")}#r(e,t,r){const n=`${b}:[${e.teams.map(i=>`'${i}'`).join(", ")}]`;let s=`${f}.isDefault:true`;if(t&&t.length){const i=t.filter(o=>o.field!==r&&o.field!==f).map(o=>{const c=o.values.map(l=>`'${l}'`);return c.length?`${o.field}:[${c.join(", ")}]`:""}).join(" && "),a=t.find(o=>o.field===f);if(a&&a.values.length&&a.values.length===2){const o=a.values[0],c=a.values[1],l=`(${f}.folderId:! ${o} && ${f}.isDefault:true)`,u=`(${f}.folderId:${o} && ${f}.version:${c})`;s=`(${l} || ${u})`}return i?`${n} && ${i} && ${s}`:`${n} && ${s}`}else return`${n} && ${s}`}#d(e,t){return e&&t?`${t}:${e}`:""}#_(e){const t=[];if(e&&e.length)for(const r of e)r.field===A&&t.push(...r.values);return t}#y(e,t){const r=[],n=this.#t.filter(s=>s.facet);for(const s of n){const i={facet_by:s.name,filter_by:this.#r(e,t,s.name)};r.push(i)}return r}cleanupFacetValues(e){const t=e.getSearchFacets();t.forEach(r=>{r.values=[]}),e.setSearchFacets(t)}}export{Y as Typesense};
@@ -1,12 +1,12 @@
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 L}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 w,JwtTokenExpired as oe}from"./jwt/types.js";import*as f from"./jwt/jwt.js";import{parseTeamClaimToArray as re}from"../utils/index.js";import{arrayBufferToBase64 as ae,decodeBase64 as P,encodeBase64URL as se,urlSafeBase64 as v}from"./jwt/encode.js";import{formatSamlCertificate as ce}from"./utils/format-saml-certificate.js";function E(e){return e?.type===u.OIDC}function ie(e){return e?.type===u.SAML2}async function Je(e,t){if(E(t))return ue(e,t);if(ie(t))return de(e,t)}async function ue(e,t){const o=await V(e,t),n=new Set((t.scopes||[]).concat(R)),r=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:o.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(n).join(" "),extraParams:r,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,o,n,r={}){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(o),grant_type:"authorization_code",...n.clientSecret?{client_secret:n.clientSecret}:{},...r}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function le(e,{authorizationEndpoint:t,clientId:o,responseType:n,scope:r,extraParams:a,idpId:s,pkce:d},m,A,p){if(!t||!o||!n||!r)return{loginUrl:void 0};const c=new URL(t),h=p?.redirectUriOverride??`${e}${G(N.OIDC_CALLBACK)}`,_={state:U(),idpId:s,redirectUri:h,redirectTo:m,branch:p?.branchOverride??me(e),inviteCode:A,source:p?.sourceOverride??"portal",uiLocales:p?.uiLocales},y={};if(d){const l=v(ne(50)),g=v(q("sha256").update(l).digest("base64")),x="S256";c.searchParams.append("code_challenge",g),c.searchParams.append("code_challenge_method",x),y.code_verifier={value:l,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:X()||"/"}}}c.searchParams.append("client_id",o),c.searchParams.append("scope",r),c.searchParams.append("response_type",n),c.searchParams.append("redirect_uri",j(h)),c.searchParams.append("state",se(JSON.stringify(_))),p?.uiLocales&&c.searchParams.append("ui_locales",p.uiLocales);for(const l in a)a[l]!==void 0&&c.searchParams.append(l,a[l]);return{loginUrl:c.toString(),cookies:y}}function We(e,t,o,n){const r=new URL(e);return r.searchParams.append("post_logout_redirect_uri",t),n&&r.searchParams.append("state",n),r.searchParams.append("id_token_hint",o),r.toString()}async function Ke(e){const t=Math.floor(Date.now()/1e3),o=t+(e.ttlSec??600);return f.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpAccessToken?{idp_access_token:e.idpAccessToken}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:o},L,w.HS256)}async function Ye(e){await f.verify(e,L,w.HS256);const{payload:t}=f.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(),o=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:o,object:"mcp_session",uri:`urn:redocly:realm:mcp:session:${o}`}}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 me(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,o,n,r){return pe(e)?le(t,e,o,n,{uiLocales:r}):fe(e)?he(t,e,o,n,r):{}}function he(e,t,o,n,r){const s=`<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 W}from"xml-crypto";import J from"xpath";import{deflateSync as q,inflateSync as K}from"fflate";import{createHash as Y}from"crypto";import{ulid as Q}from"ulid";import{AuthProviderType as u,DEFAULT_TEAM_CLAIM_NAME as X}from"@redocly/config";import{AUTH_URL as G,JWT_SECRET_KEY as L}from"../constants/common.js";import{envConfig as Z}from"../config/env-config.js";import{getPathPrefix as ee,withPathPrefix as te}from"@redocly/theme/core/utils";import{DEFAULT_AUTHENTICATED_TEAM as ne,REQUIRED_OIDC_SCOPES as D,ServerRoutes as v}from"../../constants/common.js";import{appendQueryParams as re}from"../../utils/url/append-query-params.js";import{parseHttpsUrl as R}from"../../utils/url/parse-https-url.js";import{logger as oe}from"../tools/notifiers/logger.js";import{randomString as ae}from"../utils/crypto/random-string.js";import{randomUUID as U}from"../utils/crypto/random-uuid.js";import{AlgorithmTypes as w,JwtTokenExpired as se}from"./jwt/types.js";import*as f from"./jwt/jwt.js";import{parseTeamClaimToArray as ie}from"../utils/index.js";import{arrayBufferToBase64 as ce,decodeBase64 as N,encodeBase64URL as ue,urlSafeBase64 as j}from"./jwt/encode.js";import{formatSamlCertificate as le}from"./utils/format-saml-certificate.js";function E(e){return e?.type===u.OIDC}function de(e){return e?.type===u.SAML2}async function Qe(e,t){if(E(t))return me(e,t);if(de(t))return pe(e,t)}async function me(e,t){const n=await H(e,t),r=new Set((t.scopes||[]).concat(D)),o=t.authorizationRequestCustomParams||{};return{type:u.OIDC,idpId:e,name:"OAuth provider",authorizationEndpoint:n.authorization_endpoint,clientId:t.clientId,responseType:"code",scope:Array.from(r).join(" "),extraParams:o,pkce:t.pkce}}function pe(e,t){return{type:u.SAML2,idpId:e,name:"SAML2 provider",ssoUrl:t.ssoUrl,issuerId:t.issuerId,entityId:t.entityId||t.issuerId}}async function Xe(e,t,n,r,o={}){const a=new Set((r.scopes||[]).concat(D));return await fetch(e,{method:"POST",body:new URLSearchParams({client_id:r.clientId,scope:Array.from(a).join(" "),code:t,redirect_uri:V(n),grant_type:"authorization_code",...r.clientSecret?{client_secret:r.clientSecret}:{},...o}).toString(),headers:{"Content-Type":"application/x-www-form-urlencoded",Accept:"application/json"}}).then(s=>s.json())}function fe(e,{authorizationEndpoint:t,clientId:n,responseType:r,scope:o,extraParams:a,idpId:s,pkce:l},m,A,p){if(!t||!n||!r||!o)return{loginUrl:void 0};const i=new URL(t),h=p?.redirectUriOverride??`${e}${te(v.OIDC_CALLBACK)}`,_={state:U(),idpId:s,redirectUri:h,redirectTo:m,branch:p?.branchOverride??he(e),inviteCode:A,source:p?.sourceOverride??"portal",uiLocales:p?.uiLocales},y={};if(l){const d=j(ae(50)),g=j(Y("sha256").update(d).digest("base64")),x="S256";i.searchParams.append("code_challenge",g),i.searchParams.append("code_challenge_method",x),y.code_verifier={value:d,options:{secure:!0,httpOnly:!0,expires:new Date(Date.now()+1e3*60*10),path:ee()||"/"}}}i.searchParams.append("client_id",n),i.searchParams.append("scope",o),i.searchParams.append("response_type",r),i.searchParams.append("redirect_uri",V(h)),i.searchParams.append("state",ue(JSON.stringify(_))),p?.uiLocales&&i.searchParams.append("ui_locales",p.uiLocales);for(const d in a)a[d]!==void 0&&i.searchParams.append(d,a[d]);return{loginUrl:i.toString(),cookies:y}}function Ge(e,t,n,r){const o=new URL(e);return o.searchParams.append("post_logout_redirect_uri",t),r&&o.searchParams.append("state",r),o.searchParams.append("id_token_hint",n),o.toString()}async function Ze(e){const t=Math.floor(Date.now()/1e3),n=t+(e.ttlSec??600);return f.sign({type:"mcp_auth_code",client_id:e.clientId,redirect_uri:e.redirectUri,id_token:e.idToken,...e.idpAccessToken?{idp_access_token:e.idpAccessToken}:{},...e.codeChallenge?{code_challenge:e.codeChallenge}:{},...e.codeChallengeMethod?{code_challenge_method:e.codeChallengeMethod}:{},iat:t,exp:n},L,w.HS256)}async function et(e){await f.verify(e,L,w.HS256);const{payload:t}=f.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 tt(e){const t=e||Q(),n=t.startsWith("mcp_")?t:`mcp_${t}`;return{id:n,object:"mcp_session",uri:`urn:redocly:realm:mcp:session:${n}`}}function V(e){const t=R(e);if(!t)return e;const n=ye(t.hostname);if(n)return t.hostname=`previewauth--${n.previewBranch}${n.after}`,$(e,t);const r=B(t.hostname);return r?(t.hostname=`${r.projectSlug}.previewauth.${r.after}`,$(e,t)):e}function he(e){const t=R(e);if(t)return B(t.hostname)?.previewBranch}function $(e,t){return e.replace(/^https:\/\/[^/?#]+/i,`https://${t.host}`)}function B(e){const t=e.split(".preview.",2);if(t.length<2)return null;const[n,r]=t,o=n.indexOf("--");if(o===-1)return null;const a=n.slice(0,o),s=n.slice(o+2);return!a||!s||s.includes(".")?null:{projectSlug:a,previewBranch:s,after:r}}function ye(e){const t=e.indexOf("."),n=t===-1?e:e.slice(0,t);if(!n.startsWith("preview-"))return null;const r=n.indexOf("--");if(r===-1)return null;const o=n.slice(r+2);if(!o)return null;const a=t===-1?"":e.slice(t);return{previewBranch:o,after:a}}function we(e){return e.type===u.OIDC}function Se(e){return e.type===u.SAML2}function nt(e,t,n,r,o){return we(e)?fe(t,e,n,r,{uiLocales:o}):Se(e)?Ae(t,e,n,r,o):{}}function Ae(e,t,n,r,o){const s=`<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
4
  ID="_${U()}"
5
5
  IssueInstant="${new Date().toISOString()}"
6
- AssertionConsumerServiceURL="${e}${N.SAML_CALLBACK}"
6
+ AssertionConsumerServiceURL="${e}${v.SAML_CALLBACK}"
7
7
  AttributeConsumingServiceIndex="0">
8
8
  <saml:Issuer>${t.entityId}</saml:Issuer>
9
9
  <samlp:NameIDPolicy
10
10
  AllowCreate="true"
11
11
  Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
12
- </samlp:AuthnRequest>`,d=ye(s);return{loginUrl:ee(t.ssoUrl,{SAMLRequest:d,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:o,inviteCode:n,source:"portal",uiLocales:r})})}}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 o=J(new Uint8Array(atob(e).split("").map(n=>n.charCodeAt(0))));return new TextDecoder().decode(o)}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],d=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||"",h=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],_=h&&h.nodeValue||"",y=i(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],l=y&&y.nodeValue||"",g=i(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],x=we(g),M={},k=i(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(k.length)for(const T of k){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:x,issuerId:d,entityId:A,attrs:M,cert:c,nameFormat:l,destination:a}}function we(e){const t=typeof e?.nodeValue=="string"&&I(Date.parse(e.nodeValue)),o=I(Date.now()),n=I(Date.now()+720*60*1e3);return t?t>o&&t<n?n:t:o}function I(e){return Math.floor(e/1e3)}const C={},S={jwks:{}};async function V(e,t){if(!C[e]){const o=t.configurationUrl?await $(t.configurationUrl):t.configuration;C[e]=Se()?Ae(o):o}return C[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 o of Object.keys(t)){const n=t[o];typeof n=="string"&&n.includes("://localhost")&&(t[o]=n.replace("://localhost","://host.docker.internal"))}return t}async function _e(e){for(const t of Object.keys(e)){const o=e[t];if(!E(o))continue;const n=await V(t,o);if(n.jwks_uri){const r=await $(n.jwks_uri);for(const a of r.keys)S.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=>ge(t.hostname,n))}function ge(e,t){return e===t||e.endsWith(`.${t}`)}async function ot(e,t){const o=new b().parseFromString(e,"application/xml"),n=i(o,"//*[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 r=ce(t),a=new B({publicCert:r});a.loadSignature(n);try{return a.checkSignature(e)}catch{return!1}}function rt(e,t,o,n){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=o["http://schemas.microsoft.com/identity/claims/objectidentifier"]);let r;(t==="urn:oasis:names:tc:SAML:2.0:nameid-format:email"||t==="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")&&(r=e),t==="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"&&e?.match(/.+@.+/)&&(r=e);const a=o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=a?.match(/.+@.+/);return r=r||o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?a:void 0),r=r?.toLowerCase(),{sub:e,given_name:o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:o["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:o["http://schemas.microsoft.com/identity/claims/displayname"]||a,email:r,email_verified:!0,teams:n?re(o[n]):[]}}function z(e,t={}){return e.map(o=>t[o]||o)}async function at(e,t){if(!t)return{};const o=t.authorization;if(!o)return{};try{const n=f.decode(o);if(n.header.alg===w.RS256){S.jwks[n.header.kid]===void 0&&await _e(e);const m=S.jwks[n.header.kid];if(!m)return S.jwks[n.header.kid]=null,{};await f.verify(o,m,w.RS256)}else await f.verify(o,L,w.HS256);const r=n.payload.idpId||S.jwks[n.header.kid]?.idpId,a=e[r]||{},s=Ie(a),d=Le(a);return{...n.payload,email:n.payload.email?.toLowerCase(),idpId:r,teams:Array.from(new Set([...z(n.payload.teams||[],d),..."defaultTeams"in a&&a.defaultTeams||[],...z("teamsClaimName"in a&&n.payload[s||""]||[],d),Z])),name:xe(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:o}}catch(n){n instanceof oe||te.error("Malformed JWT token: %s",n.message)}return{}}function xe(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Le(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Ie(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,le as buildOidcLoginUrl,We as buildOidcLogoutUrl,he as buildSAML2LoginUrl,Ke as createMcpAuthorizationCode,Qe as createMcpSessionResource,Ge as decodeSamlResponse,ye as encodeSAML2,rt as extractUserClaims,Je as getAuthProviderLoginParams,ue as getOidcLoginParams,V as getOidcMetadata,tt as getRedoclyTokenPayload,de as getSaml2LoginParams,at as getUserParamsFromCookies,xe as getUsernameFromPayload,E as isOidcProviderConfig,nt as isRedoclySso,ie as isSaml2ProviderConfig,qe as oidcExchangeCodeForToken,S as oidcJwksCache,C as oidcMetadataCache,Ze as parseOidcState,me as parsePreviewBranch,et as parseSamlResponse,j as rewritePreviewAuthRedirectUri,Ye as verifyMcpAuthorizationCode,ot as verifySAMLResponse};
12
+ </samlp:AuthnRequest>`,l=_e(s);return{loginUrl:re(t.ssoUrl,{SAMLRequest:l,RelayState:JSON.stringify({idpId:t.idpId,redirectTo:n,inviteCode:r,source:"portal",uiLocales:o})})}}function _e(e){return ce(q(new TextEncoder().encode(e)).buffer)}function rt(e){const t=N(e);if(t.startsWith("<samlp:Response")||t.indexOf("<saml2p:Response")>-1)return t;const n=K(new Uint8Array(atob(e).split("").map(r=>r.charCodeAt(0))));return new TextDecoder().decode(n)}function ot(e){try{return JSON.parse(N(e||""))}catch{throw new Error("Invalid OAuth2 state")}}function at(e){const t=new b().parseFromString(e,"application/xml"),r=c(t,"//*[local-name(.)='StatusCode']/@Value")[0]?.nodeValue?.endsWith("Success")||!1,a=c(t,"//*[local-name(.)='Response']/@Destination")[0]?.nodeValue||"",s=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='Issuer']/text()")[0],l=s&&s.nodeValue||void 0,m=c(t,"//*[local-name(.)='Audience']/text()")[0],A=m&&m.nodeValue||void 0,i=c(t,"//*[local-name(.)='Assertion']//*[local-name(.)='X509Certificate']/text()")[0]?.nodeValue||"",h=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/text()")[0],_=h&&h.nodeValue||"",y=c(t,"//*[local-name(.)='Subject']//*[local-name(.)='NameID']/@Format")[0],d=y&&y.nodeValue||"",g=c(t,"//*[local-name(.)='Conditions']/@NotOnOrAfter")[0],x=ge(g),C={},M=c(t,"//*[local-name(.)='AttributeStatement']//*[local-name(.)='Attribute']");if(M.length)for(const O of M){const P=c(O,"./@Name")[0];if(P.nodeValue){const T=c(O,"./*[local-name(.)='AttributeValue']/text()")[0];T?.nodeValue&&(C[P.nodeValue]=T.nodeValue)}}return{uid:_,success:r,expiresAt:x,issuerId:l,entityId:A,attrs:C,cert:i,nameFormat:d,destination:a}}function ge(e){const t=typeof e?.nodeValue=="string"&&I(Date.parse(e.nodeValue)),n=I(Date.now()),r=I(Date.now()+720*60*1e3);return t?t>n&&t<r?r:t:n}function I(e){return Math.floor(e/1e3)}const k={},S={jwks:{}};async function H(e,t){if(!k[e]){const n=t.configurationUrl?await z(t.configurationUrl):t.configuration;k[e]=xe()?Le(n):n}return k[e]}function xe(){const e=Z.REDOCLY_ENFORCE_RESIDENCY;return!!e&&e.includes("host.docker.internal")}function Le(e){if(typeof e!="object"||e===null)return e;const t={...e};for(const n of Object.keys(t)){const r=t[n];typeof r=="string"&&r.includes("://localhost")&&(t[n]=r.replace("://localhost","://host.docker.internal"))}return t}async function Ie(e){for(const t of Object.keys(e)){const n=e[t];if(!E(n))continue;const r=await H(t,n);if(r.jwks_uri){const o=await z(r.jwks_uri);for(const a of o.keys)S.jwks[a.kid]={...a,idpId:t}}}}async function z(e){return fetch(e,{headers:{Accept:"application/json"}}).then(t=>t.json())}async function st(e){return fetch(`${G}/oidc/userinfo`,{headers:{Accept:"application/json",Authorization:`Bearer ${e}`}}).then(t=>t.status===200?t.json():void 0).catch(()=>{})}function it(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(r=>ke(t.hostname,r))}function ke(e,t){return e===t||e.endsWith(`.${t}`)}async function ct(e,t){const n=new b().parseFromString(e,"application/xml"),r=c(n,"//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];if(!r)throw new Error("Cannot find Signature in the SAML response");const o=le(t),a=new W({publicCert:o});a.loadSignature(r);try{return a.checkSignature(e)}catch{return!1}}function ut(e,t,n,r){t==="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"&&(e=n["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=n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"],s=a?.match(/.+@.+/);return o=o||n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"]||(s?a:void 0),o=o?.toLowerCase(),{sub:e,given_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"],family_name:n["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"],name:n["http://schemas.microsoft.com/identity/claims/displayname"]||a,email:o,email_verified:!0,teams:r?ie(n[r]):[]}}function F(e,t={}){return e.map(n=>t[n]||n)}async function lt(e,t){if(!t)return{};const n=t.authorization;if(!n)return{};try{const r=f.decode(n);if(r.header.alg===w.RS256){S.jwks[r.header.kid]===void 0&&await Ie(e);const m=S.jwks[r.header.kid];if(!m)return S.jwks[r.header.kid]=null,{};await f.verify(n,m,w.RS256)}else await f.verify(n,L,w.HS256);const o=r.payload.idpId||S.jwks[r.header.kid]?.idpId,a=e[o]||{},s=Oe(a),l=Me(a);return{...r.payload,email:r.payload.email?.toLowerCase(),idpId:o,teams:Array.from(new Set([...F(r.payload.teams||[],l),..."defaultTeams"in a&&a.defaultTeams||[],...F("teamsClaimName"in a&&r.payload[s||""]||[],l),ne])),name:Ce(r.payload),isAuthenticated:!0,idpAccessToken:r.payload.idp_access_token||t.idp_access_token,federatedAccessToken:t.federated_access_token,federatedIdToken:t.federated_id_token,authCookie:n}}catch(r){r instanceof se||oe.error("Malformed JWT token: %s",r.message)}return{}}function Ce(e){return(e.firstName&&e.lastName?`${e.firstName} ${e.lastName}`:e.name||e.given_name||e.firstName||e.lastName)||e.email}function Me(e){switch(e.type){case u.SAML2:return e.teamsAttributeMap;case u.OIDC:return e.teamsClaimMap;default:return}}function Oe(e){switch(e.type){case u.SAML2:return e.teamsAttributeName;case u.OIDC:return e.teamsClaimName;default:return X}}function c(e,t){return J.select(t,e)||[]}export{nt as buildLoginUrl,fe as buildOidcLoginUrl,Ge as buildOidcLogoutUrl,Ae as buildSAML2LoginUrl,Ze as createMcpAuthorizationCode,tt as createMcpSessionResource,rt as decodeSamlResponse,_e as encodeSAML2,ut as extractUserClaims,Qe as getAuthProviderLoginParams,me as getOidcLoginParams,H as getOidcMetadata,st as getRedoclyTokenPayload,pe as getSaml2LoginParams,lt as getUserParamsFromCookies,Ce as getUsernameFromPayload,E as isOidcProviderConfig,it as isRedoclySso,de as isSaml2ProviderConfig,Xe as oidcExchangeCodeForToken,S as oidcJwksCache,k as oidcMetadataCache,ot as parseOidcState,he as parsePreviewBranch,at as parseSamlResponse,V as rewritePreviewAuthRedirectUri,et as verifyMcpAuthorizationCode,ct as verifySAMLResponse};
@@ -6,6 +6,7 @@
6
6
  * - It does not start with a protocol (e.g., `http://`, `https://`, `ftp://`, etc.).
7
7
  * - It does not start with `//` (protocol-relative URL).
8
8
  * - It does not start with `mailto:`.
9
+ * - It does not start with `data:` or `blob:` (inline / object URLs, not site paths).
9
10
  *
10
11
  * @param path - The input string (or null/undefined).
11
12
  * @returns `true` if the path is a local link, otherwise `false`.
@@ -1 +1 @@
1
- const s=t=>t!=null&&!t.match(/^[a-z]+:\/\//)&&!t.startsWith("//")&&!t.startsWith("mailto:");export{s as isLocalLink};
1
+ const s=t=>t!=null&&!t.match(/^[a-z]+:\/\//)&&!t.startsWith("//")&&!t.startsWith("mailto:")&&!t.startsWith("data:")&&!t.startsWith("blob:");export{s as isLocalLink};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Parses an absolute URL string; returns it only when the scheme is `https:`.
3
+ * Returns `null` on parse errors or for non-https schemes (e.g. `http:`, relative input).
4
+ *
5
+ * @param uri - Absolute URL string to parse.
6
+ * @returns A `URL` when the string is valid and uses `https:`; otherwise `null`.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * parseHttpsUrl('https://example.com/path');
11
+ * // URL { href: 'https://example.com/path' }
12
+ *
13
+ * parseHttpsUrl('http://example.com');
14
+ * // null
15
+ * ```
16
+ */
17
+ export declare function parseHttpsUrl(uri: string): URL | null;
18
+ //# sourceMappingURL=parse-https-url.d.ts.map
@@ -0,0 +1 @@
1
+ function n(r){try{const t=new URL(r);return t.protocol==="https:"?t:null}catch{return null}}export{n as parseHttpsUrl};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/redoc-revel",
3
- "version": "0.133.0-next.5",
3
+ "version": "0.133.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,7 @@
29
29
  "@opentelemetry/sdk-trace-web": "2.6.1",
30
30
  "@opentelemetry/semantic-conventions": "1.40.0",
31
31
  "@redocly/ajv": "8.18.0",
32
- "@redocly/openapi-core": "2.30.3",
32
+ "@redocly/openapi-core": "2.30.5",
33
33
  "@shikijs/transformers": "3.21.0",
34
34
  "@tanstack/react-query": "5.62.3",
35
35
  "@tanstack/react-table": "8.21.3",
@@ -53,7 +53,7 @@
53
53
  "flexsearch": "0.7.43",
54
54
  "graphql": "16.12.0",
55
55
  "gray-matter": "4.0.3",
56
- "hono": "4.12.14",
56
+ "hono": "4.12.18",
57
57
  "htmlparser2": "8.0.2",
58
58
  "i18next": "22.4.15",
59
59
  "is-glob": "4.0.3",
@@ -90,14 +90,14 @@
90
90
  "xpath": "0.0.34",
91
91
  "yaml-ast-parser": "0.0.43",
92
92
  "zod": "^3.25.76",
93
- "@redocly/asyncapi-docs": "1.10.0-next.5",
94
93
  "@redocly/config": "0.48.1",
95
- "@redocly/graphql-docs": "1.10.0-next.5",
96
- "@redocly/openapi-docs": "3.21.0-next.5",
97
- "@redocly/portal-legacy-ui": "0.16.0-next.0",
98
- "@redocly/portal-plugin-mock-server": "0.18.0-next.5",
99
- "@redocly/realm-asyncapi-sdk": "0.11.0-next.3",
100
- "@redocly/theme": "0.65.0-next.5"
94
+ "@redocly/graphql-docs": "1.10.0",
95
+ "@redocly/portal-legacy-ui": "0.16.0",
96
+ "@redocly/portal-plugin-mock-server": "0.18.0",
97
+ "@redocly/openapi-docs": "3.21.0",
98
+ "@redocly/realm-asyncapi-sdk": "0.11.0",
99
+ "@redocly/asyncapi-docs": "1.10.0",
100
+ "@redocly/theme": "0.65.0"
101
101
  },
102
102
  "peerDependencies": {
103
103
  "react": "^19.2.4",