@redocly/redoc-reef 0.132.0-next.0 → 0.132.0-next.1

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,28 @@
1
1
  # @redocly/redoc-reef
2
2
 
3
+ ## 0.132.0-next.1
4
+
5
+ ### Minor Changes
6
+
7
+ - 4003b73d9ca: Added `excalidraw` Markdoc tag to support Excalidraw integration.
8
+
9
+ ### Patch Changes
10
+
11
+ - 6561be12489: Fixed an issue where the "Last updated" date displayed incorrect values on project pages.
12
+ - 60b9b77bc39: Fixed a bug that caused search result highlighting to break in Flexsearch when the query contained duplicate words.
13
+ - ae3272861b4: Added support for `x-badges` in OpenAPI and AsyncAPI parameters and schema properties.
14
+ Badges can now be rendered before and after field names.
15
+ - 87a97521127: Fixed an issue where `partial` Markdoc tags in OpenAPI and AsyncAPI `description` fields did not resolve when path separators differed.
16
+ - Updated dependencies [4003b73d9ca]
17
+ - Updated dependencies [ae3272861b4]
18
+ - Updated dependencies [87a97521127]
19
+ - Updated dependencies [b24ffd4d9fb]
20
+ - @redocly/theme@0.64.0-next.1
21
+ - @redocly/asyncapi-docs@1.9.0-next.1
22
+ - @redocly/openapi-docs@3.20.0-next.1
23
+ - @redocly/graphql-docs@1.9.0-next.1
24
+ - @redocly/portal-plugin-mock-server@0.17.0-next.1
25
+
3
26
  ## 0.132.0-next.0
4
27
 
5
28
  ### Minor Changes
@@ -1 +1 @@
1
- import a from"i18next";import{useCallback as l}from"react";const s=(t,e)=>{let n=e&&typeof e=="string"?e:void 0,r=n?void 0:e;return t?a.t(t,{defaultValue:n,...r})||n||t||"":n??""},c=()=>({translate:l(s,[])});export{c as useTranslate};
1
+ import a from"i18next";import{useMemo as u}from"react";import{useL10n as o}from"./useL10n";const d=()=>{const{lang:r}=o();return{translate:u(()=>(n,t)=>{let e=t&&typeof t=="string"?t:void 0,s=e?void 0:t;return n?a.t(n,{defaultValue:e,...s})||e||n||"":e??""},[r])}};export{d as useTranslate};
@@ -0,0 +1,8 @@
1
+ import type { JSX } from 'react';
2
+ type ExcalidrawRendererProps = {
3
+ diagramSource: string;
4
+ className?: string;
5
+ };
6
+ export declare function ExcalidrawRenderer({ diagramSource, className, }: ExcalidrawRendererProps): JSX.Element;
7
+ export {};
8
+ //# sourceMappingURL=ExcalidrawRenderer.d.ts.map
@@ -0,0 +1,14 @@
1
+ import o,{useState as f,useEffect as g,useMemo as h,useRef as b}from"react";import x from"styled-components";import{useColorSwitcher as y}from"@redocly/theme/core/hooks";import{ExcalidrawDiagram as k}from"@redocly/theme/markdoc/components/ExcalidrawDiagram/ExcalidrawDiagram";import{SpinnerLoader as S}from"@redocly/theme/components/Loaders/SpinnerLoader";function F({diagramSource:n,className:v}){const{activeColorMode:w}=y(),[u,l]=f(null),[m,r]=f(null),c=b({}),i=w==="dark",s=i?"dark":"light",e=h(()=>{try{return{data:JSON.parse(n),error:null}}catch(a){return{data:null,error:a instanceof Error?a.message:"Failed to parse Excalidraw diagram"}}},[n]);return g(()=>{c.current={},l(null),r(null)},[n]),g(()=>{if(e.error){r(e.error);return}if(!e.data){r("Failed to parse Excalidraw diagram");return}const a=c.current[s];if(a){l(a),r(null);return}let d=!1;async function E(){try{const{exportToSvg:t}=await import("@excalidraw/excalidraw"),p=await t({elements:e.data?.elements||[],appState:{...e.data?.appState||{},exportWithDarkMode:i,exportBackground:!1},files:e.data?.files||null});d||(c.current[s]=p.outerHTML,l(p.outerHTML),r(null))}catch(t){d||r(t instanceof Error?t.message:"Failed to render Excalidraw diagram")}}return r(null),E(),()=>{d=!0}},[e,i,s]),m?o.createElement(M,{className:"excalidraw-wrapper"},m):u?o.createElement(k,{diagramHtml:u,className:v}):o.createElement(H,{className:"excalidraw-wrapper"},o.createElement(S,{color:"var(--border-color-secondary)",size:"32px"}))}const H=x.div`
2
+ background-color: var(--excalidraw-bg-color);
3
+ border-radius: var(--excalidraw-border-radius);
4
+ min-height: 200px;
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ `,M=x.div`
9
+ background-color: var(--admonition-danger-bg-color);
10
+ color: var(--admonition-danger-text-color);
11
+ border-radius: var(--excalidraw-border-radius);
12
+ padding: var(--spacing-md);
13
+ font-size: var(--font-size-sm);
14
+ `;export{F as ExcalidrawRenderer};
@@ -1,3 +1,4 @@
1
1
  export * from './html-script.js';
2
+ export * from './ExcalidrawRenderer.js';
2
3
  export declare function openapi(): Promise<typeof import("./openapi/index.js")>;
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- export*from"./html-script.js";async function n(){return await import("./openapi/index.js")}export{n as openapi};
1
+ export*from"./html-script.js";export*from"./ExcalidrawRenderer.js";async function n(){return await import("./openapi/index.js")}export{n as openapi};
@@ -1 +1 @@
1
- import a from"@markdoc/markdoc";import{isPrimitive as m}from"../../../utils/guards/is-primitive.js";import{isStringNode as s}from"../../helpers/guards/is-string-node.js";import{isTag as u}from"../../helpers/guards/is-tag.js";const g=a.nodes.fence,w={...g,attributes:{...g.attributes,label:{type:String,render:"data-label"},title:{type:String,render:"data-title"},highlight:{type:String,render:"data-highlight"}},transform(r,i){const e=r.transformAttributes(i);let t=r.transformChildren(i);const o=e["data-language"],l=e["data-title"];switch(r.attributes.process===!1&&(t=[r.attributes.content]),o){case"mermaid":return s(t[0])?new a.Tag("Mermaid",{...e,diagramSource:t[0]},t):new a.Tag(r.tag,e,t);default:const c=t.map(n=>m(n)?n.toString():u(n)?n?.attributes?.rawtag:"").join("");return s(t[0])?new a.Tag("CodeBlock",{...e,header:{title:l,controls:{copy:{}}},source:c,lang:o},[]):new a.Tag(r.tag,e,t)}}};export{w as fence};
1
+ import a from"@markdoc/markdoc";import{isPrimitive as u}from"../../../utils/guards/is-primitive.js";import{isStringNode as i}from"../../helpers/guards/is-string-node.js";import{isTag as m}from"../../helpers/guards/is-tag.js";const g=a.nodes.fence,h={...g,attributes:{...g.attributes,label:{type:String,render:"data-label"},title:{type:String,render:"data-title"},highlight:{type:String,render:"data-highlight"}},transform(e,s){const r=e.transformAttributes(s);let t=e.transformChildren(s);const o=r["data-language"],c=r["data-title"];switch(e.attributes.process===!1&&(t=[e.attributes.content]),o){case"mermaid":return i(t[0])?new a.Tag("Mermaid",{...r,diagramSource:t[0]},t):new a.Tag(e.tag,r,t);case"excalidraw":return i(t[0])?new a.Tag("ExcalidrawRenderer",{...r,diagramSource:t[0]},t):new a.Tag(e.tag,r,t);default:const l=t.map(n=>u(n)?n.toString():m(n)?n?.attributes?.rawtag:"").join("");return i(t[0])?new a.Tag("CodeBlock",{...r,header:{title:c,controls:{copy:{}}},source:l,lang:o},[]):new a.Tag(e.tag,r,t)}}};export{h as fence};
@@ -0,0 +1,3 @@
1
+ import type { CustomMarkdocTag } from '../types.js';
2
+ export declare const excalidraw: CustomMarkdocTag;
3
+ //# sourceMappingURL=excalidraw.d.ts.map
@@ -0,0 +1 @@
1
+ import a from"@markdoc/markdoc";import{RawContent as s}from"../attributes/raw-content.js";const c={schema:{attributes:{src:{type:s,required:!0},srcRawContent:{type:String,render:!1}},render:"ExcalidrawRenderer",selfClosing:!0,transform:(r,n)=>{const t=r.transformAttributes(n),e=r.attributes.srcRawContent;return typeof e=="string"?new a.Tag("ExcalidrawRenderer",{...t,diagramSource:e},[]):new a.Tag(r.tag,t,[])}},tagName:"excalidraw"};export{c as excalidraw};
@@ -4,6 +4,7 @@ import { openApiExample } from './openapi-example.js';
4
4
  import { replayOpenApi } from './replay-openapi.js';
5
5
  import { openApiResponseSample } from './openapi-response-sample.js';
6
6
  import { jsonExample } from './json-example.js';
7
+ import { excalidraw } from './excalidraw.js';
7
8
  declare const _default: {
8
9
  [jsonSchema.tagName]: import("@markdoc/markdoc").Schema & {
9
10
  dynamicComponentLib?: string;
@@ -23,6 +24,9 @@ declare const _default: {
23
24
  [jsonExample.tagName]: import("@markdoc/markdoc").Schema & {
24
25
  dynamicComponentLib?: string;
25
26
  };
27
+ [excalidraw.tagName]: import("@markdoc/markdoc").Schema & {
28
+ dynamicComponentLib?: string;
29
+ };
26
30
  };
27
31
  export default _default;
28
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- import{jsonSchema as m}from"./json-schema.js";import{openApiCodeSample as e}from"./openapi-code-sample.js";import{openApiExample as a}from"./openapi-example.js";import{replayOpenApi as p}from"./replay-openapi.js";import{openApiResponseSample as o}from"./openapi-response-sample.js";import{jsonExample as r}from"./json-example.js";var n={[m.tagName]:m.schema,[e.tagName]:e.schema,[a.tagName]:a.schema,[p.tagName]:p.schema,[o.tagName]:o.schema,[r.tagName]:r.schema};export{n as default};
1
+ import{jsonSchema as m}from"./json-schema.js";import{openApiCodeSample as a}from"./openapi-code-sample.js";import{openApiExample as e}from"./openapi-example.js";import{replayOpenApi as o}from"./replay-openapi.js";import{openApiResponseSample as p}from"./openapi-response-sample.js";import{jsonExample as r}from"./json-example.js";import{excalidraw as t}from"./excalidraw.js";var n={[m.tagName]:m.schema,[a.tagName]:a.schema,[e.tagName]:e.schema,[o.tagName]:o.schema,[p.tagName]:p.schema,[r.tagName]:r.schema,[t.tagName]:t.schema};export{n as default};
@@ -1,3 +1,3 @@
1
- import{spawn as h}from"child_process";import w from"path";async function v(a,l){if(!l)return new Map;let r,c;try{const t=await l.revparse(["--show-toplevel"]);r=new Set((await l.raw("ls-files",a)).split(`
2
- `).map(s=>s.trim()));const e=t&&w.relative(t,a);c=e&&e.length&&e.length+1||0}catch(t){if(t.message.includes("not a git repository"))return new Map;throw t}return new Promise(t=>{const e=new Map;let s=0;const o=h("git",["whatchanged","--pretty=%at","--",a],{stdio:"pipe"});let p="";function u(f){p+=String(f);const m=p.split(`
3
- `);p=m.pop()||"",m.forEach(i=>{if(i=i.trim(),!!i){if(i.startsWith(":")){const n=i.split(" ").slice(-1)[0].slice(c);if(e.has(n))return;r.has(n)&&r.delete(n),e.set(n,new Date(s*1e3).toISOString())}else s=Number(i);r.size===0&&(o.kill(),t(e))}})}o.stdout.on("data",f=>{u(f)}),o.stdout.on("end",()=>{u(""),o.kill(),t(e)})})}export{v as fastMtime};
1
+ import{spawn as w}from"child_process";import h from"path";async function v(a,l){if(!l)return new Map;let i,c;try{const t=await l.revparse(["--show-toplevel"]);i=new Set((await l.raw("ls-files",a)).split(`
2
+ `).map(s=>s.trim()));const e=t&&h.relative(t,a);c=e&&e.length&&e.length+1||0}catch(t){if(t.message.includes("not a git repository"))return new Map;throw t}return new Promise(t=>{const e=new Map;let s=0;const o=w("git",["log","--raw","--no-merges","--pretty=%at","--",a],{stdio:"pipe"});let p="";function m(f){p+=String(f);const u=p.split(`
3
+ `);p=u.pop()||"",u.forEach(r=>{if(r=r.trim(),!!r){if(r.startsWith(":")){const n=r.split(" ").slice(-1)[0].slice(c);if(e.has(n))return;i.has(n)&&i.delete(n),e.set(n,new Date(s*1e3).toISOString())}else s=Number(r);i.size===0&&(o.kill(),t(e))}})}o.stdout.on("data",f=>{m(f)}),o.stdout.on("end",()=>{m(""),o.kill(),t(e)})})}export{v as fastMtime};
@@ -1 +1 @@
1
- import{parse as d}from"path";function N(p){const a=p.split("/");let i=-1;for(let t=0;t<a.length;t++)if(a[t]==="@api"){i=t;break}let e="",r=p;i!==-1&&(e=a.slice(0,i).join("/"),r=a.slice(i+1).join("/"),e=e?`/${e}/api`:"/api");const{dir:c,name:o}=d(r),s=o.match(/\.(get|post|put|delete|patch)$/i),h=s?s[1]:"all",l=o.replace(/\.(get|post|put|delete|patch)$/,"");let n=c.split("/");l!=="index"&&n.push(l);const m=n.map(t=>t.startsWith("[...")&&t.endsWith("]")?`:${t.slice(4,-1)}{.+}`:t.startsWith("[")&&t.endsWith("]")?`:${t.slice(1,-1)}`:t).join("/");return{path:`${e}/${m}`.replace(/\/+/g,"/").replace(/\/$/,""),method:h,handler:p}}export{N as parseRouteFsPathForHono};
1
+ import{parse as o}from"path";function p(t){const e=t.split("/");let a=-1;for(let i=0;i<e.length;i++)if(e[i]==="@api"){a=i;break}if(a===-1)return{prefixPath:"",apiPath:t};const n=e.slice(0,a).join("/"),r=e.slice(a+1).join("/");return{prefixPath:n?`/${n}/api`:"/api",apiPath:r}}function c(t){const{dir:e,name:a}=o(t),n=a.match(/\.(get|post|put|delete|patch)$/i);return{dir:e,method:n?n[1]:"all",routeName:a.replace(/\.(get|post|put|delete|patch)$/,"")}}function s(t){return t.startsWith("[...")&&t.endsWith("]")?`:${t.slice(4,-1)}{.+}`:t.startsWith("[")&&t.endsWith("]")?`:${t.slice(1,-1)}`:t}function h(t,e){const a=t.split("/");return e!=="index"&&a.push(e),a}function u(t,e){return`${t}/${e.join("/")}`.replace(/\/+/g,"/").replace(/\/$/,"")}function f(t){const{prefixPath:e,apiPath:a}=p(t),{dir:n,routeName:r,method:i}=c(a);return{path:u(e,h(n,r).map(s)),method:i,handler:t}}export{f as parseRouteFsPathForHono};
@@ -1 +1 @@
1
- import{join as f}from"path";import{REDOCLY_ROUTE_RBAC as c}from"@redocly/config";import{removeTrailingSlash as d}from"../../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as m}from"../../../utils/url/remove-leading-slash.js";import{USER_DEFINED_API_FUNCTIONS_COUNTER_KEY as h}from"../../../server/store.js";import{parseRouteFsPathForHono as g}from"./helpers/parse-route-fs-path-for-hono.js";import{telemetryTraceStep as F}from"../../../cli/telemetry/helpers/trace-step.js";const R="api-functions";async function S(){return{id:"ApiFunctions",requiredEntitlements:["apiFunctions"],async processContent(n,i){await F("build.plugin.api_functions",async r=>{const s=await i.getConfig(),a=(s.apiFunctions?.folders||[]).map(e=>`^${m(d(e))}`);r?.setAttribute("config",JSON.stringify(s.apiFunctions||{})),a.push(".*@api");const l=new RegExp(`(${a.join("|")})/.*.(ts|js)$`);let o=0;for(const e of i.fs.scan(l)){if(e.isVirtual)continue;const t=g(e.relativePath);if(!t)continue;const u=`${R}:${t.handler}`,p=f(n.contentDir,t.handler);n.createRequestHandler(u,p),n.addApiRoute({requestHandlerId:u,slug:t.path,fsPath:e.relativePath,httpMethod:t.method,[c]:{fsPath:e.relativePath,slug:t.path}}),o++}r?.setAttribute("definedApiFunctions",String(o)),n.setGlobalConfig({[h]:o})})}}}export{R as API_FUNCTIONS_REQUEST_HANDLER_ID,S as apiFunctionsPlugin};
1
+ import{join as p}from"path";import{REDOCLY_ROUTE_RBAC as f}from"@redocly/config";import{removeTrailingSlash as l}from"../../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as d}from"../../../utils/url/remove-leading-slash.js";import{USER_DEFINED_API_FUNCTIONS_COUNTER_KEY as m}from"../../../server/store.js";import{parseRouteFsPathForHono as h}from"./helpers/parse-route-fs-path-for-hono.js";import{telemetryTraceStep as F}from"../../../cli/telemetry/helpers/trace-step.js";const g="api-functions";function A(t){return d(l(t))}function R(t){return`^${A(t)}`}function E(t){const i=t.map(R);return i.push(".*@api"),new RegExp(`(${i.join("|")})/.*.(ts|js)$`)}async function T(){return{id:"ApiFunctions",requiredEntitlements:["apiFunctions"],async processContent(t,i){await F("build.plugin.api_functions",async r=>{const s=await i.getConfig();r?.setAttribute("config",JSON.stringify(s.apiFunctions||{}));const a=E(s.apiFunctions?.folders||[]);let o=0;for(const e of i.fs.scan(a)){if(e.isVirtual)continue;const n=h(e.relativePath);if(!n)continue;const u=`${g}:${n.handler}`,c=p(t.contentDir,n.handler);t.createRequestHandler(u,c),t.addApiRoute({requestHandlerId:u,slug:n.path,fsPath:e.relativePath,httpMethod:n.method,[f]:{fsPath:e.relativePath,slug:n.path}}),o++}r?.setAttribute("definedApiFunctions",String(o)),t.setGlobalConfig({[m]:o})})}}}export{g as API_FUNCTIONS_REQUEST_HANDLER_ID,T as apiFunctionsPlugin};
@@ -1 +1 @@
1
- import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:e},t,{partials:a,variables:i},o)=>{const s=o.getPartialsForRoute?.(e)||a;return{definitionId:r,...t.props,markdown:{partials:s,variables:{...i,env:n()}}}};var d=l;export{d as default};
1
+ import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:t},a,{partials:i,variables:o},s)=>{const e=s.getPartialsForRoute?.(t);return{definitionId:r,...a.props,markdown:{partials:e&&Object.keys(e).length>0?e:i,variables:{...o,env:n()}}}};var c=l;export{c as default};
@@ -1 +1 @@
1
- import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as b}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getTemplatePath as R}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as F,asyncapiDocsLoader as N}from"./asyncapi-doc-loader.js";import{searchResolver as j}from"./search/search-resolver.js";import{getAiDocumentsStore as L}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as G}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function tt(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":F,"asyncapi-docs":N},processContent:async(e,a)=>{await G("build.plugin.asyncapi_docs",async()=>{if((await a.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,R("../../../client/templates/asyncapi-docs/template.js")),g=e.registerServerPropsGetter(v,R("./get-server-props.js"));for(const l of await a.fs.scan(/(\.ya?ml|\.json)$/))if(!await a.isPathIgnored(l.relativePath))try{const{data:s,compoundHash:w}=await a.cache.load(l.realRelativePath,"asyncapi-doc");if(!s?.length)continue;p=s.map(({markdocChunks:t,relativePath:o,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:o,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(s,e.outdir,w);for(const t of s){const o=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(b,`${C(t.relativePath,".json")}?download`)},{url:D(b,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(o,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(r=>{const n={fsPath:t.relativePath,slugSuffix:`/${r.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:o}],getStaticData:S(a.withPathPrefix,r.label),serverPropsGetterIds:[g]};e.addRoute(n),r.items&&r.items.forEach(i=>{e.addRoute({...n,slugSuffix:`/${i.link}`,getStaticData:S(a.withPathPrefix,i.label)}),i.items&&i.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(a.withPathPrefix,i.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:r=>{const n=i=>{const h={...i};return i.link&&(h.routeSlug=D(r.slug,i.link),h.link=D(r.slug,i.link)),i.items&&(h.items=i.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:r.slug,link:r.slug},...f.map(n)]},getSearchDocuments:j(e,t.document),getStaticData:S(a.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:L({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:o}]})}}catch(s){console.error(s)}})},afterRoutesCreated:async(e,a)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:s}of p){const w=e.getAllRoutes().filter(o=>o.fsPath===g).map(o=>o.slug),t=(await a.cache.load(s,"asyncapi-doc")).compoundHash;await a.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:r}of c){const{ast:n}=await e.parseMarkdoc({content:f,relativePath:y,isVirtual:l},a,{sharedDataIds:[`${_}${r}`],routeSlugs:w});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:o}of c)P.add(o)}const k=u.difference(P);for(const c of k)a.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{tt as asyncAPIDocsPlugin};
1
+ import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as R}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getRouteSlugsForPath as F}from"../utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as N,asyncapiDocsLoader as j}from"./asyncapi-doc-loader.js";import{searchResolver as L}from"./search/search-resolver.js";import{getAiDocumentsStore as G}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as M}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function ot(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":N,"asyncapi-docs":j},processContent:async(e,o)=>{await M("build.plugin.asyncapi_docs",async()=>{if((await o.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,b("../../../client/templates/asyncapi-docs/template.js")),g=e.registerServerPropsGetter(v,b("./get-server-props.js"));for(const l of await o.fs.scan(/(\.ya?ml|\.json)$/))if(!await o.isPathIgnored(l.relativePath))try{const{data:r,compoundHash:w}=await o.cache.load(l.realRelativePath,"asyncapi-doc");if(!r?.length)continue;p=r.map(({markdocChunks:t,relativePath:s,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:s,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(r,e.outdir,w);for(const t of r){const s=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(R,`${C(t.relativePath,".json")}?download`)},{url:D(R,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(s,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(i=>{const n={fsPath:t.relativePath,slugSuffix:`/${i.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:s}],getStaticData:S(o.withPathPrefix,i.label),serverPropsGetterIds:[g]};e.addRoute(n),i.items&&i.items.forEach(a=>{e.addRoute({...n,slugSuffix:`/${a.link}`,getStaticData:S(o.withPathPrefix,a.label)}),a.items&&a.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(o.withPathPrefix,a.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:i=>{const n=a=>{const h={...a};return a.link&&(h.routeSlug=D(i.slug,a.link),h.link=D(i.slug,a.link)),a.items&&(h.items=a.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:i.slug,link:i.slug},...f.map(n)]},getSearchDocuments:L(e,t.document),getStaticData:S(o.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:G({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:s}]})}}catch(r){console.error(r)}})},afterRoutesCreated:async(e,o)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:r}of p){const w=F(e.getAllRoutes(),g),t=(await o.cache.load(r,"asyncapi-doc")).compoundHash;await o.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:i}of c){const{ast:n}=await e.parseMarkdoc({content:f,relativePath:y,isVirtual:l},o,{sharedDataIds:[`${_}${i}`],routeSlugs:w});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:s}of c)P.add(s)}const k=u.difference(P);for(const c of k)o.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{ot as asyncAPIDocsPlugin};
@@ -1 +1 @@
1
- import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:e},t,{variables:a,partials:i},o)=>{const s=o.getPartialsForRoute?.(e)||i;return{definitionId:r,...t.props,markdown:{partials:s,variables:{...a,env:n()}}}};var d=l;export{d as default};
1
+ import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:t},a,{variables:i,partials:o},s)=>{const e=s.getPartialsForRoute?.(t);return{definitionId:r,...a.props,markdown:{partials:e&&Object.keys(e).length>0?e:o,variables:{...i,env:n()}}}};var c=l;export{c as default};
@@ -1 +1 @@
1
- import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as $,PUBLIC_RBAC_SCOPE_ITEM as j}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as oe,OPENAPI_SHARED_DATA_PREFIX as U}from"../../constants/plugins/openapi-docs.js";import{envConfig as V}from"../../config/env-config.js";import{searchResolver as ae}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as re,shouldAddRoute as se}from"./utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as ne}from"./store-definition-bundles.js";import{definitionLoader as ie,definitionsLoader as pe}from"./load-definition.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{fromCurrentDir as ce}from"../../utils/paths.js";import{telemetryTraceStep as le}from"../../../cli/telemetry/helpers/trace-step.js";const w="openapi-spec-download";async function Ce(){let M=[],R={},L=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":pe,"load-oas":ie},processContent:async(e,p)=>{await le("build.plugin.openapi_docs",async u=>{e.createRequestHandler(w,ce(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})});const A=e.createTemplate($,b("../../../client/templates/openapi-docs/template.js")),a=e.registerServerPropsGetter($,b("./get-server-props.js")),s=e.registerServerPropsGetter(oe,b("./get-server-props-custom-fields.js")),d=await p.getConfig();u?.setAttribute("config",JSON.stringify(d.openapi||{}));const g=d.rules?.["custom-fields-schema"];R={};const m=await e.loadOpenApiDefinitions(p);M=m.map(({markdocChunks:r,relativePath:f,customOutputRelativeFile:i,isVirtual:n,realRelativePath:c})=>({chunks:r,relativePath:f,realRelativePath:c,isVirtual:i!=null||n})),ne(m,e.outdir);const S={};for(const r of m||[]){const{definition:f,config:i,relativePath:n,customOutputRelativeFile:c,contentItems:_,flatItems:k,parser:E,options:B,rawOptions:q,hash:J}=r,N=c||n,o=[],x={},{definition:Q}=E||{},{info:l}=Q||{},v=l?.["x-metadata"],C=!!i.openapi?.excludeFromSearch||!!i.theme?.openapi?.excludeFromSearch||!!d.openapi?.excludeFromSearch||!!d.theme?.openapi?.excludeFromSearch,G={title:l?.title,description:l?.description,summary:l?.summary,...i.metadata,...v},h={untagged:[],tagged:new Map};for(const t of k){const{id:O,href:I,operationDefinition:y}=t;if(y){const{tags:P}=y;if(P)for(const T of P)h.tagged.has(T)||h.tagged.set(T,[]),h.tagged.get(T)?.push(t);else h.untagged.push(t);V.isDevelopMode&&(x[`#${y.pointer}`]=t.href)}if(!se({item:t}))continue;const F=t,Y=F.type==="section"&&!!F.infoDefinition,z=I.split("#")[0]+"/",K=t?.operationDefinition?.[D];o.push({excludeFromSearch:C,slugSuffix:z,fsPath:N,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:n,templateId:A,[D]:K||i.rbac,getAiDocumentsStore:de({parser:E,options:B,info:l,tagOperations:h,openapiContentItem:F,metadata:G,relativePath:n,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:Y,excludeFromSearch:C}),getStaticData:async P=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:P.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:O,disableAutoScroll:!0}})})}o[0]={...o[0],metadata:{type:"openapi",...G},hasClientRoutes:!0,getSidebar:(t,O)=>{const I=[];return re({contentItems:_,sidebarItems:I,routeSlug:t.slug,navItem:O}),I},getNavText:()=>l?.title,getSearchDocuments:ae(E,B,k,e.getSearchFacets,e.setSearchFacets,C)},v?.apiId&&(S[v.apiId]={slug:o[0]?.slug||""});const W=o[0];o[0]=o[o.length-1],o[o.length-1]=W;for(const t of o)e.addRoute({...t,serverPropsGetterIds:g?[a,s]:[a]});const X=V.isDevelopMode?n:void 0,H=`${U}${n}`;R[H]={fsPath:N,definition:f,options:q,sourcePath:X,routesMapping:x,hash:J};for(const t of o)e.addRoute({...t,sharedData:[{id:H,key:"openAPIDocsStore"}],serverPropsGetterIds:g?[a,s]:[a]})}e.setGlobalData({apiProducts:S})})},afterRoutesCreated:async(e,p)=>{const u=new Set;for(const{chunks:a,relativePath:s,isVirtual:d,realRelativePath:g}of M){const m=e.getAllRoutes().filter(r=>r.fsPath===s).map(r=>r.slug),S=(await p.cache.load(g,"load-oas")).compoundHash;await p.cache.load(s,{loader:async function(){for(const{node:f,markdown:i,key:n,relativePath:c}of a){const{ast:_}=await e.parseMarkdoc({content:i,relativePath:c,isVirtual:d},p,{sharedDataIds:[`${U}${c}`],routeSlugs:m});f[`x-parsed-md-${n}`]={result:Z(_)}}},name:"openapi-markdoc-inline-parser"},[S]);for(const{pointer:r}of a)u.add(r)}const A=L.difference(u);for(const a of A)p.cache.delete(a);L=u;for(const[a,s]of Object.entries(R))await e.createSharedData(a,{...s,baseSlug:e.getRouteByFsPath(s.fsPath)?.baseSlug},s.hash)}}}export{Ce as openAPIDocsPlugin};
1
+ import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as $,PUBLIC_RBAC_SCOPE_ITEM as j}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as oe,OPENAPI_SHARED_DATA_PREFIX as U}from"../../constants/plugins/openapi-docs.js";import{envConfig as V}from"../../config/env-config.js";import{getRouteSlugsForPath as ae}from"../utils.js";import{searchResolver as re}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as se,shouldAddRoute as ne}from"./utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as ie}from"./store-definition-bundles.js";import{definitionLoader as pe,definitionsLoader as de}from"./load-definition.js";import{getAiDocumentsStore as ce}from"./search/get-ai-search-documents.js";import{fromCurrentDir as le}from"../../utils/paths.js";import{telemetryTraceStep as ue}from"../../../cli/telemetry/helpers/trace-step.js";const w="openapi-spec-download";async function ye(){let M=[],R={},L=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":de,"load-oas":pe},processContent:async(e,i)=>{await ue("build.plugin.openapi_docs",async u=>{e.createRequestHandler(w,le(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})});const A=e.createTemplate($,b("../../../client/templates/openapi-docs/template.js")),a=e.registerServerPropsGetter($,b("./get-server-props.js")),r=e.registerServerPropsGetter(oe,b("./get-server-props-custom-fields.js")),p=await i.getConfig();u?.setAttribute("config",JSON.stringify(p.openapi||{}));const h=p.rules?.["custom-fields-schema"];R={};const m=await e.loadOpenApiDefinitions(i);M=m.map(({markdocChunks:d,relativePath:f,customOutputRelativeFile:n,isVirtual:s,realRelativePath:c})=>({chunks:d,relativePath:f,realRelativePath:c,isVirtual:n!=null||s})),ie(m,e.outdir);const S={};for(const d of m||[]){const{definition:f,config:n,relativePath:s,customOutputRelativeFile:c,contentItems:_,flatItems:k,parser:E,options:B,rawOptions:q,hash:J}=d,N=c||s,o=[],x={},{definition:Q}=E||{},{info:l}=Q||{},v=l?.["x-metadata"],C=!!n.openapi?.excludeFromSearch||!!n.theme?.openapi?.excludeFromSearch||!!p.openapi?.excludeFromSearch||!!p.theme?.openapi?.excludeFromSearch,G={title:l?.title,description:l?.description,summary:l?.summary,...n.metadata,...v},g={untagged:[],tagged:new Map};for(const t of k){const{id:O,href:I,operationDefinition:y}=t;if(y){const{tags:P}=y;if(P)for(const T of P)g.tagged.has(T)||g.tagged.set(T,[]),g.tagged.get(T)?.push(t);else g.untagged.push(t);V.isDevelopMode&&(x[`#${y.pointer}`]=t.href)}if(!ne({item:t}))continue;const F=t,Y=F.type==="section"&&!!F.infoDefinition,z=I.split("#")[0]+"/",K=t?.operationDefinition?.[D];o.push({excludeFromSearch:C,slugSuffix:z,fsPath:N,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:s,templateId:A,[D]:K||n.rbac,getAiDocumentsStore:ce({parser:E,options:B,info:l,tagOperations:g,openapiContentItem:F,metadata:G,relativePath:s,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:Y,excludeFromSearch:C}),getStaticData:async P=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:P.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:O,disableAutoScroll:!0}})})}o[0]={...o[0],metadata:{type:"openapi",...G},hasClientRoutes:!0,getSidebar:(t,O)=>{const I=[];return se({contentItems:_,sidebarItems:I,routeSlug:t.slug,navItem:O}),I},getNavText:()=>l?.title,getSearchDocuments:re(E,B,k,e.getSearchFacets,e.setSearchFacets,C)},v?.apiId&&(S[v.apiId]={slug:o[0]?.slug||""});const W=o[0];o[0]=o[o.length-1],o[o.length-1]=W;for(const t of o)e.addRoute({...t,serverPropsGetterIds:h?[a,r]:[a]});const X=V.isDevelopMode?s:void 0,H=`${U}${s}`;R[H]={fsPath:N,definition:f,options:q,sourcePath:X,routesMapping:x,hash:J};for(const t of o)e.addRoute({...t,sharedData:[{id:H,key:"openAPIDocsStore"}],serverPropsGetterIds:h?[a,r]:[a]})}e.setGlobalData({apiProducts:S})})},afterRoutesCreated:async(e,i)=>{const u=new Set;for(const{chunks:a,relativePath:r,isVirtual:p,realRelativePath:h}of M){const m=ae(e.getAllRoutes(),r),S=(await i.cache.load(h,"load-oas")).compoundHash;await i.cache.load(r,{loader:async function(){for(const{node:f,markdown:n,key:s,relativePath:c}of a){const{ast:_}=await e.parseMarkdoc({content:n,relativePath:c,isVirtual:p},i,{sharedDataIds:[`${U}${c}`],routeSlugs:m});f[`x-parsed-md-${s}`]={result:Z(_)}}},name:"openapi-markdoc-inline-parser"},[S]);for(const{pointer:d}of a)u.add(d)}const A=L.difference(u);for(const a of A)i.cache.delete(a);L=u;for(const[a,r]of Object.entries(R))await e.createSharedData(a,{...r,baseSlug:e.getRouteByFsPath(r.fsPath)?.baseSlug},r.hash)}}}export{ye as openAPIDocsPlugin};
@@ -1 +1 @@
1
- import L from"flexsearch";import{REDOCLY_TEAMS_RBAC as g}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as w,HIGHLIGHTED_TEXT_MAX_LENGTH as S,SEARCH_LIMIT as I}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as E}from"../../../../telemetry/helpers/trace-step.js";class T{#e;#t=new Map;#r=1;id;constructor(e,t){this.id=e,this.#e=new L.Document(t)}get documents(){return this.#t.entries()}get documentsCount(){return this.#r}clearDocuments(){this.#t.clear()}async export(e){await this.#e.export(e)}async import(e){const{documents:t,index:r}=e;this.#t.clear();for(const[i,s]of t)this.#t.set(i,s);for(const[i,s]of Object.entries(r))await this.#e.import(i,s)}add(e){e.tags||(e.tags=[]),this.#t.set(this.#r,e[g]?e:{...e,[g]:void 0}),this.#e.add(this.#r,e),this.#r++}async search(e){return await E("search",async t=>{const{query:r,offset:i,auth:s,product:n,versions:a}=e,o=[],c=s.teams,h={limit:I,offset:i};let d=new Map,p=await this.#e.searchAsync(r,{...h,tag:c});if(n){const l=await this.#e.searchAsync(r,{...h,tag:n});p=this.#n(p,l),t?.setAttribute("product",n)}if(a&&a.length){const l=await this.#e.searchAsync(r,{...h,tag:a});p=this.#n(p,l),t?.setAttribute("versions",a.join(","))}for(const l of p)for(const u of l.result){const f=d.get(u)?.fields||[];d.set(u,{fields:l.field?[...f,l.field]:[...f]})}let m=0;for(const[l,u]of d.entries()){if(m>=I)break;const f=this.#t.get(l);f&&!this.#c(f,a)&&(o.push({document:this.#o(f,r,u.fields),highlight:this.#a(f,r,u.fields)}),m++)}return{documents:{[this.id]:o},facets:{}}})}#o(e,t,r){return this.#h(e,t,r)}#a(e,t,r){const i={};let s=!1;for(const n of r)if(n==="path")i.path=e.path?e.path.map(a=>this.#s(t,a)):[];else if(n.includes("parameters")){if(!s){const a=n.split(":")[1],o=e.parameters?.find(c=>{const h=c[a];return this.#i(t,typeof h=="boolean"?h.toString():h)});o&&(i.parameters=[{name:this.#s(t,o.name),description:this.#s(t,o.description),place:this.#s(t,o.place),path:o.path?o.path.map(c=>this.#s(t,c)):[]}],s=!0)}}else i[n]=this.#s(t,e[n]);return i}#s(e,t){const r=e.split(/\s+/g),i=n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),s=r.reduce((n,a)=>a?n?.replace?.(new RegExp(`(^|\\s)${i(a)}`,"i"),o=>`<mark>${o}</mark>`):n,t);if(!s)return t||"";if(s.length<S)return s;{const n=s.indexOf("<mark>"),a=s.indexOf("</mark>")+7,o=S/2+e.length/2,c=n<o,h=a+o<s.length,d=s.substring(c?0:n-o,h?a+o:s.length);return`${c?"":"..."}${d}${h?"...":""}`}}#i=(e,t)=>{if(t){const r=e.split(/\s+/g);return Array.isArray(t)?t.some(i=>r.some(s=>i.toLowerCase().includes(s.toLowerCase()))):r.some(i=>t.toLowerCase().includes(i.toLowerCase()))}else return!1};#n(e,t){const r=[];for(const i of e){const s=[];for(const n of t)for(const a of i.result){const o=n.result.find(c=>c===a);o&&s.push(o)}s.length&&r.push({result:s,field:i.field})}return r}#c(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(r=>r.includes(e.versionFolderId??""))&&!t.some(r=>r.includes(e.version??"")))}#h(e,t,r){for(const s of w)if(r.some(n=>n===s))return e;let i;for(const s of r)if(s.includes("parameters")){const n=s.split(":")[1],a=e.parameters?.find(o=>{const c=o[n];return this.#i(t,typeof c=="boolean"?c.toString():c)});if(a){i=a.deepLink;break}}if(i){const s=i.split("#")[1];return{...e,url:`${e.url}#${s}`}}return e}}export{T as FlexSearchIndex};
1
+ import I from"flexsearch";import{REDOCLY_TEAMS_RBAC as S}from"@redocly/config";import{DISABLE_DEEP_LINK_IF_FIELDS_EXIST as L,SEARCH_LIMIT as w}from"../../../../constants/plugins/search.js";import{telemetryTraceStep as D}from"../../../../telemetry/helpers/trace-step.js";import{highlightTextForSearch as p}from"../../../../utils/search/highlight-text-for-search.js";class y{#e;#t=new Map;#s=1;id;constructor(e,t){this.id=e,this.#e=new I.Document(t)}get documents(){return this.#t.entries()}get documentsCount(){return this.#s}clearDocuments(){this.#t.clear()}async export(e){await this.#e.export(e)}async import(e){const{documents:t,index:s}=e;this.#t.clear();for(const[r,i]of t)this.#t.set(r,i);for(const[r,i]of Object.entries(s))await this.#e.import(r,i)}add(e){e.tags||(e.tags=[]),this.#t.set(this.#s,e[S]?e:{...e,[S]:void 0}),this.#e.add(this.#s,e),this.#s++}async search(e){return await D("search",async t=>{const{query:s,offset:r,auth:i,product:o,versions:a}=e,n=[],c=i.teams,h={limit:w,offset:r};let m=new Map,u=await this.#e.searchAsync(s,{...h,tag:c});if(o){const l=await this.#e.searchAsync(s,{...h,tag:o});u=this.#i(u,l),t?.setAttribute("product",o)}if(a&&a.length){const l=await this.#e.searchAsync(s,{...h,tag:a});u=this.#i(u,l),t?.setAttribute("versions",a.join(","))}for(const l of u)for(const d of l.result){const f=m.get(d)?.fields||[];m.set(d,{fields:l.field?[...f,l.field]:[...f]})}let g=0;for(const[l,d]of m.entries()){if(g>=w)break;const f=this.#t.get(l);f&&!this.#n(f,a)&&(n.push({document:this.#o(f,s,d.fields),highlight:this.#a(f,s,d.fields)}),g++)}return{documents:{[this.id]:n},facets:{}}})}#o(e,t,s){return this.#c(e,t,s)}#a(e,t,s){const r={};let i=!1;for(const o of s)if(o==="path")r.path=e.path?e.path.map(a=>p(t,a)):[];else if(o.includes("parameters")){if(!i){const a=o.split(":")[1],n=e.parameters?.find(c=>{const h=c[a];return this.#r(t,typeof h=="boolean"?h.toString():h)});n&&(r.parameters=[{name:p(t,n.name),description:p(t,n.description),place:p(t,n.place),path:n.path?n.path.map(c=>p(t,c)):[]}],i=!0)}}else r[o]=p(t,e[o]);return r}#r=(e,t)=>{if(t){const s=e.split(/\s+/g);return Array.isArray(t)?t.some(r=>s.some(i=>r.toLowerCase().includes(i.toLowerCase()))):s.some(r=>t.toLowerCase().includes(r.toLowerCase()))}else return!1};#i(e,t){const s=[];for(const r of e){const i=[];for(const o of t)for(const a of r.result){const n=o.result.find(c=>c===a);n&&i.push(n)}i.length&&s.push({result:i,field:r.field})}return s}#n(e,t){return!!(t&&t.length&&e.isDefaultVersion&&e.versionFolderId&&e.version&&t.some(s=>s.includes(e.versionFolderId??""))&&!t.some(s=>s.includes(e.version??"")))}#c(e,t,s){for(const i of L)if(s.some(o=>o===i))return e;let r;for(const i of s)if(i.includes("parameters")){const o=i.split(":")[1],a=e.parameters?.find(n=>{const c=n[o];return this.#r(t,typeof c=="boolean"?c.toString():c)});if(a){r=a.deepLink;break}}if(r){const i=r.split("#")[1];return{...e,url:`${e.url}#${i}`}}return e}}export{y as FlexSearchIndex};
@@ -9,4 +9,8 @@ export declare function findFrontmatterSlugs(relativePath: string, loaderName: s
9
9
  export declare function getSidebarSharedDataId(sidebar: string | {
10
10
  path: string;
11
11
  }, relativePath: string, fs: ContentFs): Promise<string | null>;
12
+ export declare function getRouteSlugsForPath(routes: {
13
+ fsPath: string;
14
+ slug: string;
15
+ }[], relativePath: string): string[];
12
16
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- import a from"path";import{DEFAULT_LOCALE_PLACEHOLDER as s}from"../../constants/common.js";import{normalizeRouteSlug as m}from"../../utils/path/normalize-route-slug.js";import{logger as l}from"../tools/notifiers/logger.js";import{getLocaleFromRelativePath as p}from"../fs/utils/get-locale-from-relative-path.js";import{isL10nPath as f}from"../fs/utils/is-l10n-path.js";import{removeL10nPrefix as u}from"../fs/utils/remove-l10n-prefix.js";import{resolveSidebarId as c}from"./sidebars/index.js";function E(e,o){return(Array.isArray(e)?e:e?[e]:[]).map(r=>d(r,o))}function d(e,o){const t=p(o).toLowerCase(),r=m(e);return t!==s?`/${t}${r}`:r}function b(e){const o=e.endsWith(".page.tsx")?".page.tsx":a.posix.extname(e),t=a.posix.basename(e,o);return{baseName:t,isIndexFile:t==="index"}}async function R(e,o,t,r){if(t?.slug||!f(e))return t?.slug;const n=u(e);if(!r.fs.exists(n))return;const{data:i}=await r.cache.load(n,o);return i?.frontmatter?.slug}async function I(e,o,t){const r=typeof e=="string",n=r?e:e.path;return r&&l.warnForRealFile("The 'sidebar' property in the front matter of %rp is deprecated. Use 'sidebar.path' instead.",o,t),n?c(o,n,t):null}export{R as findFrontmatterSlugs,I as getSidebarSharedDataId,b as parseBaseName,E as resolveFrontmatterSlugs};
1
+ import a from"path";import{DEFAULT_LOCALE_PLACEHOLDER as m}from"../../constants/common.js";import{normalizeRouteSlug as l}from"../../utils/path/normalize-route-slug.js";import{slash as i}from"../../utils/path/slash.js";import{logger as u}from"../tools/notifiers/logger.js";import{getLocaleFromRelativePath as f}from"../fs/utils/get-locale-from-relative-path.js";import{isL10nPath as p}from"../fs/utils/is-l10n-path.js";import{removeL10nPrefix as c}from"../fs/utils/remove-l10n-prefix.js";import{resolveSidebarId as d}from"./sidebars/index.js";function b(e,r){return(Array.isArray(e)?e:e?[e]:[]).map(o=>g(o,r))}function g(e,r){const t=f(r).toLowerCase(),o=l(e);return t!==m?`/${t}${o}`:o}function I(e){const r=e.endsWith(".page.tsx")?".page.tsx":a.posix.extname(e),t=a.posix.basename(e,r);return{baseName:t,isIndexFile:t==="index"}}async function P(e,r,t,o){if(t?.slug||!p(e))return t?.slug;const n=c(e);if(!o.fs.exists(n))return;const{data:s}=await o.cache.load(n,r);return s?.frontmatter?.slug}async function w(e,r,t){const o=typeof e=="string",n=o?e:e.path;return o&&u.warnForRealFile("The 'sidebar' property in the front matter of %rp is deprecated. Use 'sidebar.path' instead.",r,t),n?d(r,n,t):null}function C(e,r){return e.filter(t=>i(t.fsPath)===i(r)).map(t=>t.slug)}export{P as findFrontmatterSlugs,C as getRouteSlugsForPath,w as getSidebarSharedDataId,I as parseBaseName,b as resolveFrontmatterSlugs};
@@ -0,0 +1,2 @@
1
+ export declare function highlightTextForSearch(query: string, text: string): string;
2
+ //# sourceMappingURL=highlight-text-for-search.d.ts.map
@@ -0,0 +1 @@
1
+ import{HIGHLIGHTED_TEXT_MAX_LENGTH as a}from"../../constants/plugins/search.js";function L(n,g){const p=n.split(/\s+/g),d=t=>t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),e=p.reduce((t,h)=>{if(!h||!t?.replace)return t;const u=new RegExp(`(^|\\s)${d(h)}`,"gi");return t.replace(u,(l,H,x,k)=>{const m=k.substring(0,x),T=(m.match(/<mark>/g)??[]).length,$=(m.match(/<\/mark>/g)??[]).length;return T>$?l:`<mark>${l}</mark>`})},g);if(!e)return g||"";if(e.replace(/<mark>/g,"").replace(/<\/mark>/g,"").length<a)return e;const s=e.indexOf("<mark>"),i=e.indexOf("</mark>")+7,r=a/2+n.length/2,o=s<r,c=i+r<e.length,f=e.substring(o?0:s-r,c?i+r:e.length);return`${o?"":"..."}${f}${c?"...":""}`}export{L as highlightTextForSearch};
@@ -1 +1 @@
1
- import{FEEDBACK_API_URL as k}from"../../constants/common.js";import{MAX_CONTEXT_LENGTH as p,MAX_EMAIL_LENGTH as _,MAX_LANG_LENGTH as j,MAX_PATH_LENGTH as E,MAX_REASONS_COUNT as N}from"../../constants/feedback.js";import{mapObject as T}from"../../../utils/object/map-object.js";import{getClientIp as C}from"../utils/get-client-ip.js";import{canAccessResource as S}from"../../utils/rbac.js";function o(n,e){if(n!=null)return String(n).replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"").trim().slice(0,e)||void 0}function F(n){if(!n)return n;const e=["userAgent","firstName","lastName","auth_time","platform","id","email","ipAddress"];return T(n,(r,a)=>e.includes(a)?r:"*****")}function L({component:n,path:e,location:r,lang:a,score:m,max:s,reasons:i,comment:t,metadata:f,email:u}){const l=Array.isArray(i)?i.map(c=>o(String(c),p)).filter(c=>!!c).slice(0,N):void 0;return{feedbackComponent:n.toUpperCase(),path:o(e,E),location:o(r,p),lang:o(a,j),score:typeof m=="number"?m:void 0,maxScore:typeof s=="number"?s:void 0,reasons:l?.length?l:void 0,comment:o(t,p),email:o(u,_),metadata:F(f)}}async function w(n,e){return(await fetch(k,{method:"POST",body:JSON.stringify(L(n)),headers:e})).json()}function G(n){return async e=>{const r=await e.req.json(),a=e.req.header("user-agent"),m=C(e.req.raw),s=e.req.header("Sec-Ch-Ua-Platform"),i={...r.metadata,userAgent:a,ipAddress:m,platform:s?s.replace(/"/g,""):"unknown"},t=[];(!r.path||r.path==="")&&t.push("`path` is required");const f=["sentiment","rating","comment","problem","mood","scale"];if(f.includes(r.component)||t.push(`\`component\` field should be one of ${f.join(", ")}.`),t.length)return e.json({errors:t},400);const{claims:u,isAuthenticated:l,teams:c}=e.get("auth"),b={isAuthenticated:l,email:u?.email,teams:c};if(Object.keys(n.config.rbac||{}).length>0){const d=r.path,y=new URL(d).pathname,g=n.getRouteBySlug(y);if(!g)return e.json({errors:["Resource not found"]},404);if(!S(g,b,n.config.rbac,n.config.requiresLogin))return e.json({errors:["Forbidden: no permission to send feedback for resource"]},403)}const A={"Content-Type":"application/json"},h=u?.email||r?.email||i?.email;try{const d=await w({...r,email:h,metadata:{email:h,...i}},A);return e.json({message:"Thanks for your feedback",...d},200,{})}catch(d){return e.json({errors:["Failed to send feedback",d.message]},500)}}}export{G as feedbackHandler,F as normalizeFeedbackMetadata};
1
+ import{FEEDBACK_API_URL as _}from"../../constants/common.js";import{MAX_CONTEXT_LENGTH as g,MAX_EMAIL_LENGTH as C,MAX_LANG_LENGTH as j,MAX_PATH_LENGTH as E,MAX_REASONS_COUNT as N}from"../../constants/feedback.js";import{mapObject as T}from"../../../utils/object/map-object.js";import{getClientIp as q}from"../utils/get-client-ip.js";import{canAccessResource as w}from"../../utils/rbac.js";function a(e,n){if(e!=null)return String(e).replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"").trim().slice(0,n)||void 0}function S(e){if(!e)return e;const n=["userAgent","firstName","lastName","auth_time","platform","id","email","ipAddress"];return T(e,(o,r)=>n.includes(r)?o:"*****")}function L({component:e,path:n,location:o,lang:r,score:u,max:i,reasons:s,comment:m,metadata:t,email:l}){const c=Array.isArray(s)?s.map(d=>a(String(d),g)).filter(d=>!!d).slice(0,N):void 0;return{feedbackComponent:e.toUpperCase(),path:a(n,E),location:a(o,g),lang:a(r,j),score:typeof u=="number"?u:void 0,maxScore:typeof i=="number"?i:void 0,reasons:c?.length?c:void 0,comment:a(m,g),email:a(l,C),metadata:S(t)}}async function R(e,n){return(await fetch(_,{method:"POST",body:JSON.stringify(L(e)),headers:n})).json()}function G(e){return async n=>{const o=n.get("logger"),r=await n.req.json(),u=n.req.header("user-agent"),i=q(n.req.raw),s=n.req.header("Sec-Ch-Ua-Platform"),m={...r.metadata,userAgent:u,ipAddress:i,platform:s?s.replace(/"/g,""):"unknown"};o.info("Feedback IP diagnostics",I(n,i??void 0));const t=[];(!r.path||r.path==="")&&t.push("`path` is required");const l=["sentiment","rating","comment","problem","mood","scale"];if(l.includes(r.component)||t.push(`\`component\` field should be one of ${l.join(", ")}.`),t.length)return n.json({errors:t},400);const{claims:c,isAuthenticated:d,teams:A}=n.get("auth"),k={isAuthenticated:d,email:c?.email,teams:A};if(Object.keys(e.config.rbac||{}).length>0){const f=r.path,F=new URL(f).pathname,b=e.getRouteBySlug(F);if(!b)return n.json({errors:["Resource not found"]},404);if(!w(b,k,e.config.rbac,e.config.requiresLogin))return n.json({errors:["Forbidden: no permission to send feedback for resource"]},403)}const y={"Content-Type":"application/json"},h=c?.email||r?.email||m?.email;try{const f=await R({...r,email:h,metadata:{email:h,...m}},y);return n.json({message:"Thanks for your feedback",...f},200,{})}catch(f){return n.json({errors:["Failed to send feedback",f.message]},500)}}}function I(e,n){return{extractedIpAddress:n,xForwardedFor:p(e.req.header("x-forwarded-for")),xRealIp:p(e.req.header("x-real-ip")),trueClientIp:p(e.req.header("true-client-ip")),cfConnectingIp:p(e.req.header("cf-connecting-ip"))}}function p(e){if(e)return e.slice(0,256)}export{G as feedbackHandler,S as normalizeFeedbackMetadata};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/redoc-reef",
3
- "version": "0.132.0-next.0",
3
+ "version": "0.132.0-next.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,7 @@
16
16
  "dependencies": {
17
17
  "@babel/core": "7.23.5",
18
18
  "@dr.pogodin/react-helmet": "3.0.2",
19
+ "@excalidraw/excalidraw": "0.18.0",
19
20
  "@libsql/client": "0.15.4",
20
21
  "@markdoc/markdoc": "0.5.2",
21
22
  "@opentelemetry/api": "1.9.0",
@@ -91,14 +92,14 @@
91
92
  "xpath": "0.0.34",
92
93
  "yaml-ast-parser": "0.0.43",
93
94
  "zod": "^3.25.76",
94
- "@redocly/asyncapi-docs": "1.9.0-next.0",
95
+ "@redocly/asyncapi-docs": "1.9.0-next.1",
95
96
  "@redocly/config": "0.44.1",
96
- "@redocly/graphql-docs": "1.9.0-next.0",
97
- "@redocly/openapi-docs": "3.20.0-next.0",
97
+ "@redocly/graphql-docs": "1.9.0-next.1",
98
+ "@redocly/openapi-docs": "3.20.0-next.1",
98
99
  "@redocly/portal-legacy-ui": "0.15.0-next.0",
99
- "@redocly/portal-plugin-mock-server": "0.17.0-next.0",
100
+ "@redocly/portal-plugin-mock-server": "0.17.0-next.1",
100
101
  "@redocly/realm-asyncapi-sdk": "0.10.0-next.0",
101
- "@redocly/theme": "0.64.0-next.0"
102
+ "@redocly/theme": "0.64.0-next.1"
102
103
  },
103
104
  "peerDependencies": {
104
105
  "react": "^19.2.4",