@redocly/reef 0.140.0-next.10 → 0.140.0-next.13

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,40 @@
1
1
  # @redocly/reef
2
2
 
3
+ ## 0.140.0-next.13
4
+
5
+ ### Patch Changes
6
+
7
+ - 7e43e310476: Updated `@redocly/openapi-core` to version `2.73.0`.
8
+ - Updated dependencies [8bde47c6eaf]
9
+ - Updated dependencies [7e43e310476]
10
+ - @redocly/api-docs@0.5.0-next.10
11
+ - @redocly/portal-plugin-mock-server@0.25.0-next.3
12
+
13
+ ## 0.140.0-next.12
14
+
15
+ ### Patch Changes
16
+
17
+ - 694a8c8c663: Fixed security vulnerability `GHSA-g3hv-75wg-m249` by upgrading `minimatch` to version `11.0.3`.
18
+ - Updated dependencies [42ce6c31eaf]
19
+ - Updated dependencies [42ce6c31eaf]
20
+ - Updated dependencies [42ce6c31eaf]
21
+ - @redocly/api-docs@0.5.0-next.9
22
+
23
+ ## 0.140.0-next.11
24
+
25
+ ### Patch Changes
26
+
27
+ - 90819702eb9: Fixed an issue where the top items of the page table of contents were hidden under the navbar when a banner was displayed.
28
+ - f1f6907ccbf: Replaced the `enabled` option with `disabled` in `platform.agent` and its duties, review specialists, and custom duties.
29
+ The build reports an error when `platform.agent` uses `enabled` or sets no options.
30
+ - Updated dependencies [6dbe08e9614]
31
+ - Updated dependencies [6dbe08e9614]
32
+ - Updated dependencies [6d0d8601978]
33
+ - Updated dependencies [0d8d14bdb7a]
34
+ - Updated dependencies [90819702eb9]
35
+ - @redocly/api-docs@0.5.0-next.8
36
+ - @redocly/theme@0.72.0-next.7
37
+
3
38
  ## 0.140.0-next.10
4
39
 
5
40
  ### Minor Changes
@@ -1,5 +1,5 @@
1
- import{useMemo as u,useRef as m}from"react";import{components as c}from"@redocly-markdoc/components";import{schema as s}from"@redocly-markdoc/schema";import{withPathPrefix as i}from"@redocly/theme/core/utils";import{tags as p,components as f}from"@redocly/theme/markdoc/default";import*as l from"../../app/markdoc/custom-components/index.js";import{parsePartials as d}from"../../../markdoc/helpers/parse-partials.js";import*as g from"../../../markdoc/nodes/index.js";import w from"../../../markdoc/tags/index.js";import{normalizeCustomTags as h}from"../../../markdoc/helpers/normalize-custom-tags.js";import{deepEqual as y}from"../../../utils/object/deep-equal.js";function b(t){return t.map(r=>{const o={...r};return typeof o.link=="string"&&(o.link=i(o.link)),typeof o.routeSlug=="string"&&(o.routeSlug=i(o.routeSlug)),Array.isArray(o.items)&&(o.items=b(o.items)),o})}function a(t){const r=m(t);return y(r.current,t)||(r.current=t),r.current}function E(t,r){const o=a(t),n=a(r);return u(()=>{const e=globalThis.__LOADER?.markdocComponents??{};return{...n,...o,tags:{...n?.tags??{},...w,...p,...h(s?.tags??{})},nodes:{...n?.nodes??{},...g,...s?.nodes??{}},functions:{...s?.functions??{}},components:{...n?.components??{},...l,...f,...c,...e},partials:d(o?.partials)}},[o,n])}function M(t){if(typeof window>"u")return null;if(typeof t=="function")return t;if(typeof t!="string")return null;try{const r=t.trim();if(!r.match(/^(\([^)]*\)\s*=>\s*\S.*|[a-zA-Z_$][\w$]*\s*=>\s*\S.*)$/))throw new Error("Invalid function format. Only arrow functions allowed.");if(["eval","Function","constructor","prototype","__proto__","import","require","process","global","window","document"].some(e=>r.includes(e)))throw new Error("Function contains prohibited keywords");return new Function("event",`
1
+ import{useMemo as a,useRef as m}from"react";import{components as c}from"@redocly-markdoc/components";import{schema as s}from"@redocly-markdoc/schema";import{ITEM_ROUTE_PATH_KEYS as u}from"@redocly/api-docs/lib/utils/previous-route-slug.js";import{withPathPrefix as p}from"@redocly/theme/core/utils";import{tags as f,components as l}from"@redocly/theme/markdoc/default";import*as d from"../../app/markdoc/custom-components/index.js";import{parsePartials as g}from"../../../markdoc/helpers/parse-partials.js";import*as w from"../../../markdoc/nodes/index.js";import h from"../../../markdoc/tags/index.js";import{normalizeCustomTags as y}from"../../../markdoc/helpers/normalize-custom-tags.js";import{deepEqual as T}from"../../../utils/object/deep-equal.js";function _(r){return r.map(o=>{const t={...o};for(const n of u){const e=t[n];typeof e=="string"&&(t[n]=p(e))}return Array.isArray(t.items)&&(t.items=_(t.items)),t})}function i(r){const o=m(r);return T(o.current,r)||(o.current=r),o.current}function S(r,o){const t=i(r),n=i(o);return a(()=>{const e=globalThis.__LOADER?.markdocComponents??{};return{...n,...t,tags:{...n?.tags??{},...h,...f,...y(s?.tags??{})},nodes:{...n?.nodes??{},...w,...s?.nodes??{}},functions:{...s?.functions??{}},components:{...n?.components??{},...d,...l,...c,...e},partials:g(t?.partials)}},[t,n])}function $(r){if(typeof window>"u")return null;if(typeof r=="function")return r;if(typeof r!="string")return null;try{const o=r.trim();if(!o.match(/^(\([^)]*\)\s*=>\s*\S.*|[a-zA-Z_$][\w$]*\s*=>\s*\S.*)$/))throw new Error("Invalid function format. Only arrow functions allowed.");if(["eval","Function","constructor","prototype","__proto__","import","require","process","global","window","document"].some(e=>o.includes(e)))throw new Error("Function contains prohibited keywords");return new Function("event",`
2
2
  'use strict';
3
- const userFn = ${r};
3
+ const userFn = ${o};
4
4
  return userFn(event);
5
- `)}catch(r){return console.error("Function parsing error:",r),null}}export{b as applyPathPrefixToApiItems,M as safeParseFunction,E as useCollectMarkdocOptions};
5
+ `)}catch(o){return console.error("Function parsing error:",o),null}}export{_ as applyPathPrefixToApiItems,$ as safeParseFunction,S as useCollectMarkdocOptions};
@@ -1 +1 @@
1
- import f from"@babel/core";import h from"node:fs";import r from"node:path";import d from"babel-plugin-styled-components";import u from"crypto";import{envConfig as m}from"../../config/env-config.js";import{babelCache as i}from"../babel-cache.js";const A=()=>({name:"styled-components-ssr",setup:c=>{const l=process.cwd();c.onLoad({filter:/\.[tj]sx?$/},async t=>{if(new RegExp(`${r.sep}replay-[A-Za-z0-9_-]+\\.js$`).test(t.path)||t.path.endsWith(`${r.sep}replay.js`)||t.path.includes(`${r.sep}replay-index-`)&&t.path.endsWith(".js")||t.path.includes(`${r.sep}replay-tauri-path-`)&&t.path.endsWith(".js"))return;const e=t.path.split(".").pop(),s=i.get(t.path);if(s&&t.path.includes("/node_modules/"))return{contents:s.contents,loader:e};const p=["importMeta","topLevelAwait","classProperties","classPrivateProperties","classPrivateMethods","jsx"];(e==="tsx"||e==="ts")&&p.push("typescript");const o=await h.promises.readFile(t.path,"utf8");if(o.indexOf("styled-components")===-1)return{contents:o,loader:e};const a=u.createHash("sha1").update(o).digest("base64");if(s&&s.hash===a)return{contents:s.contents,loader:e};try{const n=(await f.transformAsync(o,{babelrc:!1,configFile:!1,ast:!1,root:l,filename:t.path,parserOpts:{allowAwaitOutsideFunction:!0,plugins:p},generatorOpts:{decoratorsBeforeExport:!0},plugins:[d],sourceMaps:!1}))?.code||void 0;return i.set(t.path,{contents:n,hash:a}),{contents:n,loader:e}}catch(n){if(!m.isDevelopMode)throw n;return{contents:o,loader:e}}})}});export{A as StyledComponentsSSR};
1
+ import l from"@babel/core";import f from"node:fs";import d from"babel-plugin-styled-components";import u from"crypto";import{envConfig as m}from"../../config/env-config.js";import{babelCache as c}from"../babel-cache.js";const h=/[\\/]replay[\\/]dist[\\/][^\\/]+\.js$/,A=()=>({name:"styled-components-ssr",setup:i=>{const p=process.cwd();i.onLoad({filter:/\.[tj]sx?$/},async t=>{if(h.test(t.path))return;const e=t.path.split(".").pop(),s=c.get(t.path);if(s&&t.path.includes("/node_modules/"))return{contents:s.contents,loader:e};const r=["importMeta","topLevelAwait","classProperties","classPrivateProperties","classPrivateMethods","jsx"];(e==="tsx"||e==="ts")&&r.push("typescript");const o=await f.promises.readFile(t.path,"utf8");if(o.indexOf("styled-components")===-1)return{contents:o,loader:e};const a=u.createHash("sha1").update(o).digest("base64");if(s&&s.hash===a)return{contents:s.contents,loader:e};try{const n=(await l.transformAsync(o,{babelrc:!1,configFile:!1,ast:!1,root:p,filename:t.path,parserOpts:{allowAwaitOutsideFunction:!0,plugins:r},generatorOpts:{decoratorsBeforeExport:!0},plugins:[d],sourceMaps:!1}))?.code||void 0;return c.set(t.path,{contents:n,hash:a}),{contents:n,loader:e}}catch(n){if(!m.isDevelopMode)throw n;return{contents:o,loader:e}}})}});export{A as StyledComponentsSSR};
@@ -1 +1 @@
1
- import{Minimatch as c}from"minimatch";import{envConfig as d}from"../../../config/env-config.js";import{gateSsrComponents as s}from"../../consent/gate-ssr-components.js";import{buildScripts as l}from"./build-scripts.js";import{resolveBrowserHooksPath as u}from"./resolve-browser-hooks.js";async function P(){return{id:"Amplitude Analytics",requiredEntitlements:["analytics"],async processContent(t,{getConfig:r}){const o=await r(),n=o?.analytics?.amplitude;if(!n?.apiKey||!d.isProductionEnv&&!n.includeInDevelopment)return;const e=[];typeof n.exclude<"u"&&n.exclude.map(p=>{const i=new c(p).makeRe();i&&e.push(i)});const{headComponents:m,postBodyComponents:a}=l(n,e);t.addSsrComponents(s(m,"analytics",o.consent),"head"),t.addSsrComponents(s(a,"analytics",o.consent),"postBody"),t.addBrowserPlugin(u())}}}export{P as amplitudeAnalyticsPlugin};
1
+ import{envConfig as c}from"../../../config/env-config.js";import{convertGlobToRegex as m}from"../../../utils/globs.js";import{gateSsrComponents as r}from"../../consent/gate-ssr-components.js";import{buildScripts as l}from"./build-scripts.js";import{resolveBrowserHooksPath as u}from"./resolve-browser-hooks.js";async function v(){return{id:"Amplitude Analytics",requiredEntitlements:["analytics"],async processContent(o,{getConfig:p}){const t=await p(),n=t?.analytics?.amplitude;if(!n?.apiKey||!c.isProductionEnv&&!n.includeInDevelopment)return;const e=[];typeof n.exclude<"u"&&n.exclude.map(i=>{const s=i?m(i):void 0;s&&e.push(s)});const{headComponents:a,postBodyComponents:d}=l(n,e);o.addSsrComponents(r(a,"analytics",t.consent),"head"),o.addSsrComponents(r(d,"analytics",t.consent),"postBody"),o.addBrowserPlugin(u())}}}export{v as amplitudeAnalyticsPlugin};
@@ -1,4 +1,4 @@
1
- import{Minimatch as i}from"minimatch";import g from"react";const l=e=>{const o=[],n=[g.createElement("link",{rel:"preconnect",key:"preconnect-google-gtag",href:"https://www.googletagmanager.com"}),g.createElement("link",{rel:"dns-prefetch",key:"dns-prefetch-google-gtag",href:"https://www.googletagmanager.com"})],r=s(e);return e.head?n.push(...r):o.push(...r),{headComponents:n,postBodyComponents:o}};function s(e){const o=[];typeof e.exclude<"u"&&e.exclude.map(c=>{const a=new i(c).makeRe();a&&o.push(a)});const n=[...Object.entries(e.trackers||{})],r=()=>`
1
+ import g from"react";import{convertGlobToRegex as i}from"../../../utils/globs.js";const m=e=>{const o=[],a=[g.createElement("link",{rel:"preconnect",key:"preconnect-google-gtag",href:"https://www.googletagmanager.com"}),g.createElement("link",{rel:"dns-prefetch",key:"dns-prefetch-google-gtag",href:"https://www.googletagmanager.com"})],n=d(e);return e.head?a.push(...n):o.push(...n),{headComponents:a,postBodyComponents:o}};function d(e){const o=[];typeof e.exclude<"u"&&e.exclude.map(r=>{const t=r?i(r):void 0;t&&o.push(t)});const a=[...Object.entries(e.trackers||{})],n=()=>`
2
2
  ${o.length?`window.excludeGtagPaths=[${o.join(",")}];`:""}
3
3
  ${e.anonymizeIp===!0?`function gaOptout(){document.cookie=disableStr+'=true; expires=Thu, 31 Dec 2099 23:59:59 UTC;path=/',window[disableStr]=!0}var gaProperty='${e.trackingId}',disableStr='ga-disable-'+gaProperty;document.cookie.indexOf(disableStr+'=true')>-1&&(window[disableStr]=!0);`:""}
4
4
  if(${e.respectDNT?'!(navigator.doNotTrack == "1" || window.doNotTrack == "1")':"true"}) {
@@ -6,14 +6,14 @@ import{Minimatch as i}from"minimatch";import g from"react";const l=e=>{const o=[
6
6
  function gtag(){dataLayer.push(arguments);}
7
7
  gtag('js', new Date());
8
8
 
9
- ${n.map(([c,t])=>{const a=JSON.stringify({optimize_id:t.optimizeId,anonymize_ip:e.anonymizeIp,cookie_expires:e.cookieExpires,send_page_view:!1,groups:c});return`
9
+ ${a.map(([r,t])=>{const c=JSON.stringify({optimize_id:t.optimizeId,anonymize_ip:e.anonymizeIp,cookie_expires:e.cookieExpires,send_page_view:!1,groups:r});return`
10
10
 
11
- gtag('config', '${t.trackingId}', ${a});
12
- ${t.conversionId?`gtag('config', '${t.conversionId}', ${a});`:""}
13
- ${t.floodlightId?`gtag('config', '${t.floodlightId}', ${a});`:""}
11
+ gtag('config', '${t.trackingId}', ${c});
12
+ ${t.conversionId?`gtag('config', '${t.conversionId}', ${c});`:""}
13
+ ${t.floodlightId?`gtag('config', '${t.floodlightId}', ${c});`:""}
14
14
  `}).join(`
15
15
  `)}
16
16
 
17
17
 
18
18
  }
19
- `;return[g.createElement("script",{key:"gatsby-plugin-google-gtag",async:!0,src:`https://www.googletagmanager.com/gtag/js?id=${e.trackingId}`}),g.createElement("script",{key:"gatsby-plugin-google-gtag-config",dangerouslySetInnerHTML:{__html:r()}})]}export{l as buildScripts};
19
+ `;return[g.createElement("script",{key:"gatsby-plugin-google-gtag",async:!0,src:`https://www.googletagmanager.com/gtag/js?id=${e.trackingId}`}),g.createElement("script",{key:"gatsby-plugin-google-gtag-config",dangerouslySetInnerHTML:{__html:n()}})]}export{m as buildScripts};
@@ -1 +1 @@
1
- import{REDOCLY_ROUTE_RBAC as T,REDOCLY_TEAMS_RBAC as v}from"@redocly/config";import{mcpTagSchemas as rt,schemaDefinitionTag as at,markdocParser as U}from"@redocly/api-docs";import{withPathPrefix as $}from"@redocly/theme/core/utils";import{API_DOCS_TEMPLATE_ID as j,GRAPHQL_SPEC_SLUG as st,PUBLIC_RBAC_SCOPE_ITEM as N}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as it,PUBLIC_API_DEFINITIONS_FOLDER as nt}from"../../constants/common.js";import{API_DOCS_SHARED_DATA_PREFIX as O}from"../../constants/plugins/api-docs.js";import{fromCurrentDir as ct}from"../../utils/paths.js";import{normalizeRouteSlug as pt}from"../../../utils/path/normalize-route-slug.js";import{removeTrailingSlash as ut}from"../../../utils/url/remove-trailing-slash.js";import{isTranslationFallback as lt}from"../../fs/utils/is-translation-fallback.js";import{createSlugify as dt}from"../create-slugify.js";import{apiDocLoader as mt,apiDocsLoader as ft}from"./loader.js";import{getTemplatePath as V}from"./get-template-path.js";import{storeDefinitionBundles as gt}from"./store-definition-bundles.js";import{definitionAccessKey as ht,describeDefinitionAccess as Dt}from"./definition-access.js";import{telemetryTraceStep as St}from"../../../cli/telemetry/helpers/trace-step.js";import{searchResolver as Pt}from"./search/search-resolver.js";import{getAiDocumentsStore as yt}from"./search/get-ai-search-documents.js";import{getApiConfigByPath as At}from"../get-api-config.js";import{getRouteSlugsForPath as It}from"../utils.js";import{collectItemRoutes as vt}from"./utils/collect-item-routes.js";import{isChunkCurrent as bt}from"./utils/decorators.js";import{applyNavItemToRoot as Rt}from"./utils/apply-nav-item-to-root.js";import{buildRoutesMapping as _t}from"./utils/build-routes-mapping.js";import{buildItemPositions as Ct}from"./utils/build-item-positions.js";import{resolveApiDocTitle as Tt}from"./utils/resolve-api-doc-title.js";import{resolveConfigRbac as K}from"./utils/resolve-config-rbac.js";import{relativePathToBaseSlug as wt}from"./utils/relative-path-to-base-slug.js";import{normalizeApiVersion as Et}from"./utils/normalize-api-version.js";import{importApiDocsBuilder as W}from"./import-api-docs-builder.js";import{envConfig as G}from"../../config/env-config.js";import{logger as kt}from"../../tools/notifiers/logger.js";const F="openapi-spec-download",Ot={asyncapi:"AsyncAPI Docs",graphql:"GraphQL Docs",openapi:"OpenAPI Docs"};async function he(){let e=[],r=new Map;const s=new WeakMap;let n=new Set,f={},A={};function Y(o,S,b){const I=s.get(o)??new Map;s.set(o,I);const P=S??"";return I.get(P)===b?!1:(I.set(P,b),!0)}return{id:"api-docs",requiredEntitlements:["openapi","asyncapi","graphql"],loaders:{"api-doc":mt,"api-docs":ft},processContent:async(o,S)=>{await St("com.redocly.build.plugin.apiDocs",async()=>{o.createRequestHandler(F,ct(import.meta.url,"./spec-download.api.js")),o.addApiRoute({slug:nt+"/*",requestHandlerId:F,httpMethod:"all",[v]:N,getStaticData:async()=>({props:{definitionAccess:A}})}),o.addApiRoute({slug:it+"/*",requestHandlerId:F,httpMethod:"all",[v]:N,getStaticData:async()=>({props:{definitionAccess:A}})}),o.addApiRoute({slug:st+"/*",requestHandlerId:F,httpMethod:"all",[v]:N,getStaticData:async()=>({props:{definitionAccess:A}})});const b=o.createTemplate(j,V("../../../client/templates/api-docs/template.js")),I=o.registerServerPropsGetter(j,V("./get-server-props.js")),P=await S.getConfig();r=new Map,f={};const y=await o.loadApiDocuments(S);gt(y,o.outdir),A={};const w=!!P.plugins?.some(t=>typeof t=="string"&&t.startsWith("@redocly/portal-plugin-async-api/"));w&&y.some(t=>t.type==="asyncapi")&&kt.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");const p=w?y.filter(t=>t.type!=="asyncapi"):y;e=p.map(({markdocChunks:t,relativePath:u,isVirtual:c,customOutputRelativeFile:a,realRelativePath:D})=>({chunks:t??[],relativePath:u,realRelativePath:D,isVirtual:a!=null||c}));const{buildItems:i}=await W(o.serverOutDir),g=(await S.cache.load("content-slugs","content-slugs")).data,h=dt(g),E=t=>pt(h(t));for(const t of y){const u=ht(t);if(u===void 0)continue;const c=E(t.customOutputRelativeFile||t.relativePath);A[u]=Dt(t,c)}for(const t of p){const u=t.customOutputRelativeFile||t.relativePath,c=E(u);Lt(t,c);const{items:a,store:D}=await i({type:t.type,document:t.document,options:t.options,basePath:c,markdownParser:U}),R=`${O}${t.relativePath}`,M=G.isDevelopMode?t.relativePath:void 0,l=qt(t.document),_=l?.["x-metadata"],C=t.isVirtual?void 0:_?.apiId,L={document:t,basePath:c,sourcePath:M,apiId:C,build:{items:a,store:D}};await o.createSharedData(R,Q(L,a,D));const X=K(t.config),B=!!t.options.excludeFromSearch,J=t.type==="openapi",Z=vt(a,X),tt=lt(t),m=Z.map(d=>{const x=d.metadata?.seo,k={fsPath:u,templateId:b,sharedData:[{key:"apiDocsStore",id:R}],serverPropsGetterIds:[I],excludeFromSearch:B,getStaticData:Mt(d.label,x,tt),[v]:d[v]};return Object.assign(k,Bt(d.link,c)),J&&d.httpVerb&&(k.httpVerb=d.httpVerb,k.metadata={subType:"openapi-operation"}),k});if(!m.length)continue;const H=Tt(l,t.type,a),et=Et(l?.version),q={type:t.type,title:H,version:et,description:typeof l?.description=="string"?l.description:void 0,summary:typeof l?.summary=="string"?l.summary:void 0,...l?.["x-metadata"]&&typeof l["x-metadata"]=="object"?l["x-metadata"]:{}};m[0]={...m[0],metadata:q,hasClientRoutes:!0,getSidebar:(d,x)=>Rt(z(a),c,x),getNavText:()=>H??Ot[t.type]??"API Docs",getSearchDocuments:Pt(a,q,o.getSearchFacets,o.setSearchFacets,B,D,t.document),getAiDocumentsStore:yt({getBuild:()=>L.build,metadata:q,document:t.document,specType:t.type,excludeFromSearch:B,basePath:c,getSearchFacets:o.getSearchFacets,markdocTags:{...rt,schemaDefinition:at}})};const ot=m[0];m[0]=m[m.length-1],m[m.length-1]=ot;for(const d of m)o.addRoute(d);if(C){const d=At(t.config?.apis,t.realRelativePath);f[C]={[v]:d.rbac,[T]:{fsPath:u}}}r.set(R,L)}})},afterRoutesCreated:async(o,S)=>{const{buildItems:b,simplifyAstStructure:I}=await W(o.serverOutDir),P=new Set,y=new Set;for(const{chunks:p,relativePath:i,isVirtual:g}of e){const h=`${O}${i}`,E=It(o.getAllRoutes(),i);for(const{node:t,markdown:u,pointer:c,key:a,relativePath:D}of p){const{ast:R,compoundHash:M}=await o.parseMarkdoc({input:{content:u,relativePath:D,isVirtual:g},resource:c,context:S,deps:{sharedDataIds:[`${O}${D}`],routeSlugs:E}});if(P.add(c),!(a==="graphql-docs"?t?.description?.value!==void 0:!!a&&bt(t,a,u))||!Y(t,a,M))continue;y.add(h);const _=I(R);if(a==="graphql-docs"){t.description&&(t.description.value=_);const C=`${O}${D}`;Ft(r.get(C),_)}else a&&(t[a]=_)}}const w=n.difference(P);for(const p of w)S.cache.delete(p);n=P,Object.entries(f).forEach(([p,i])=>{const g=i[T]?.fsPath;if(!g)return;const h=o.getRouteByFsPath(g)?.baseSlug;f[p]={...i,[T]:{...i[T],slug:h},slug:h}}),o.setGlobalData({apiProducts:f});for(const[p,i]of r){if(!y.has(p))continue;const{items:g,store:h}=await b({type:i.document.type,document:i.document.document,options:i.document.options,basePath:i.basePath,markdownParser:U});i.build={items:g,store:h},await o.createSharedData(p,Q(i,g,h))}}}}function Q({document:e,basePath:r,sourcePath:s,apiId:n},f,A){return{[v]:K(e.config),[T]:{slug:ut(r),fsPath:e.customOutputRelativeFile||e.relativePath},items:f,store:A,options:e.options,baseSlug:r,routesMapping:G.isDevelopMode?_t(f,r):{},graphqlPositions:G.isDevelopMode&&e.type==="graphql"?Ct(f,r):void 0,sourcePath:s,apiId:n}}function Ft(e,r){e?.document.type!=="graphql"||!e.document.options||(e.document.options.info={...e.document.options.info||{},description:r})}function Mt(e,r,s){return async function(n){return{...s?{isTranslationFallback:!0}:{},props:{settings:{baseUrlPath:$(n.baseSlug)},disableAutoScroll:!0,seo:{title:e,...r}}}}}function Lt(e,r){const s=e.options?.mockServer,n=$(`/_mock${wt(e.relativePath)}`);s?.url===n&&(e.options={...e.options,mockServer:{...s,url:$(`/_mock${r}`)}})}function Bt(e,r){if(e===r)return{};const s=r==="/"?"/":`${r}/`;if(e.startsWith(s)){const n=e.slice(s.length);return n?{slugSuffix:n}:{}}return{slug:e}}function qt(e){if(e&&typeof e=="object"&&"info"in e)return e.info}function z(e){return e.map(({content:r,items:s,...n})=>({...n,...s&&{items:z(s)}}))}export{he as apiDocsPlugin,Bt as toRouteSlugFields};
1
+ import{REDOCLY_ROUTE_RBAC as w,REDOCLY_TEAMS_RBAC as I}from"@redocly/config";import{mcpTagSchemas as ae,schemaDefinitionTag as ie,markdocParser as U,collectPreviousRouteSlugs as se}from"@redocly/api-docs";import{withPathPrefix as $}from"@redocly/theme/core/utils";import{API_DOCS_TEMPLATE_ID as j,GRAPHQL_SPEC_SLUG as ne,PUBLIC_RBAC_SCOPE_ITEM as N}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ce,PUBLIC_API_DEFINITIONS_FOLDER as pe}from"../../constants/common.js";import{API_DOCS_SHARED_DATA_PREFIX as O}from"../../constants/plugins/api-docs.js";import{fromCurrentDir as ue}from"../../utils/paths.js";import{normalizeRouteSlug as le}from"../../../utils/path/normalize-route-slug.js";import{removeTrailingSlash as de}from"../../../utils/url/remove-trailing-slash.js";import{isTranslationFallback as me}from"../../fs/utils/is-translation-fallback.js";import{createSlugify as fe}from"../create-slugify.js";import{apiDocLoader as ge,apiDocsLoader as he}from"./loader.js";import{getTemplatePath as V}from"./get-template-path.js";import{storeDefinitionBundles as Se}from"./store-definition-bundles.js";import{definitionAccessKey as De,describeDefinitionAccess as Pe}from"./definition-access.js";import{telemetryTraceStep as ye}from"../../../cli/telemetry/helpers/trace-step.js";import{searchResolver as ve}from"./search/search-resolver.js";import{getAiDocumentsStore as Ae}from"./search/get-ai-search-documents.js";import{getApiConfigByPath as Ie}from"../get-api-config.js";import{getRouteSlugsForPath as Re}from"../utils.js";import{collectItemRoutes as be}from"./utils/collect-item-routes.js";import{isChunkCurrent as _e}from"./utils/decorators.js";import{applyNavItemToRoot as Ce}from"./utils/apply-nav-item-to-root.js";import{buildRoutesMapping as we}from"./utils/build-routes-mapping.js";import{buildItemPositions as Te}from"./utils/build-item-positions.js";import{resolveApiDocTitle as ke}from"./utils/resolve-api-doc-title.js";import{resolveConfigRbac as K}from"./utils/resolve-config-rbac.js";import{relativePathToBaseSlug as Ee}from"./utils/relative-path-to-base-slug.js";import{normalizeApiVersion as Oe}from"./utils/normalize-api-version.js";import{importApiDocsBuilder as W}from"./import-api-docs-builder.js";import{envConfig as G}from"../../config/env-config.js";import{logger as Fe}from"../../tools/notifiers/logger.js";const F="openapi-spec-download",Me={asyncapi:"AsyncAPI Docs",graphql:"GraphQL Docs",openapi:"OpenAPI Docs"};async function Dt(){let t=[],r=new Map;const a=new WeakMap;let i=new Set,g={},v={};function X(o,D,R){const A=a.get(o)??new Map;a.set(o,A);const P=D??"";return A.get(P)===R?!1:(A.set(P,R),!0)}return{id:"api-docs",requiredEntitlements:["openapi","asyncapi","graphql"],loaders:{"api-doc":ge,"api-docs":he},processContent:async(o,D)=>{await ye("com.redocly.build.plugin.apiDocs",async()=>{o.createRequestHandler(F,ue(import.meta.url,"./spec-download.api.js")),o.addApiRoute({slug:pe+"/*",requestHandlerId:F,httpMethod:"all",[I]:N,getStaticData:async()=>({props:{definitionAccess:v}})}),o.addApiRoute({slug:ce+"/*",requestHandlerId:F,httpMethod:"all",[I]:N,getStaticData:async()=>({props:{definitionAccess:v}})}),o.addApiRoute({slug:ne+"/*",requestHandlerId:F,httpMethod:"all",[I]:N,getStaticData:async()=>({props:{definitionAccess:v}})});const R=o.createTemplate(j,V("../../../client/templates/api-docs/template.js")),A=o.registerServerPropsGetter(j,V("./get-server-props.js")),P=await D.getConfig();r=new Map,g={};const y=await o.loadApiDocuments(D);Se(y,o.outdir),v={};const T=!!P.plugins?.some(e=>typeof e=="string"&&e.startsWith("@redocly/portal-plugin-async-api/"));T&&y.some(e=>e.type==="asyncapi")&&Fe.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");const c=T?y.filter(e=>e.type!=="asyncapi"):y;t=c.map(({markdocChunks:e,relativePath:u,isVirtual:p,customOutputRelativeFile:s,realRelativePath:S})=>({chunks:e??[],relativePath:u,realRelativePath:S,isVirtual:s!=null||p}));const{buildItems:n}=await W(o.serverOutDir),m=(await D.cache.load("content-slugs","content-slugs")).data,h=fe(m),k=e=>le(h(e));for(const e of y){const u=De(e);if(u===void 0)continue;const p=k(e.customOutputRelativeFile||e.relativePath);v[u]=Pe(e,p)}for(const e of c){const u=e.customOutputRelativeFile||e.relativePath,p=k(u);qe(e,p);const{items:s,store:S}=await n({type:e.type,document:e.document,options:e.options,basePath:p,markdownParser:U}),b=`${O}${e.relativePath}`,M=G.isDevelopMode?e.relativePath:void 0,l=$e(e.document),_=l?.["x-metadata"],C=e.isVirtual?void 0:_?.apiId,B={document:e,basePath:p,sourcePath:M,apiId:C,build:{items:s,store:S}};await o.createSharedData(b,z(B,s,S));const J=K(e.config),L=!!e.options.excludeFromSearch,Z=e.type==="openapi",ee=be(s,J),te=me(e),f=ee.map(d=>{const x=d.metadata?.seo,E={fsPath:u,templateId:R,sharedData:[{key:"apiDocsStore",id:b}],serverPropsGetterIds:[A],excludeFromSearch:L,getStaticData:Le(d.label,x,te),[I]:d[I]};return Object.assign(E,xe(d.link,p)),Z&&d.httpVerb&&(E.httpVerb=d.httpVerb,E.metadata={subType:"openapi-operation"}),E});if(!f.length)continue;const H=ke(l,e.type,s),oe=Oe(l?.version),q={type:e.type,title:H,version:oe,description:typeof l?.description=="string"?l.description:void 0,summary:typeof l?.summary=="string"?l.summary:void 0,...l?.["x-metadata"]&&typeof l["x-metadata"]=="object"?l["x-metadata"]:{}};f[0]={...f[0],metadata:q,hasClientRoutes:!0,getSidebar:(d,x)=>Ce(Y(s),p,x),getNavText:()=>H??Me[e.type]??"API Docs",getSearchDocuments:ve(s,q,o.getSearchFacets,o.setSearchFacets,L,S,e.document),getAiDocumentsStore:Ae({getBuild:()=>B.build,metadata:q,document:e.document,specType:e.type,excludeFromSearch:L,basePath:p,getSearchFacets:o.getSearchFacets,markdocTags:{...ae,schemaDefinition:ie}})};const re=f[0];f[0]=f[f.length-1],f[f.length-1]=re;for(const d of f)o.addRoute(d);if(C){const d=Ie(e.config?.apis,e.realRelativePath);g[C]={[I]:d.rbac,[w]:{fsPath:u}}}r.set(b,B)}})},afterRoutesCreated:async(o,D)=>{const{buildItems:R,simplifyAstStructure:A}=await W(o.serverOutDir);for(const c of r.values())Q(o,c.build.items);const P=new Set,y=new Set;for(const{chunks:c,relativePath:n,isVirtual:m}of t){const h=`${O}${n}`,k=Re(o.getAllRoutes(),n);for(const{node:e,markdown:u,pointer:p,key:s,relativePath:S}of c){const{ast:b,compoundHash:M}=await o.parseMarkdoc({input:{content:u,relativePath:S,isVirtual:m},resource:p,context:D,deps:{sharedDataIds:[`${O}${S}`],routeSlugs:k}});if(P.add(p),!(s==="graphql-docs"?e?.description?.value!==void 0:!!s&&_e(e,s,u))||!X(e,s,M))continue;y.add(h);const _=A(b);if(s==="graphql-docs"){e.description&&(e.description.value=_);const C=`${O}${S}`;Be(r.get(C),_)}else s&&(e[s]=_)}}const T=i.difference(P);for(const c of T)D.cache.delete(c);i=P,Object.entries(g).forEach(([c,n])=>{const m=n[w]?.fsPath;if(!m)return;const h=o.getRouteByFsPath(m)?.baseSlug;g[c]={...n,[w]:{...n[w],slug:h},slug:h}}),o.setGlobalData({apiProducts:g});for(const[c,n]of r){if(!y.has(c))continue;const{items:m,store:h}=await R({type:n.document.type,document:n.document.document,options:n.document.options,basePath:n.basePath,markdownParser:U});n.build={items:m,store:h},Q(o,m),await o.createSharedData(c,z(n,m,h))}}}}function Q(t,r){for(const{from:a,to:i}of se(r))t.getConfig().redirects?.[a]||t.getRouteBySlug(a,{followRedirect:!1})||(t.addRouteAlias(a,i),t.addRedirect(a,{to:i,type:301},{trackOriginalSource:!1}))}function z({document:t,basePath:r,sourcePath:a,apiId:i},g,v){return{[I]:K(t.config),[w]:{slug:de(r),fsPath:t.customOutputRelativeFile||t.relativePath},items:g,store:v,options:t.options,baseSlug:r,routesMapping:G.isDevelopMode?we(g,r):{},graphqlPositions:G.isDevelopMode&&t.type==="graphql"?Te(g,r):void 0,sourcePath:a,apiId:i}}function Be(t,r){t?.document.type!=="graphql"||!t.document.options||(t.document.options.info={...t.document.options.info||{},description:r})}function Le(t,r,a){return async function(i){return{...a?{isTranslationFallback:!0}:{},props:{settings:{baseUrlPath:$(i.baseSlug)},disableAutoScroll:!0,seo:{title:t,...r}}}}}function qe(t,r){const a=t.options?.mockServer,i=$(`/_mock${Ee(t.relativePath)}`);a?.url===i&&(t.options={...t.options,mockServer:{...a,url:$(`/_mock${r}`)}})}function xe(t,r){if(t===r)return{};const a=r==="/"?"/":`${r}/`;if(t.startsWith(a)){const i=t.slice(a.length);return i?{slugSuffix:i}:{}}return{slug:t}}function $e(t){if(t&&typeof t=="object"&&"info"in t)return t.info}function Y(t){return t.map(({content:r,items:a,...i})=>({...i,...a&&{items:Y(a)}}))}export{Dt as apiDocsPlugin,xe as toRouteSlugFields};
@@ -1,34 +1,34 @@
1
- import x from"node:path";import{REDOCLY_TEAMS_RBAC as C}from"@redocly/config";import{nodeTypes as $,contentType as g,isGraphqlFieldsNode as pn,resolveGraphqlItemFields as un}from"@redocly/api-docs";import{normalizeApiVersion as dn}from"../utils/normalize-api-version.js";import{replaceFileExtension as v}from"../utils/replace-file-extension.js";import{isResourcePubliclyAccessible as mn,canDownloadApiDefinition as hn,extractTeamsFromScopeItems as $n}from"../../../utils/rbac.js";import{getLlmsTxtMdPathBySlug as K}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{PUBLIC_API_DEFINITIONS_FOLDER as X}from"../../../constants/common.js";import{GRAPHQL_SPEC_SLUG as yn}from"../../../../constants/common.js";import{isPlainObject as N}from"../../../../utils/guards/is-plain-object.js";import{ANONYMOUS_AUTH_DETAILS as gn}from"../../../constants/rbac.js";import{toMarkdown as j}from"../../markdown/search/to-markdown.js";import{createRenderTagFn as bn}from"../../markdown/search/create-render-tag-fn.js";import{getLocaleFromRelativePath as In}from"../../../fs/utils/get-locale-from-relative-path.js";import{getBuildTranslateContext as On}from"../../../utils/l10n/get-build-translate-context.js";import{llmsTxtLink as w}from"../../search/llmstxt/index.js";import{formatDocumentMetadata as Pn}from"../../search/utils.js";import{extractDocumentSearchFacets as Sn}from"./search-facets.js";import{createApiDocsSearchIndexer as An,createLlmDescriptionFormatter as xn}from"./create-indexer.js";function O(e,s){return s==="openapi"&&"openapi"in e}function Z(e,s){return s==="asyncapi"&&"asyncapi"in e}function it({getBuild:e,metadata:s,document:c,specType:o,excludeFromSearch:n,basePath:r,getSearchFacets:t,markdocTags:i}){return async(l,f,d,p)=>{if(n)return;const{items:a,store:m}=e(),h={...p.markdocOptions?.tags,...i},{locale:en,translate:on}=await On(l.slug,p.getGlobalData?.().l10n),P=bn(h,en,on),L=p.getConfig(),D=In(l.fsPath),R=xn(P),V=An(r,R,m?.schemaStore,c,m?.exampleStore,m?.graphqlMeta),F=b=>{for(const u of b)V.addItem(u),u.items?.length&&F(u.items)};F(a);const sn=V.getResult(),_=new Map;for(const b of sn)_.set(b.url,b);const E=typeof s.title=="string"?s.title:void 0,q=dn(s.version),k=Sn(l.metadata||{},E,q,t),S=[],A=[],G=Cn(c,s),z=G?R(G):void 0,W=Tn(s,z,c,o,R),B=Ln(o,s,l.fsPath,L),rn=En(a,L,P),cn=W+B+`
2
- `+rn,ln=W+B;A.push({title:E||"API Overview",description:z,content:cn,slug:r,fsPath:l.fsPath,includeInLLMsTxt:!0}),S.push({title:E||"API Overview",content:ln,url:r,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k});const fn=c&&O(c,o)?c.security:void 0,U=b=>{for(const u of b){if(!u.content||!u.link){u.items?.length&&U(u.items);continue}const an=_.get(u.link),J=u.content.contentType,Q=u[C],H=Q?$n(Q):void 0,Y=H?.length?H:void 0;if(J===g.ITEM){const y=kn(u,c,o)??nn(u,an,o,q,fn,P,m);if(y){const I=u.label||"";A.push({title:I,description:void 0,content:y,slug:u.link,fsPath:l.fsPath,includeInLLMsTxt:!1}),S.push({title:I,content:y,url:u.link,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k,rbacTeams:Y})}}else if(J===g.GROUP){const y=Un(u,L,o,P,m);if(y){const I=u.label||"";A.push({title:I,description:void 0,content:y.llmstxt,slug:u.link,fsPath:l.fsPath,includeInLLMsTxt:!1}),S.push({title:I,content:y.aiSearch,url:u.link,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k,rbacTeams:Y})}}u.items?.length&&U(u.items)}};return U(a),{async getLLMsTxts(){return A},async getSearchDocuments(){return S}}}}function Cn(e,s){const c=N(e?.info)?e.info:void 0,o=N(c?.["x-metadata"])?c["x-metadata"]:{},r=(typeof o.description=="string"?o.description:void 0)??c?.description??s.description;return typeof r=="string"?r||void 0:r&&typeof r=="object"?r:void 0}function Tn(e,s,c,o,n){const r=typeof e.title=="string"?e.title:"",t=typeof e.summary=="string"?e.summary:"",i=typeof e.version=="string"?e.version:"";let l=r?`# ${r}
1
+ import C from"node:path";import{REDOCLY_TEAMS_RBAC as T}from"@redocly/config";import{nodeTypes as y,contentType as b,isGraphqlFieldsNode as pn,resolveGraphqlItemFields as un}from"@redocly/api-docs";import{normalizeApiVersion as dn}from"../utils/normalize-api-version.js";import{replaceFileExtension as N}from"../utils/replace-file-extension.js";import{isResourcePubliclyAccessible as mn,canDownloadApiDefinition as hn,extractTeamsFromScopeItems as yn}from"../../../utils/rbac.js";import{getLlmsTxtMdPathBySlug as K}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{PUBLIC_API_DEFINITIONS_FOLDER as X}from"../../../constants/common.js";import{GRAPHQL_SPEC_SLUG as $n}from"../../../../constants/common.js";import{isPlainObject as $}from"../../../../utils/guards/is-plain-object.js";import{ANONYMOUS_AUTH_DETAILS as gn}from"../../../constants/rbac.js";import{toMarkdown as j}from"../../markdown/search/to-markdown.js";import{createRenderTagFn as bn}from"../../markdown/search/create-render-tag-fn.js";import{getLocaleFromRelativePath as In}from"../../../fs/utils/get-locale-from-relative-path.js";import{getBuildTranslateContext as An}from"../../../utils/l10n/get-build-translate-context.js";import{llmsTxtLink as w}from"../../search/llmstxt/index.js";import{formatDocumentMetadata as Pn}from"../../search/utils.js";import{extractDocumentSearchFacets as On}from"./search-facets.js";import{createApiDocsSearchIndexer as Sn,createLlmDescriptionFormatter as xn}from"./create-indexer.js";function P(e,s){return s==="openapi"&&"openapi"in e}function Z(e,s){return s==="asyncapi"&&"asyncapi"in e}function it({getBuild:e,metadata:s,document:c,specType:o,excludeFromSearch:n,basePath:r,getSearchFacets:t,markdocTags:i}){return async(l,f,d,p)=>{if(n)return;const{items:a,store:m}=e(),h={...p.markdocOptions?.tags,...i},{locale:en,translate:on}=await An(l.slug,p.getGlobalData?.().l10n),O=bn(h,en,on),v=p.getConfig(),D=In(l.fsPath),R=xn(O),V=Sn(r,R,m?.schemaStore,c,m?.exampleStore,m?.graphqlMeta),F=I=>{for(const u of I)V.addItem(u),u.items?.length&&F(u.items)};F(a);const rn=V.getResult(),_=new Map;for(const I of rn)_.set(I.url,I);const E=typeof s.title=="string"?s.title:void 0,q=dn(s.version),k=On(l.metadata||{},E,q,t),S=[],x=[],G=Cn(c,s),z=G?R(G):void 0,W=Tn(s,z,c,o,R),B=Ln(o,s,l.fsPath,v),sn=Rn(a,v,O),cn=W+B+`
2
+ `+sn,ln=W+B;x.push({title:E||"API Overview",description:z,content:cn,slug:r,fsPath:l.fsPath,includeInLLMsTxt:!0}),S.push({title:E||"API Overview",content:ln,url:r,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k});const fn=c&&P(c,o)?c.security:void 0,U=I=>{for(const u of I){if(!u.content||!u.link){u.items?.length&&U(u.items);continue}const an=_.get(u.link),J=u.content.contentType,Q=u[T],H=Q?yn(Q):void 0,Y=H?.length?H:void 0;if(J===b.ITEM){const g=En(u,c,o)??nn(u,an,o,q,fn,O,m);if(g){const A=u.label||"";x.push({title:A,description:void 0,content:g,slug:u.link,fsPath:l.fsPath,includeInLLMsTxt:!1}),S.push({title:A,content:g,url:u.link,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k,rbacTeams:Y})}}else if(J===b.GROUP){const g=kn(u,v,o,O,m);if(g){const A=u.label||"";x.push({title:A,description:void 0,content:g.llmstxt,slug:u.link,fsPath:l.fsPath,includeInLLMsTxt:!1}),S.push({title:A,content:g.aiSearch,url:u.link,fsPath:l.fsPath,locale:D,product:l.product?.name,facets:k,rbacTeams:Y})}}u.items?.length&&U(u.items)}};return U(a),{async getLLMsTxts(){return x},async getSearchDocuments(){return S}}}}function Cn(e,s){const c=$(e?.info)?e.info:void 0,o=$(c?.["x-metadata"])?c["x-metadata"]:{},r=(typeof o.description=="string"?o.description:void 0)??c?.description??s.description;return typeof r=="string"?r||void 0:r&&typeof r=="object"?r:void 0}function Tn(e,s,c,o,n){const r=typeof e.title=="string"?e.title:"",t=typeof e.summary=="string"?e.summary:"",i=typeof e.version=="string"?e.version:"";let l=r?`# ${r}
3
3
 
4
4
  `:"";if(l+=s?`${s}
5
5
 
6
6
  `:"",l+=t?`${t}
7
7
 
8
8
  `:"",l+=i?`Version: ${i}
9
- `:"",c){if(O(c,o)){const{info:f}=c;f?.license?.name&&(l+=`License: ${f.license.name}
10
- `);const d=f["x-metadata"],p=Object.entries(N(d)?d:{}).filter(([m,h])=>m!=="description"||typeof h!="string"),a=Pn(Object.fromEntries(p));a&&(l+=`
9
+ `:"",c){if(P(c,o)){const{info:f}=c;f?.license?.name&&(l+=`License: ${f.license.name}
10
+ `);const d=f["x-metadata"],p=Object.entries($(d)?d:{}).filter(([m,h])=>m!=="description"||typeof h!="string"),a=Pn(Object.fromEntries(p));a&&(l+=`
11
11
  Metadata:
12
12
  ${a}
13
13
  `)}else if(Z(c,o)){const{info:f}=c;f?.license?.name&&(l+=`License: ${f.license.name}
14
14
  `)}}return l+=`
15
- `,l+=Dn(c,o,n),l+=Rn(c,o,n),l}function Ln(e,s,c,o){if(!c)return"";let n,r,t;if(e==="openapi")n=x.posix.join(X,v(c,".yaml")),r="## Download OpenAPI description",t="OpenAPI definition";else if(e==="asyncapi")n=x.posix.join(X,v(c,".yaml")),r="## Download AsyncAPI description",t="AsyncAPI definition";else if(e==="graphql"){const f=x.posix.extname(c)||".graphql";n=x.posix.join(yn,v(c,f)),r="## Download GraphQL schema",t="GraphQL schema"}else return"";if(!hn(n,o.access?.rbac??{},o.access?.requiresLogin??!1,gn))return"";const l=typeof s.title=="string"&&s.title||t;return`${r}
15
+ `,l+=vn(c,o,n),l+=Dn(c,o,n),l}function Ln(e,s,c,o){if(!c)return"";let n,r,t;if(e==="openapi")n=C.posix.join(X,N(c,".yaml")),r="## Download OpenAPI description",t="OpenAPI definition";else if(e==="asyncapi")n=C.posix.join(X,N(c,".yaml")),r="## Download AsyncAPI description",t="AsyncAPI definition";else if(e==="graphql"){const f=C.posix.extname(c)||".graphql";n=C.posix.join($n,N(c,f)),r="## Download GraphQL schema",t="GraphQL schema"}else return"";if(!hn(n,o.access?.rbac??{},o.access?.requiresLogin??!1,gn))return"";const l=typeof s.title=="string"&&s.title||t;return`${r}
16
16
 
17
- - ${w({title:l,description:void 0,slug:n,siteUrl:o.seo?.siteUrl})}`}function Dn(e,s,c){if(!e)return"";if(O(e,s)){const{servers:o}=e;if(!o?.length)return"";let n=`## Servers
17
+ - ${w({title:l,description:void 0,slug:n,siteUrl:o.seo?.siteUrl})}`}function vn(e,s,c){if(!e)return"";if(P(e,s)){const o=Array.isArray(e.servers)?e.servers.filter($):[];if(!o.length)return"";let n=`## Servers
18
18
 
19
- `;for(const r of o)if(r.description&&(n+=`${c(r.description)}
19
+ `;for(const r of o){r.description&&(n+=`${c(r.description)}
20
20
  `),n+=`\`\`\`
21
21
  ${r.url}
22
22
  \`\`\`
23
23
 
24
- `,r.variables){n+=`Variables:
25
- `;for(const[t,i]of Object.entries(r.variables))n+=`- \`${t}\`${i.description?`: ${c(i.description).replace(/\s+/g," ")}`:""}
26
- `,i.default&&(n+=` Default: ${JSON.stringify(i.default)}
27
- `),i.enum&&(n+=` Enum: ${i.enum.map(l=>JSON.stringify(l)).join(", ")}
24
+ `;const t=Object.entries($(r.variables)?r.variables:{}).filter(([,i])=>$(i));if(t.length){n+=`Variables:
25
+ `;for(const[i,l]of t)n+=`- \`${i}\`${l.description?`: ${c(l.description).replace(/\s+/g," ")}`:""}
26
+ `,l.default&&(n+=` Default: ${JSON.stringify(l.default)}
27
+ `),Array.isArray(l.enum)&&(n+=` Enum: ${l.enum.map(f=>JSON.stringify(f)).join(", ")}
28
28
  `);n+=`
29
- `}return n}if(Z(e,s)){const{servers:o}=e;if(!o||!Object.keys(o).length)return"";let n=`## Servers
29
+ `}}return n}if(Z(e,s)){const o=Object.entries($(e.servers)?e.servers:{}).filter(([,r])=>$(r));if(!o.length)return"";let n=`## Servers
30
30
 
31
- `;for(const[r,t]of Object.entries(o))n+=`### ${r}
31
+ `;for(const[r,t]of o)n+=`### ${r}
32
32
 
33
33
  `,t.description&&(n+=`${c(t.description)}
34
34
  `),t.host&&(n+=`Host: ${t.host}
@@ -36,7 +36,7 @@ ${r.url}
36
36
  `),t.protocolVersion&&(n+=`Protocol Version: ${t.protocolVersion}
37
37
  `),t.pathname&&(n+=`Pathname: ${t.pathname}
38
38
  `),n+=`
39
- `;return n}return""}function Rn(e,s,c){if(!e||!O(e,s))return"";const o=e.components?.securitySchemes;if(!o)return"";let n=`## Security
39
+ `;return n}return""}function Dn(e,s,c){if(!e||!P(e,s))return"";const o=e.components?.securitySchemes;if(!o)return"";let n=`## Security
40
40
 
41
41
  `;for(const[r,t]of Object.entries(o)){if(!t||"$ref"in t)continue;const i=t;n+=`### ${r}
42
42
 
@@ -53,19 +53,19 @@ ${r.url}
53
53
  `),f.scopes)){n+=`Scopes:
54
54
  `;for(const[d,p]of Object.entries(f.scopes))n+=`- \`${d}\`: ${p}
55
55
  `}n+=`
56
- `}return n}function En(e,s,c){let o="";const n=(r,t)=>{for(const i of r)if(i.link){if(i.content?.contentType===g.GROUP)o+=`${t} ${i.label||""}
56
+ `}return n}function Rn(e,s,c){let o="";const n=(r,t)=>{for(const i of r)if(i.link){if(i.content?.contentType===b.GROUP)o+=`${t} ${i.label||""}
57
57
 
58
- `,i.items?.length&&n(i.items,t+"#");else if(i.content?.contentType===g.ITEM){if(!M(i,s))continue;const l=i,f=l.httpVerb,d=l.httpPath,p=f&&d?`${f.toUpperCase()} ${d}`:i.label||"",a=i.content?T(i.content.children,c):void 0;o+=` - ${w({title:p,description:a?a.slice(0,200):void 0,slug:K(i.link),siteUrl:s.seo?.siteUrl})}`}}};return n(e,"##"),o}function nn(e,s,c,o,n,r,t){if(!e.content)return;const i=e,l=e.label||"",f=T(e.content.children,r),d=e.content.meta?.deprecated;let p=`# ${l}${d?" (deprecated)":""}
58
+ `,i.items?.length&&n(i.items,t+"#");else if(i.content?.contentType===b.ITEM){if(!M(i,s))continue;const l=i,f=l.httpVerb,d=l.httpPath,p=f&&d?`${f.toUpperCase()} ${d}`:i.label||"",a=i.content?L(i.content.children,c):void 0;o+=` - ${w({title:p,description:a?a.slice(0,200):void 0,slug:K(i.link),siteUrl:s.seo?.siteUrl})}`}}};return n(e,"##"),o}function nn(e,s,c,o,n,r,t){if(!e.content)return;const i=e,l=e.label||"",f=L(e.content.children,r),d=e.content.meta?.deprecated;let p=`# ${l}${d?" (deprecated)":""}
59
59
 
60
60
  `;if(f&&(p+=`${f}
61
61
 
62
62
  `),c==="openapi"||c==="asyncapi"){const a=i.httpVerb,m=i.httpPath;a&&m?p+=`Endpoint: ${a.toUpperCase()} ${m}
63
63
  `:a&&(p+=`Method: ${a.toUpperCase()}
64
64
  `),o&&(p+=`Version: ${o}
65
- `);const h=vn(e.content.children,n);h&&(p+=`Security: ${h}
65
+ `);const h=Un(e.content.children,n);h&&(p+=`Security: ${h}
66
66
  `)}return s?.parameters?.length&&c!=="graphql"&&(p+=`
67
67
  `+Nn(s.parameters)+`
68
- `),c==="graphql"&&(p+=jn(e.content.children,t,r)),p}function kn(e,s,c){if(e.httpVerb!=="tool"||!s||!O(s,c))return;const o=e.content?.meta?.name,n=o?s["x-mcp"]?.tools?.find(t=>t.name===o):void 0;if(!n)return;let r=`# ${e.label||n.name}
68
+ `),c==="graphql"&&(p+=jn(e.content.children,t,r)),p}function En(e,s,c){if(e.httpVerb!=="tool"||!s||!P(s,c))return;const o=e.content?.meta?.name,n=o?s["x-mcp"]?.tools?.find(t=>t.name===o):void 0;if(!n)return;let r=`# ${e.label||n.name}
69
69
 
70
70
  `;return typeof n.description=="string"&&n.description&&(r+=`${n.description}
71
71
 
@@ -81,15 +81,15 @@ ${JSON.stringify(n.inputSchema,null,2)}
81
81
  ${JSON.stringify(n.outputSchema,null,2)}
82
82
  \`\`\`
83
83
 
84
- `),r}function Un(e,s,c,o,n){if(!e.content)return;const r=e.label||"",t=T(e.content.children,o);let i=`# ${r}
84
+ `),r}function kn(e,s,c,o,n){if(!e.content)return;const r=e.label||"",t=L(e.content.children,o);let i=`# ${r}
85
85
 
86
86
  `;if(t&&(i+=`${t}
87
87
 
88
- `),c==="graphql"){let f="";const d=p=>{for(const a of p??[])if(!(!a.content||!M(a,s)))if(a.content.contentType===g.ITEM){const m=nn(a,void 0,c,void 0,void 0,o,n);m&&(f+=`${m}
88
+ `),c==="graphql"){let f="";const d=p=>{for(const a of p??[])if(!(!a.content||!M(a,s)))if(a.content.contentType===b.ITEM){const m=nn(a,void 0,c,void 0,void 0,o,n);m&&(f+=`${m}
89
89
 
90
90
  ---
91
91
 
92
- `)}else a.content.contentType===g.GROUP&&d(a.items)};return d(e.items),{llmstxt:i+f,aiSearch:i}}let l="";if(e.items?.length)for(const f of e.items){if(!f.link||!f.content||f.content.contentType!==g.ITEM||!M(f,s))continue;const d=f,p=d.httpVerb,a=d.httpPath,m=p&&a?`${p.toUpperCase()} ${a}`:f.label||"",h=f.content?T(f.content.children,o):void 0;l+=` - ${w({title:m,description:h?h.slice(0,200):void 0,slug:K(f.link),siteUrl:s.seo?.siteUrl})}`}return{llmstxt:i+l,aiSearch:i}}function vn(e,s){const c=[],o=n=>{for(const r of n)if(r.nodeType===$.SECURITY){const t=r;for(const i of t.requirements)for(const l of i.schemes)l[C]||l.name&&!c.includes(l.name)&&c.push(l.name)}else(r.nodeType===$.CONTAINER||r.nodeType===$.OVERVIEW_SECTION_WRAPPER)&&o(r.children)};if(o(e),c.length)return c.join(", ");if(s?.length){const n=s.flatMap(r=>Object.keys(r));if(n.length)return[...new Set(n)].join(", ")}}function Nn(e){const s={};for(const o of e){const n=`${o.place}${o.mediaType?` (${o.mediaType})`:""}`;s[n]||(s[n]=[]),s[n].push(o)}return Object.entries(s).map(([o,n])=>{const r=n.map(t=>{const i=[...t.path||[],t.name],l=Array.isArray(t.description)?t.description.join(" "):t.description;let f=` - \`${i.join(".")}\` (${t.type}${t.required?", required":""})
92
+ `)}else a.content.contentType===b.GROUP&&d(a.items)};return d(e.items),{llmstxt:i+f,aiSearch:i}}let l="";if(e.items?.length)for(const f of e.items){if(!f.link||!f.content||f.content.contentType!==b.ITEM||!M(f,s))continue;const d=f,p=d.httpVerb,a=d.httpPath,m=p&&a?`${p.toUpperCase()} ${a}`:f.label||"",h=f.content?L(f.content.children,o):void 0;l+=` - ${w({title:m,description:h?h.slice(0,200):void 0,slug:K(f.link),siteUrl:s.seo?.siteUrl})}`}return{llmstxt:i+l,aiSearch:i}}function Un(e,s){const c=[],o=n=>{for(const r of n)if(r.nodeType===y.SECURITY){const t=r;for(const i of t.requirements)for(const l of i.schemes)l[T]||l.name&&!c.includes(l.name)&&c.push(l.name)}else(r.nodeType===y.CONTAINER||r.nodeType===y.OVERVIEW_SECTION_WRAPPER)&&o(r.children)};if(o(e),c.length)return c.join(", ");if(s?.length){const n=s.flatMap(r=>Object.keys(r));if(n.length)return[...new Set(n)].join(", ")}}function Nn(e){const s={};for(const o of e){const n=`${o.place}${o.mediaType?` (${o.mediaType})`:""}`;s[n]||(s[n]=[]),s[n].push(o)}return Object.entries(s).map(([o,n])=>{const r=n.map(t=>{const i=[...t.path||[],t.name],l=Array.isArray(t.description)?t.description.join(" "):t.description;let f=` - \`${i.join(".")}\` (${t.type}${t.required?", required":""})
93
93
  `;return l&&(f+=` ${l.trim()}
94
94
  `),t.enum?f+=` Enum: ${t.enum.map(d=>JSON.stringify(d)).join(", ")}
95
95
  `:t.example&&(f+=` Example: ${t.example}
@@ -97,9 +97,9 @@ ${JSON.stringify(n.outputSchema,null,2)}
97
97
 
98
98
  ${r.join(`
99
99
  `)}`}).join(`
100
- `)}function jn(e,s,c){let o="";const n=r=>{for(const t of r)if(t.nodeType===$.ITEM){const i=pn(t)?un(t,s??{}):void 0;i&&(o+=wn(i,t.variant,c))}else(t.nodeType===$.CONTAINER||t.nodeType===$.OVERVIEW_SECTION_WRAPPER)&&n(t.children)};return n(e),o}function wn(e,s,c){let n=`
100
+ `)}function jn(e,s,c){let o="";const n=r=>{for(const t of r)if(t.nodeType===y.ITEM){const i=pn(t)?un(t,s??{}):void 0;i&&(o+=wn(i,t.variant,c))}else(t.nodeType===y.CONTAINER||t.nodeType===y.OVERVIEW_SECTION_WRAPPER)&&n(t.children)};return n(e),o}function wn(e,s,c){let n=`
101
101
  ## ${tn(s==="return-type"?"Return type":s==="graphql-args"||s==="arguments"?"Arguments":s==="graphql-fields"?"Fields":s)}:
102
102
 
103
103
  `;const r=t=>{const i=t.description?j(Array.isArray(t.description)?t.description:[t.description],{renderTag:c}).trim():"";return` - \`${t.name}\` (${t.type.display})${i?`: ${i}`:""}
104
104
  `};if(e.type){const t=e.type.description?j(Array.isArray(e.type.description)?e.type.description:[e.type.description],{renderTag:c}).trim():"";n+=` Type: ${e.type.display}`,t&&(n+=` - ${t}`),n+=`
105
- `}else if(!e.fields.length)return"";for(const t of e.fields)n+=r(t);return n}function T(e,s){const c=[],o=r=>{for(const t of r)if(t.nodeType===$.MARKDOC){const i=t.content,l=Array.isArray(i)?i:[i],f=j(l,{renderTag:s}).trim();f&&c.push(f)}else(t.nodeType===$.CONTAINER||t.nodeType===$.OVERVIEW_SECTION_WRAPPER)&&o(t.children)};return o(e),c.join(" ").trim()||void 0}function tn(e){return e.charAt(0).toUpperCase()+e.slice(1)}function M(e,s){return s.access?.requiresLogin?!0:mn({slug:e.link||"",[C]:e[C]},s)}export{it as getAiDocumentsStore};
105
+ `}else if(!e.fields.length)return"";for(const t of e.fields)n+=r(t);return n}function L(e,s){const c=[],o=r=>{for(const t of r)if(t.nodeType===y.MARKDOC){const i=t.content,l=Array.isArray(i)?i:[i],f=j(l,{renderTag:s}).trim();f&&c.push(f)}else(t.nodeType===y.CONTAINER||t.nodeType===y.OVERVIEW_SECTION_WRAPPER)&&o(t.children)};return o(e),c.join(" ").trim()||void 0}function tn(e){return e.charAt(0).toUpperCase()+e.slice(1)}function M(e,s){return s.access?.requiresLogin?!0:mn({slug:e.link||"",[T]:e[T]},s)}export{it as getAiDocumentsStore};
@@ -1 +1 @@
1
- import R from"path";import{lintConfig as O,loadConfig as j,createConfigTypes as E}from"@redocly/openapi-core";import{rbacConfigSchema as q,rootRedoclyConfigSchema as S,withPlatformSection as x}from"@redocly/config";import{deepMerge as B}from"../../../../../utils/object/deep-merge.js";import{isPlainObject as y}from"../../../../../utils/guards/is-plain-object.js";import{logger as p}from"../../../../tools/notifiers/logger.js";import{BRANCH_ENV_PREFIX as k}from"../../../../../constants/common.js";import{sanitizeBranchName as I}from"../../../../utils/envs/sanitize-branch-name.js";import{envConfig as C}from"../../../../config/env-config.js";import{ajv as M,safeParsePartial as N}from"../../safe-parse.js";import{formatConfigProblem as _}from"../../format-error.js";import{ExternalResolver as D}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as F}from"../../resolve-mutual-exclusion.js";function v(e,t,s,r){t in e&&e[t]&&typeof e[t]=="string"&&(/^https?:\/\/.*/.test(e[t])||r(new Error(`Invalid ${s} URL: "${e[t]}". ${s} must start with "http://" or "https://".`)))}function G(e,t){if("access"in e&&e.access&&typeof e.access=="object"){const s=e.access;v(s,"logoutReturnUrl","access.logoutReturnUrl",t),v(s,"residency","access.residency",t);const r=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const o of r)o in s&&s[o]!==void 0&&o in e&&e[o]!==void 0&&t(new Error(`Property '${o}' is defined both at root level and in 'access' object. Please use 'access.${o}' to define this configuration.`))}}function z(e){return M.compile(S.properties.graphql.properties.servers.items.properties.url)(e)}function T(e,t,s){if(y(e)&&Array.isArray(e.servers))for(const r of e.servers){const o=y(r)?r.url:void 0;if(typeof o=="string"&&!z(o)){const a=e.servers.indexOf(r),c=`${t}.servers[${a}].url`;s(new Error(`Invalid ${c}: "${o}". It must be an absolute http:// or https:// URL.`))}}}function V(e,t){if(T(e.graphql,"graphql",t),!!y(e.apis))for(const[s,r]of Object.entries(e.apis))y(r)&&T(r.graphql,`apis.${s}.graphql`,t)}async function ue(e,t,s,r){const a=t.getFileInfo(e)?.realRelativePath||e;async function c(){const f=new D(t),m=R.join(t.cwd,a),d=await j({configPath:m,externalRefResolver:f}),h=await r(d.resolvedConfig);if(h===void 0)return d.resolvedConfig;const g=d.document?.source,P=[...g?await O({config:d,externalConfigTypes:E(h,d)}):[],...g?F(d.resolvedConfig,g):[]];if(P.length>0)for(const L of P)s(new Error(_(L,t.cwd)));return d.resolvedConfig}const n=t.exists(e)?await c():{},l=X(n),w=await r(n);v(n,"residency","Residency",s),v(n,"logoutReturnUrl","Logout return URL",s),G(n,s),V(n,s);let u=w?N(w,n):n;u=H(u),u=W(u,s);const{env:b}=u;if(b){const f=C.REDOCLY_ENV,m=b[f]||{},d=C.PUBLIC_REDOCLY_BRANCH_NAME||"",h=d?I(d):"",g=h&&b[`${k}${h}`]||{};u=B(u,g,m)}const i=J(u,l);if(i.imports&&i.imports.length>0){p.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const f=new Set([...i.plugins||[],...i.imports.map(m=>R.posix.join(m,"plugin.js"))]);i.plugins=Array.from(f),delete i.imports}if(i.catalog&&(p.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),i.catalogClassic={...i.catalog},delete i.catalog),i.scorecard&&(p.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),i.scorecardClassic=i.scorecard,delete i.scorecard),i.search?.ai){p.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const f={...i.search?.ai,...i.aiAssistant,suggestions:i.aiAssistant?.suggestions?.length?i.aiAssistant.suggestions:i.search?.ai.suggestions||[]};i.aiAssistant=f,delete i.search.ai}return Y(i)}function Y(e){const t={...e},r={..."access"in e&&e.access&&typeof e.access=="object"?e.access:{}},o=["requiresLogin","logoutReturnUrl","residency","sso","idps","rbac"],a=[];for(const c of o){const n=t[c];n!==void 0&&(a.push(c),c==="requiresLogin"&&r.requiresLogin===void 0&&(r.requiresLogin=n),c==="logoutReturnUrl"&&r.logoutReturnUrl===void 0&&(r.logoutReturnUrl=n),c==="residency"&&r.residency===void 0&&(r.residency=n),c==="sso"&&r.sso===void 0&&(r.sso=n),c==="idps"&&r.idps===void 0&&(r.idps=n),c==="rbac"&&r.rbac===void 0&&(r.rbac=n),delete t[c])}return a.length>0&&p.warn(`The following properties at root level are deprecated: ${a.join(", ")}. Please move them to the 'access' object.`),Object.keys(r).length>0&&(t.access=r),t}function H(e){const t=Object.entries(e.env??{});[e,...t.map(([,o])=>o)].some(o=>o?.mcp?.docs)&&p.warn("The 'mcp.docs' property is deprecated. Please use the 'mcp' properties instead.");const s=e.mcp?{...e,mcp:A(e.mcp)}:e;if(!e.env)return s;const r=t.map(([o,a])=>[o,a?.mcp?{...a,mcp:A(a.mcp)}:a]);return{...s,env:Object.fromEntries(r)}}function A(e){const t=e.docs??{},s={};(e.hide??t.hide)!==void 0&&(s.hide=e.hide===!0||t.hide===!0);const r=e.name??t.name;r!==void 0&&(s.name=r);const o=e.ignore??t.ignore;o!==void 0&&(s.ignore=o);const a=e.publicEndpoint??t.publicEndpoint;return a!==void 0&&(s.publicEndpoint=a),{...e,...s,docs:{...t,...s}}}function K(e){if(!y(e)||e.platform===void 0)return!1;const t=Object.keys(e).filter(s=>s!=="platform");return t.length>0&&t.every(s=>!Object.hasOwn(q.properties,s))}function W(e,t){const s=Object.entries(e.env??{}),r=new Set;let o=!1;for(const n of[e,...s.map(([,l])=>l)])n?.reunite!==void 0&&r.add("The 'reunite' property is deprecated. Please use 'platform' property instead."),n?.reunite!==void 0&&n?.platform!==void 0&&r.add("Both 'platform' and 'reunite' are set. 'reunite' is ignored, so remove it."),[n?.rbac,n?.access?.rbac].some(l=>l?.reunite!==void 0)&&r.add("The 'access.rbac.reunite' property is deprecated. Please use 'access.rbac.platform' property instead."),[n?.rbac,n?.access?.rbac].some(K)&&(o=!0);for(const n of r)p.warn(n);o&&t(new Error("You are using an incorrect format of 'rbac:' configuration. See: https://redocly.com/docs/realm/access"));const a=U(e);if(!e.env)return a;const c=s.map(([n,l])=>[n,l&&U(l)]);return{...a,env:Object.fromEntries(c)}}function U(e){const t=x(e),s=e.rbac?{...t,rbac:$(e.rbac)}:t;return e.access?.rbac?{...s,access:{...e.access,rbac:$(e.access.rbac)}}:s}function $(e){const{reunite:t,...s}=e;return t===void 0?s:{...s,platform:e.platform??t}}function X(e){if(!e.theme)return[];p.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const t=[];for(const s of Object.keys(e.theme))e[s]==null?t.push(s):p.warn(`Detected both '${s}' and 'theme.${s}' properties in redocly.yaml. The 'theme.${s}' property will be ignored and needs to be removed or merged into the '${s}'.`);return t}function J(e,t){if(!e.theme||t.length===0)return e;const s={...e};for(const r of t)s[r]=e.theme[r];return delete s.theme,s}export{Y as ensureAccessBackwardsCompatibility,ue as readAndValidateConfig};
1
+ import R from"path";import{lintConfig as j,loadConfig as E,createConfigTypes as L}from"@redocly/openapi-core";import{findEmptyAgentSection as S,rbacConfigSchema as q,rootRedoclyConfigSchema as x,withPlatformSection as B}from"@redocly/config";import{deepMerge as k}from"../../../../../utils/object/deep-merge.js";import{isPlainObject as v}from"../../../../../utils/guards/is-plain-object.js";import{logger as p}from"../../../../tools/notifiers/logger.js";import{BRANCH_ENV_PREFIX as I}from"../../../../../constants/common.js";import{sanitizeBranchName as M}from"../../../../utils/envs/sanitize-branch-name.js";import{envConfig as C}from"../../../../config/env-config.js";import{ajv as N,safeParsePartial as _}from"../../safe-parse.js";import{formatConfigProblem as D}from"../../format-error.js";import{ExternalResolver as F}from"../../../../fs/utils/external-ref-resolver.js";import{resolveMutuallyExclusiveProps as G}from"../../resolve-mutual-exclusion.js";function y(e,s,t,n){s in e&&e[s]&&typeof e[s]=="string"&&(/^https?:\/\/.*/.test(e[s])||n(new Error(`Invalid ${t} URL: "${e[s]}". ${t} must start with "http://" or "https://".`)))}function z(e,s){if("access"in e&&e.access&&typeof e.access=="object"){const t=e.access;y(t,"logoutReturnUrl","access.logoutReturnUrl",s),y(t,"residency","access.residency",s);const n=["requiresLogin","logoutReturnUrl","residency","sso","rbac"];for(const r of n)r in t&&t[r]!==void 0&&r in e&&e[r]!==void 0&&s(new Error(`Property '${r}' is defined both at root level and in 'access' object. Please use 'access.${r}' to define this configuration.`))}}function V(e){return N.compile(x.properties.graphql.properties.servers.items.properties.url)(e)}function A(e,s,t){if(v(e)&&Array.isArray(e.servers))for(const n of e.servers){const r=v(n)?n.url:void 0;if(typeof r=="string"&&!V(r)){const a=e.servers.indexOf(n),c=`${s}.servers[${a}].url`;t(new Error(`Invalid ${c}: "${r}". It must be an absolute http:// or https:// URL.`))}}}function Y(e,s){if(A(e.graphql,"graphql",s),!!v(e.apis))for(const[t,n]of Object.entries(e.apis))v(n)&&A(n.graphql,`apis.${t}.graphql`,s)}function H(e,s){const t=[["",e],...Object.entries(e.env??{}).map(([n,r])=>[`env.${n}.`,r])];for(const[n,r]of t){const a=S(r);a&&s(new Error(`Invalid ${n}${a}.agent: it must set at least one option.`))}}async function me(e,s,t,n){const a=s.getFileInfo(e)?.realRelativePath||e;async function c(){const f=new F(s),m=R.join(s.cwd,a),d=await E({configPath:m,externalRefResolver:f}),h=await n(d.resolvedConfig);if(h===void 0)return d.resolvedConfig;const g=d.document?.source,P=[...g?await j({config:d,externalConfigTypes:L(h,d)}):[],...g?G(d.resolvedConfig,g):[]];if(P.length>0)for(const U of P)t(new Error(D(U,s.cwd)));return d.resolvedConfig}const o=s.exists(e)?await c():{},l=Q(o),w=await n(o);y(o,"residency","Residency",t),y(o,"logoutReturnUrl","Logout return URL",t),z(o,t),Y(o,t),H(o,t);let u=w?_(w,o):o;u=W(u),u=J(u,t);const{env:b}=u;if(b){const f=C.REDOCLY_ENV,m=b[f]||{},d=C.PUBLIC_REDOCLY_BRANCH_NAME||"",h=d?M(d):"",g=h&&b[`${I}${h}`]||{};u=k(u,g,m)}const i=Z(u,l);if(i.imports&&i.imports.length>0){p.warn("The 'imports' property is deprecated. Please use 'plugins' property instead.");const f=new Set([...i.plugins||[],...i.imports.map(m=>R.posix.join(m,"plugin.js"))]);i.plugins=Array.from(f),delete i.imports}if(i.catalog&&(p.warn("The 'catalog' property is deprecated. Please use 'catalogClassic' property instead."),i.catalogClassic={...i.catalog},delete i.catalog),i.scorecard&&(p.warn("The 'scorecard' property is deprecated. Please use 'scorecardClassic' property instead."),i.scorecardClassic=i.scorecard,delete i.scorecard),i.search?.ai){p.warn("The 'search.ai' property is deprecated. Please use 'aiAssistant' property instead.");const f={...i.search?.ai,...i.aiAssistant,suggestions:i.aiAssistant?.suggestions?.length?i.aiAssistant.suggestions:i.search?.ai.suggestions||[]};i.aiAssistant=f,delete i.search.ai}return K(i)}function K(e){const s={...e},n={..."access"in e&&e.access&&typeof e.access=="object"?e.access:{}},r=["requiresLogin","logoutReturnUrl","residency","sso","idps","rbac"],a=[];for(const c of r){const o=s[c];o!==void 0&&(a.push(c),c==="requiresLogin"&&n.requiresLogin===void 0&&(n.requiresLogin=o),c==="logoutReturnUrl"&&n.logoutReturnUrl===void 0&&(n.logoutReturnUrl=o),c==="residency"&&n.residency===void 0&&(n.residency=o),c==="sso"&&n.sso===void 0&&(n.sso=o),c==="idps"&&n.idps===void 0&&(n.idps=o),c==="rbac"&&n.rbac===void 0&&(n.rbac=o),delete s[c])}return a.length>0&&p.warn(`The following properties at root level are deprecated: ${a.join(", ")}. Please move them to the 'access' object.`),Object.keys(n).length>0&&(s.access=n),s}function W(e){const s=Object.entries(e.env??{});[e,...s.map(([,r])=>r)].some(r=>r?.mcp?.docs)&&p.warn("The 'mcp.docs' property is deprecated. Please use the 'mcp' properties instead.");const t=e.mcp?{...e,mcp:$(e.mcp)}:e;if(!e.env)return t;const n=s.map(([r,a])=>[r,a?.mcp?{...a,mcp:$(a.mcp)}:a]);return{...t,env:Object.fromEntries(n)}}function $(e){const s=e.docs??{},t={};(e.hide??s.hide)!==void 0&&(t.hide=e.hide===!0||s.hide===!0);const n=e.name??s.name;n!==void 0&&(t.name=n);const r=e.ignore??s.ignore;r!==void 0&&(t.ignore=r);const a=e.publicEndpoint??s.publicEndpoint;return a!==void 0&&(t.publicEndpoint=a),{...e,...t,docs:{...s,...t}}}function X(e){if(!v(e)||e.platform===void 0)return!1;const s=Object.keys(e).filter(t=>t!=="platform");return s.length>0&&s.every(t=>!Object.hasOwn(q.properties,t))}function J(e,s){const t=Object.entries(e.env??{}),n=new Set;let r=!1;for(const o of[e,...t.map(([,l])=>l)])o?.reunite!==void 0&&n.add("The 'reunite' property is deprecated. Please use 'platform' property instead."),o?.reunite!==void 0&&o?.platform!==void 0&&n.add("Both 'platform' and 'reunite' are set. 'reunite' is ignored, so remove it."),[o?.rbac,o?.access?.rbac].some(l=>l?.reunite!==void 0)&&n.add("The 'access.rbac.reunite' property is deprecated. Please use 'access.rbac.platform' property instead."),[o?.rbac,o?.access?.rbac].some(X)&&(r=!0);for(const o of n)p.warn(o);r&&s(new Error("You are using an incorrect format of 'rbac:' configuration. See: https://redocly.com/docs/realm/access"));const a=T(e);if(!e.env)return a;const c=t.map(([o,l])=>[o,l&&T(l)]);return{...a,env:Object.fromEntries(c)}}function T(e){const s=B(e),t=e.rbac?{...s,rbac:O(e.rbac)}:s;return e.access?.rbac?{...t,access:{...e.access,rbac:O(e.access.rbac)}}:t}function O(e){const{reunite:s,...t}=e;return s===void 0?t:{...t,platform:e.platform??s}}function Q(e){if(!e.theme)return[];p.warn("The 'theme' property in redocly.yaml is deprecated. Please move all of the properties from 'theme' to the root of the config.");const s=[];for(const t of Object.keys(e.theme))e[t]==null?s.push(t):p.warn(`Detected both '${t}' and 'theme.${t}' properties in redocly.yaml. The 'theme.${t}' property will be ignored and needs to be removed or merged into the '${t}'.`);return s}function Z(e,s){if(!e.theme||s.length===0)return e;const t={...e};for(const n of s)t[n]=e.theme[n];return delete t.theme,t}export{K as ensureAccessBackwardsCompatibility,me as readAndValidateConfig};
@@ -1 +1 @@
1
- import{buildCodeSamples as v,getRequestBodySamples as d,normalizeOptions as f,resolveOperationSampleContext as S}from"@redocly/api-docs";import{setNodeAttributeValue as O}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{loadOpenapiBundle as b}from"./helpers/load-openapi-bundle.js";import{getOptionalAttribute as t}from"./utils.js";const h={curl:"shell",JavaScript:"javascript","Node.js":"javascript",Python:"python",Java:"java","Java8+Apache":"java","C#":"csharp","C#+Newtonsoft":"csharp",PHP:"php",Go:"go",Ruby:"ruby",R:"r"};async function N(e,u,x,{context:g}){const o=await b(e,g);if(!o)return;const i=t(e,"language"),l=t(e,"options"),n={exampleKey:t(e,"exampleKey"),mimeType:t(e,"mimeType"),parameters:t(e,"parameters"),requestBody:t(e,"requestBody"),environments:t(e,"environments"),environment:t(e,"environment")},y={...o.rawOptions,...l,...o.rawOptions.mockServer&&{mockServer:{...o.rawOptions.mockServer,position:"off"}},codeSamples:{...o.rawOptions.codeSamples,...l?.codeSamples,...i&&{languages:[{lang:i}]}}},m=f(y),r=S(o.definition,m,{operationId:t(e,"operationId"),pointer:t(e,"pointer")});if(!r)return;const s=v(r,n).map(a=>({lang:h[a.lang]??a.lang.toLowerCase(),title:a.label??a.lang,source:a.source})),c=m.codeSamples?.languages??[],p=c.findIndex(({lang:a})=>a==="Payload");if(p!==-1){const a=d(r,{exampleKey:n.exampleKey,mimeType:n.mimeType,titlePrefix:c[p].label});s.splice(p,0,...a)}s.length&&O(e,u,s)}export{N as resolveOpenapiCodeSamples};
1
+ import{buildCodeSamples as v,getRequestBodySamples as d,normalizeOptions as f,resolveOperationSampleContext as S}from"@redocly/api-docs";import{setNodeAttributeValue as O}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{loadOpenapiBundle as b}from"./helpers/load-openapi-bundle.js";import{getOptionalAttribute as t}from"./utils.js";const h={curl:"shell",JavaScript:"javascript","Node.js":"javascript",Python:"python",Java:"java","Java8+Apache":"java","C#":"csharp","C#+Newtonsoft":"csharp",PHP:"php",Go:"go",Ruby:"ruby",R:"r"};async function N(e,u,x,{context:g}){const o=await b(e,g);if(!o)return;const i=t(e,"language"),l=t(e,"options"),n={exampleKey:t(e,"exampleKey"),mimeType:t(e,"mimeType"),parameters:t(e,"parameters"),requestBody:t(e,"requestBody"),environments:t(e,"environments"),environment:t(e,"environment")},y={...o.rawOptions,...l,...o.rawOptions.mockServer&&{mockServer:{...o.rawOptions.mockServer,position:"off"}},codeSamples:{...o.rawOptions.codeSamples,...l?.codeSamples,...i&&{languages:[{lang:i}]}}},m=f(y),r=S(o.definition,m,{operationId:t(e,"operationId"),pointer:t(e,"pointer")});if(!r)return;const s=v(r,n).map(a=>({lang:h[a.lang]??a.lang?.toLowerCase(),title:a.label??a.lang,source:a.source})),c=m.codeSamples?.languages??[],p=c.findIndex(({lang:a})=>a==="Payload");if(p!==-1){const a=d(r,{exampleKey:n.exampleKey,mimeType:n.mimeType,titlePrefix:c[p].label});s.splice(p,0,...a)}s.length&&O(e,u,s)}export{N as resolveOpenapiCodeSamples};
@@ -21,6 +21,7 @@ export type StoreOptions = {
21
21
  export declare class Store {
22
22
  #private;
23
23
  routesBySlug: Map<string, PageRouteDetails>;
24
+ routeAliases: Map<string, string>;
24
25
  staticFilePaths: StaticFilePaths;
25
26
  replacedEnvVars: Record<string, {
26
27
  original: string;
@@ -134,6 +135,8 @@ export declare class Store {
134
135
  getRouteBySlug: (slug: string, opts?: {
135
136
  followRedirect?: boolean;
136
137
  }) => PageRouteDetails | undefined;
138
+ /** Makes `from` resolve to the route at `to` wherever a redirect would be followed (link resolution, the link checker), without an HTTP redirect; unlike `addRedirect` it needs no entitlement. */
139
+ addRouteAlias: (from: string, to: string) => void;
137
140
  hasRouteOrRedirectBySlug: (slug: string) => boolean;
138
141
  getRoutesByTemplateId: (templateId: string) => PageRouteInit[];
139
142
  getAllRoutesForLocale: (locale?: string) => PageRouteDetails[];
@@ -1 +1 @@
1
- import k from"@redocly/markdoc";import{writeFileSync as D}from"node:fs";import{readFile as R}from"node:fs/promises";import{join as g}from"node:path";import{parseAndResolveMarkdoc as F}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as L}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as m}from"../constants/common.js";import{DEFAULT_TITLE as H,MARKDOC_PARTIALS_DATA_KEY as y,MARKDOC_PARTIALS_DEPS_KEY as G}from"./constants/common.js";import{GATED_MARKDOC_TAGS as v}from"./constants/entitlements.js";import{isObject as _}from"../utils/guards/is-object.js";import{mapObject as N}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as B}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as u}from"../utils/path/normalize-route-slug.js";import{isLocalLink as E}from"../utils/path/is-local-link.js";import{reporter as P}from"./tools/notifiers/reporter.js";import{logger as h}from"./tools/notifiers/logger.js";import{sha1 as I}from"./utils/crypto/sha1.js";import{envConfig as j,setEnv as V}from"./config/env-config.js";import{KvService as q}from"./persistence/kv/services/kv-service.js";import{SandboxContext as J}from"./utils/sandbox-context.js";import{isAllowedEnv as U}from"./utils/envs/get-api-route-allowed-env-variables.js";import{ensureDir as x,writeSharedData as K}from"./utils/index.js";import{renderComponents as W}from"./ssr/render.js";import{readStaticData as $,writeStaticData as z}from"./utils/static-data.js";import{getMarkdocOptions as Y}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as C}from"./entitlements/entitlements-provider.js";import{isRouteReserved as Z}from"./plugins/get-reserved-routes.js";import{isL10nPath as Q}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as X}from"./utils/globs.js";import{createDefaultStoreConfig as ee,resolveConfigEntries as te,resolveStoreConfig as se}from"./store-config.js";import{findRedirect as re}from"./utils/redirects/find-redirect.js";import{followRedirectChain as oe}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as ae}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as ie}from"../cli/telemetry/helpers/trace-step.js";const b={routesBySlug:"map",staticFilePaths:"object",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},O="store.json",A="store-config.json",T="PLAN_GATES",ne=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Ue="userDefinedApiFunctions";class S{routesBySlug=new Map;staticFilePaths={};replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#a=void 0;config=ee();configFile;#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#h=Promise.resolve();#u;#e=!1;#r=0;#f=0;#o=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:r}){this.#i=t,this.outdir=e,this.serverMode=s,this.serverOutDir=r,J.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(o=>{this.#n=o})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#o.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const r of this.listeners.get(e)||new Set)t?r(t,...s):r(...s)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#o.values())this.runListeners(...e);this.#o.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#h=new Promise(e=>{this.#u=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#u?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await ie("com.redocly.build.reloadMarkdocOptions",async()=>{const e=C.instance(),t=await Y(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([r])=>v[r]!=null?e.canAccessFeature(v[r]):!0));this.#a={...t,tags:s}})}get markdocOptions(){return{...this.#a,partials:this.getGlobalConfig(y),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>q.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:t,deps:s,resource:r})=>{const{data:{info:o,ast:a},compoundHash:c}=await F(e,this.markdocOptions,{actions:this,context:t},r);for(const i of o.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const l=this.sharedDataDeps.get(n)||new Set;l.add(i),this.sharedDataDeps.set(n,l)}}for(const i of o.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const l=this.routesDynamicComponents.get(n)||new Set;l.add(i),this.routesDynamicComponents.set(n,l)}for(const n of s?.sharedDataIds||[]){const l=this.sharedDataMarkdocComponents.get(n)||new Set;l.add(i),this.sharedDataMarkdocComponents.set(n,l)}}if(s?.routeSlugs&&o.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const l of o.partials)n.includes(l)||n.push(l);this.routesPartials.set(i,n)}return{info:o,ast:a,compoundHash:c}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setStaticFilePaths=e=>{this.staticFilePaths=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const a of t)for(const c in this.replacedEnvVars)if(c===a||c.startsWith(`${a}:`)){const i=c.split(":"),{error:n,value:l}=w(e,i);(n||l!==this.replacedEnvVars[c].replaced)&&delete this.replacedEnvVars[c]}const{config:s,unsetEnvVars:r,replacedValues:o}=te(e);for(const a of r)this.unsetEnvVars.add(a);Object.assign(this.replacedEnvVars,o),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t,s={})=>{if(!C.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const a=u(e).toLowerCase();this.config.redirects[a]=t;const{trackOriginalSource:c=!0}=s,i=this.getGlobalConfig("originalRedirectSources");c&&Array.isArray(i)&&!i.includes(a)&&i.push(a),a.endsWith("*")&&ae(this.config.wildcardRedirectsTree,a)};getRedirect=e=>{const t=u(e).toLowerCase(),s=re(t,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!s)return null;if(E(s.to)){const r=u(s.to).toLowerCase();if(!r.endsWith("*")&&oe(r,[t],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:s.to,type:s.type}};createSharedData=async(e,t,s)=>{if(s&&this.#t[e]===s)return e;const r=JSON.stringify(t),o=s??I(r);return this.#t[e]===o||(this.#t[e]=o,await K(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=B(e),o=this.routesSharedData.get(r)||{};o[t]=s,this.routesSharedData.set(r,o),h.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};getPartialsForRoute=e=>{const t=this.getGlobalConfig(y)||{},s=this.routesPartials.get(e);if(!s||s.length===0)return{};const r=this.getGlobalConfig(G)||{},o=new Set(s),a=Array.from(s);for(let i=0;i<a.length;i++){const n=a[i],l=r[n]?.partials??[];for(const d of l)o.has(d)||(o.add(d),a.push(d))}const c={};for(const i of o)t[i]&&(c[i]=t[i]);return c};addRoute=e=>{const s={...X(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),h.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[m,...this.lifecycleContext?.fs.localeFolders||[]].map(o=>({code:o,name:o}));for(const o of r){const a=L(e,m,o.code,r);this.addRouteSharedData(a,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),h.verbose("Created API route %s",e.slug)};addMcpTools=(e,t)=>{for(const s of t){const r=this.mcpToolHandlers.get(s.name);r&&r.importPath!==e&&h.warn('MCP tool "%s" from %s overwrites the tool registered from %s',s.name,e,r.importPath);const o=s.hasAvailabilityGate??(r?.importPath===e?r.hasAvailabilityGate:void 0);this.mcpToolHandlers.set(s.name,{...s,importPath:e,hasAvailabilityGate:o}),h.verbose("Created MCP tool %s",s.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const t of e){const s=this.mcpToolHandlers.get(t);s&&this.mcpToolHandlers.set(t,{...s,hasAvailabilityGate:!0})}};addSkills=e=>{for(const t of e)this.skills.set(t.slug,t),h.verbose("Discovered skill %s",t.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const t of e)this.mcpToolHandlers.delete(t)};addMiddleware=e=>{this.middleware.push(e),h.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(a=>a.name.toLowerCase())),o=[...(this.config.responseHeaders[e]??[]).filter(a=>!s.has(a.name.toLowerCase())),...t];this.config.responseHeaders[e]=o};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,r=this.getRedirect(e);return s&&r?this.routesBySlug.get(u(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||Z(e,this.getConfig()))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!E(t.to))return!0;const s=u(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=m)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(r=>e===m?!Q(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);clearRequestHandlersByPrefix=e=>{for(const t of this.apiRoutesRequestHandlers.keys())t.startsWith(e)&&this.apiRoutesRequestHandlers.delete(t)};registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&z(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return $(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:l,context:d,resource:f})=>this.parseMarkdoc({input:l,context:d,deps:{routeSlugs:[e.slug]},resource:f})},o=await e.getStaticData?.(e,r)||{},a=new Set(this.routesDynamicComponents.get(e.slug)),c=this.routesSharedData.get(e.slug)||{};for(const l of Object.values(c)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(p=>a.add(p));const f=this.sharedDataDeps.get(l);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=o?.frontmatter||{};return{...o,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...o.props,dynamicMarkdocComponents:Array.from(a),metadata:{...o?.props?.metadata,...e.metadata},seo:{title:H,...i,...o.props?.seo,siteUrl:i?.siteUrl},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):W(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};#p(){const e=[];for(const[s,r]of Object.entries(b))switch(r){case"map":{const o=Array.from(this[s].entries());e.push([s,o]);break}case"object":e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[T]=j.PLAN_GATES,t}static#g(e,t){const s=new S(t);for(const[o,a]of Object.entries(b))switch(a){case"map":s[o]=new Map(e[o]);break;case"object":s[o]=e[o];break;default:throw new Error("Invalid format")}const r=e[T];return r&&V("PLAN_GATES",r),s}async writeServerFiles(){x(this.serverOutDir),D(g(this.serverOutDir,O),JSON.stringify(this.#p())),D(g(this.serverOutDir,A),JSON.stringify(await this.getConfigWithEnvPlaceholders()))}static async fromServerFiles(e){const t=g(e.serverOutDir,A),{config:s,env:r}=se(JSON.parse(await R(t,"utf8")));s[y]=ce(s[y]);const o=JSON.parse(await R(g(e.serverOutDir,O),"utf8")),a=S.#g(o,e);a.config=s;const c=Object.fromEntries(Object.entries(r).filter(([i])=>U(i)));return a.configFile={path:t,env:c,config:{...s}},a}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],r=t.split(":"),o=r.pop(),{error:a,value:c}=w(e,r);if(a||!_(c)&&!Array.isArray(c)){await P.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}c[o]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!ne.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await P.panicOnBuildContentError(t)}}function ce(M){return N(M,e=>k.Ast.fromJSON(JSON.stringify(e)))}export{S as Store,Ue as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import k from"@redocly/markdoc";import{writeFileSync as S}from"node:fs";import{readFile as D}from"node:fs/promises";import{join as g}from"node:path";import{parseAndResolveMarkdoc as F}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as L}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as m}from"../constants/common.js";import{DEFAULT_TITLE as H,MARKDOC_PARTIALS_DATA_KEY as y,MARKDOC_PARTIALS_DEPS_KEY as G}from"./constants/common.js";import{GATED_MARKDOC_TAGS as v}from"./constants/entitlements.js";import{isObject as _}from"../utils/guards/is-object.js";import{mapObject as N}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as B}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as d}from"../utils/path/normalize-route-slug.js";import{isLocalLink as E}from"../utils/path/is-local-link.js";import{reporter as P}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as I}from"./utils/crypto/sha1.js";import{envConfig as j,setEnv as V}from"./config/env-config.js";import{KvService as q}from"./persistence/kv/services/kv-service.js";import{SandboxContext as J}from"./utils/sandbox-context.js";import{isAllowedEnv as U}from"./utils/envs/get-api-route-allowed-env-variables.js";import{ensureDir as x,writeSharedData as K}from"./utils/index.js";import{renderComponents as W}from"./ssr/render.js";import{readStaticData as $,writeStaticData as z}from"./utils/static-data.js";import{getMarkdocOptions as Y}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as C}from"./entitlements/entitlements-provider.js";import{isRouteReserved as Z}from"./plugins/get-reserved-routes.js";import{isL10nPath as Q}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as X}from"./utils/globs.js";import{createDefaultStoreConfig as ee,resolveConfigEntries as te,resolveStoreConfig as se}from"./store-config.js";import{findRedirect as re}from"./utils/redirects/find-redirect.js";import{followRedirectChain as ae}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as oe}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as ie}from"../cli/telemetry/helpers/trace-step.js";const A={routesBySlug:"map",staticFilePaths:"object",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},b="store.json",O="store-config.json",T="PLAN_GATES",ne=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Ue="userDefinedApiFunctions";class R{routesBySlug=new Map;routeAliases=new Map;staticFilePaths={};replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#o=void 0;config=ee();configFile;#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#l;#c=Promise.resolve();#d;#h=Promise.resolve();#u;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:r}){this.#i=t,this.outdir=e,this.serverMode=s,this.serverOutDir=r,J.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(a=>{this.#n=a})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#a.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const r of this.listeners.get(e)||new Set)t?r(t,...s):r(...s)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#l=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#c,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#l?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#c=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#h=new Promise(e=>{this.#u=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#u?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await ie("com.redocly.build.reloadMarkdocOptions",async()=>{const e=C.instance(),t=await Y(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([r])=>v[r]!=null?e.canAccessFeature(v[r]):!0));this.#o={...t,tags:s}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(y),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>q.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:t,deps:s,resource:r})=>{const{data:{info:a,ast:o},compoundHash:l}=await F(e,this.markdocOptions,{actions:this,context:t},r);for(const i of a.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of a.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(s?.routeSlugs&&a.partials?.length)for(const i of s.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of a.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:a,ast:o,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setStaticFilePaths=e=>{this.staticFilePaths=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const o of t)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=w(e,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{config:s,unsetEnvVars:r,replacedValues:a}=te(e);for(const o of r)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t,s={})=>{if(!C.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const o=d(e).toLowerCase();this.config.redirects[o]=t;const{trackOriginalSource:l=!0}=s,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&oe(this.config.wildcardRedirectsTree,o)};getRedirect=e=>{const t=d(e).toLowerCase(),s=re(t,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!s)return null;if(E(s.to)){const r=d(s.to).toLowerCase();if(!r.endsWith("*")&&ae(r,[t],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:s.to,type:s.type}};createSharedData=async(e,t,s)=>{if(s&&this.#t[e]===s)return e;const r=JSON.stringify(t),a=s??I(r);return this.#t[e]===a||(this.#t[e]=a,await K(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=B(e),a=this.routesSharedData.get(r)||{};a[t]=s,this.routesSharedData.set(r,a),u.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};getPartialsForRoute=e=>{const t=this.getGlobalConfig(y)||{},s=this.routesPartials.get(e);if(!s||s.length===0)return{};const r=this.getGlobalConfig(G)||{},a=new Set(s),o=Array.from(s);for(let i=0;i<o.length;i++){const n=o[i],c=r[n]?.partials??[];for(const h of c)a.has(h)||(a.add(h),o.push(h))}const l={};for(const i of a)t[i]&&(l[i]=t[i]);return l};addRoute=e=>{const s={...X(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),u.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[m,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const o=L(e,m,a.code,r);this.addRouteSharedData(o,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),u.verbose("Created API route %s",e.slug)};addMcpTools=(e,t)=>{for(const s of t){const r=this.mcpToolHandlers.get(s.name);r&&r.importPath!==e&&u.warn('MCP tool "%s" from %s overwrites the tool registered from %s',s.name,e,r.importPath);const a=s.hasAvailabilityGate??(r?.importPath===e?r.hasAvailabilityGate:void 0);this.mcpToolHandlers.set(s.name,{...s,importPath:e,hasAvailabilityGate:a}),u.verbose("Created MCP tool %s",s.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const t of e){const s=this.mcpToolHandlers.get(t);s&&this.mcpToolHandlers.set(t,{...s,hasAvailabilityGate:!0})}};addSkills=e=>{for(const t of e)this.skills.set(t.slug,t),u.verbose("Discovered skill %s",t.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const t of e)this.mcpToolHandlers.delete(t)};addMiddleware=e=>{this.middleware.push(e),u.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,t)=>{this.config.responseHeaders||(this.config.responseHeaders={});const s=new Set(t.map(o=>o.name.toLowerCase())),a=[...(this.config.responseHeaders[e]??[]).filter(o=>!s.has(o.name.toLowerCase())),...t];this.config.responseHeaders[e]=a};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,r=this.getRedirect(e);if(s&&r)return this.routesBySlug.get(d(r.to));const a=s?this.routeAliases.get(d(e).toLowerCase()):void 0;return this.routesBySlug.get(a??e)};addRouteAlias=(e,t)=>{this.routeAliases.set(d(e).toLowerCase(),d(t))};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||this.routeAliases.has(d(e).toLowerCase())||Z(e,this.getConfig()))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!E(t.to))return!0;const s=d(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=m)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(r=>e===m?!Q(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);clearRequestHandlersByPrefix=e=>{for(const t of this.apiRoutesRequestHandlers.keys())t.startsWith(e)&&this.apiRoutesRequestHandlers.delete(t)};registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&z(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return $(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:h,resource:f})=>this.parseMarkdoc({input:c,context:h,deps:{routeSlugs:[e.slug]},resource:f})},a=await e.getStaticData?.(e,r)||{},o=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const h=this.sharedDataMarkdocComponents.get(c);h&&h.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(o),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:H,...i,...a.props?.seo,siteUrl:i?.siteUrl},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):W(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.routeAliases.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};#p(){const e=[];for(const[s,r]of Object.entries(A))switch(r){case"map":{const a=Array.from(this[s].entries());e.push([s,a]);break}case"object":e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[T]=j.PLAN_GATES,t}static#g(e,t){const s=new R(t);for(const[a,o]of Object.entries(A))switch(o){case"map":s[a]=new Map(e[a]);break;case"object":s[a]=e[a];break;default:throw new Error("Invalid format")}const r=e[T];return r&&V("PLAN_GATES",r),s}async writeServerFiles(){x(this.serverOutDir),S(g(this.serverOutDir,b),JSON.stringify(this.#p())),S(g(this.serverOutDir,O),JSON.stringify(await this.getConfigWithEnvPlaceholders()))}static async fromServerFiles(e){const t=g(e.serverOutDir,O),{config:s,env:r}=se(JSON.parse(await D(t,"utf8")));s[y]=le(s[y]);const a=JSON.parse(await D(g(e.serverOutDir,b),"utf8")),o=R.#g(a,e);o.config=s;const l=Object.fromEntries(Object.entries(r).filter(([i])=>U(i)));return o.configFile={path:t,env:l,config:{...s}},o}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],r=t.split(":"),a=r.pop(),{error:o,value:l}=w(e,r);if(o||!_(l)&&!Array.isArray(l)){await P.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}l[a]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!ne.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await P.panicOnBuildContentError(t)}}function le(M){return N(M,e=>k.Ast.fromJSON(JSON.stringify(e)))}export{R as Store,Ue as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -28,6 +28,10 @@ export declare class Logger {
28
28
  timeMs: number;
29
29
  } | undefined;
30
30
  success(message: string, ...args: unknown[]): void;
31
+ /**
32
+ * Status line: describes the current state (error count, preview URL, ...).
33
+ * In non-interactive mode it is printed only when its text changes, so repeated rebuilds don't flood the log.
34
+ */
31
35
  logInFooter(id: string, message: string, ...args: unknown[]): void;
32
36
  successTime(timingId: symbol | string, message: string, ...args: unknown[]): {
33
37
  message: string;
@@ -2,7 +2,7 @@ import{envConfig as h}from"../../config/env-config.js";import{logger as e}from".
2
2
  `+r.stack),h.isBuildMode?await this.panic(r,...t):this.pushError(r,"PANIC",...t)}async panicOnBuildContentErrorForRealFile(r,t,o,...i){C(t,o)||await this.panicOnBuildContentError(r,...i)}async panicOnBuildContentError(r,...t){r instanceof Error&&(r=r.message+`
3
3
  `+r.stack),h.isBuildMode?await this.panicOnContentError(r,...t):this.pushError(r,"PANIC",...t)}async panic(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
4
4
  `+r.stack):o=new Error(r),e.error(r,...t),u.sendCliErrorCaughtMessage([{id:"cliId",object:"cli",uri:"urn:redocly:realm:api:cli:cliId",message:r}]),await d.exitWithCode(1,o)}async panicOnContentError(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
5
- `+r.stack):o=new Error(r),e.contentError(r,...t),u.sendCliErrorCaughtMessage([{id:"cliId",object:"cli",uri:"urn:redocly:realm:api:cli:cliId",message:r,scope:"content"}]),await d.exitWithCode(1,o)}reportMarkdocProblem(r){this.#o.push(r)}clearErrors(){this.#r=[]}clearMarkdocProblems(){this.#o=[]}clearEsbuildProblems(){this.#e.clear()}clearPageRenderProblems(){this.#t=[]}getCompilationProblem(r){return this.#e.get(r)}getCompilationProblems(){return[...this.#e.values()]}getPageRenderProblems(){return this.#t}getPageRenderProblem(r){return this.#t.find(t=>t.sourceFileRelativePath===r)}getProblems(){return[...this.#r,...this.getCompilationProblems(),...this.#o,...this.#t]}summary(r,t=0){const o=this.getProblems(),i=this.#o.filter(s=>s.type==="BROKEN_LINK").length,l=this.#r.filter(s=>s.type==="BROKEN_LINK").length,f=this.#o.length-i,E=this.#r.length-l+this.getCompilationProblems().length+this.#t.length;return e.logInFooter("validate",o.length?a(" \u274C Status: %s markdoc errors, %s broken links, %s other errors"):" \u2705 Status: No errors found",f,i+l,E),t!==0&&e.logInFooter("pages",` \u{1F4C4} Total pages: ${t}`),e.logInFooter("timing",r),e.logInFooter("validate-sep",""),e.isInteractive()&&(o.length?e.logInFooter("actions","Press (e) to print all errors, (q) to quit"):e.logInFooter("actions",p("Press (q) to quit"))),o}printErrors(r=[]){const t=this.#r.length,o=r.length?r:this.getProblems();let i=0;for(const l of o.slice(0,c))i>=t?e.contentError(a(`[${++i}] `)+m(l)):e.error(a(`[${++i}] `)+m(l));o.length>c&&e.error(`... and ${o.length-c} more errors`)}}const $=new b;function m(n){const r=n.sourceFileLocation,t=r?`:${r.line}:${r.character??1}`:"";return n.message+(n.codeframe?`
5
+ `+r.stack):o=new Error(r),e.contentError(r,...t),u.sendCliErrorCaughtMessage([{id:"cliId",object:"cli",uri:"urn:redocly:realm:api:cli:cliId",message:r,scope:"content"}]),await d.exitWithCode(1,o)}reportMarkdocProblem(r){this.#o.push(r)}clearErrors(){this.#r=[]}clearMarkdocProblems(){this.#o=[]}clearEsbuildProblems(){this.#e.clear()}clearPageRenderProblems(){this.#t=[]}getCompilationProblem(r){return this.#e.get(r)}getCompilationProblems(){return[...this.#e.values()]}getPageRenderProblems(){return this.#t}getPageRenderProblem(r){return this.#t.find(t=>t.sourceFileRelativePath===r)}getProblems(){return[...this.#r,...this.getCompilationProblems(),...this.#o,...this.#t]}summary(r,t=0){const o=this.getProblems(),i=this.#o.filter(s=>s.type==="BROKEN_LINK").length,l=this.#r.filter(s=>s.type==="BROKEN_LINK").length,m=this.#o.length-i,E=this.#r.length-l+this.getCompilationProblems().length+this.#t.length;return e.logInFooter("validate",o.length?a(" \u274C Status: %s markdoc errors, %s broken links, %s other errors"):" \u2705 Status: No errors found",m,i+l,E),t!==0&&e.logInFooter("pages",` \u{1F4C4} Total pages: ${t}`),e.isInteractive()?e.logInFooter("timing",r):e.info(r),e.logInFooter("validate-sep",""),e.isInteractive()&&(o.length?e.logInFooter("actions","Press (e) to print all errors, (q) to quit"):e.logInFooter("actions",p("Press (q) to quit"))),o}printErrors(r=[]){const t=this.#r.length,o=r.length?r:this.getProblems();let i=0;for(const l of o.slice(0,c))i>=t?e.contentError(a(`[${++i}] `)+f(l)):e.error(a(`[${++i}] `)+f(l));o.length>c&&e.error(`... and ${o.length-c} more errors`)}}const $=new b;function f(n){const r=n.sourceFileLocation,t=r?`:${r.line}:${r.character??1}`:"";return n.message+(n.codeframe?`
6
6
 
7
7
  `+n.codeframe+`
8
8
 
@@ -201,6 +201,7 @@ export type AfterRoutesCreatedActions = {
201
201
  getSearchFacets: () => Map<string, SearchFacet>;
202
202
  setSearchEngine: (engine: SearchEngine) => void;
203
203
  addRedirect: (from: string, to: RedirectConfig, options?: RedirectOptions) => void;
204
+ addRouteAlias: (from: string, to: string) => void;
204
205
  contentDir: string;
205
206
  outdir: string;
206
207
  serverOutDir: string;
@@ -7,5 +7,17 @@ export declare function compileGlobMatcher(patterns: string[]): (relativePath: s
7
7
  export declare function pathMatchesGlobPattern(relativePath: string, pattern: string): boolean;
8
8
  export declare function getMostSpecificMatchingGlobKey(relativePath: string, globMap?: Record<string, unknown>): string | undefined;
9
9
  export declare function resolveGlobMapValue<T>(relativePath: string, globMap?: Record<string, T>): T | undefined;
10
+ /**
11
+ * Converts a glob to a regular expression that is safe to inline in an HTML script: its source
12
+ * never contains `<`.
13
+ *
14
+ * @param glob - The glob, for example `/docs/**`
15
+ * @returns The regular expression, or undefined when the glob has none
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * convertGlobToRegex('/docs/**')?.test('/docs/a') // Returns true
20
+ * ```
21
+ */
10
22
  export declare function convertGlobToRegex(glob: string): RegExp | undefined;
11
23
  //# sourceMappingURL=globs.d.ts.map
@@ -1 +1 @@
1
- import s from"picomatch";import{minimatch as m,Minimatch as p}from"minimatch";import c from"is-glob";import l from"path";import{removeTrailingSlash as u}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as f}from"../../utils/url/remove-leading-slash.js";const h=(n,t)=>{const e=n.tokens??[],o=t.tokens??[];if(n.isGlob!==t.isGlob)return n.isGlob?t:n;if(e.length!==o.length)return e.length>o.length?n:t;for(let r=0;r<e.length;r++){if(e[r].isGlob!==o[r].isGlob)return e[r].isGlob?t:n;if(e[r].value!==o[r].value)return e[r].value.length>o[r].value.length?n:t}return n};function v(n){const t=n.map(e=>{if(c(e)){const r=new p(e);return i=>r.match(i)}const o=u(f(l.posix.normalize(e)));return r=>r===o||r.startsWith(o+"/")});return e=>t.some(o=>o(e))}function a(n,t){if(c(t)){if(m(n,t))return!0}else{const e=u(f(l.posix.normalize(t))),o=n.startsWith(e+"/");if(n===e||o)return!0}return!1}function d(n,t){if(!t)return;const e=[];for(const i of Object.keys(t))a(n,i)&&e.push(i);if(!e.length)return;const o=e.map(i=>s.scan(i,{tokens:!0,parts:!0}));let r=o[0];for(let i=1;i<o.length;i++)r=h(r,o[i]);return r.input}function P(n,t){const e=d(n,t);return e!=null&&t?t[e]:void 0}function T(n){const t=s.makeRe(n);return t||void 0}export{v as compileGlobMatcher,T as convertGlobToRegex,h as getDeeperGlobPattern,d as getMostSpecificMatchingGlobKey,a as pathMatchesGlobPattern,P as resolveGlobMapValue};
1
+ import s from"picomatch";import{minimatch as m,Minimatch as p}from"minimatch";import l from"is-glob";import c from"path";import{removeTrailingSlash as u}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as f}from"../../utils/url/remove-leading-slash.js";const a=(n,e)=>{const t=n.tokens??[],o=e.tokens??[];if(n.isGlob!==e.isGlob)return n.isGlob?e:n;if(t.length!==o.length)return t.length>o.length?n:e;for(let r=0;r<t.length;r++){if(t[r].isGlob!==o[r].isGlob)return t[r].isGlob?e:n;if(t[r].value!==o[r].value)return t[r].value.length>o[r].value.length?n:e}return n};function v(n){const e=n.map(t=>{if(l(t)){const r=new p(t);return i=>r.match(i)}const o=u(f(c.posix.normalize(t)));return r=>r===o||r.startsWith(o+"/")});return t=>e.some(o=>o(t))}function h(n,e){if(l(e)){if(m(n,e))return!0}else{const t=u(f(c.posix.normalize(e))),o=n.startsWith(t+"/");if(n===t||o)return!0}return!1}function d(n,e){if(!e)return;const t=[];for(const i of Object.keys(e))h(n,i)&&t.push(i);if(!t.length)return;const o=t.map(i=>s.scan(i,{tokens:!0,parts:!0}));let r=o[0];for(let i=1;i<o.length;i++)r=a(r,o[i]);return r.input}function P(n,e){const t=d(n,e);return t!=null&&e?e[t]:void 0}function T(n){const e=s.makeRe(n);return e?new RegExp(e.source.replaceAll("<","\\u003c"),e.flags):void 0}export{v as compileGlobMatcher,T as convertGlobToRegex,a as getDeeperGlobPattern,d as getMostSpecificMatchingGlobKey,h as pathMatchesGlobPattern,P as resolveGlobMapValue};