@redocly/realm 0.130.0-custom.17 → 0.130.0-custom.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{REDOCLY_TEAMS_RBAC as C}from"@redocly/config";import{combineUrls as Y}from"@redocly/theme/core/utils";import{OPENAPI_DOCS_TEMPLATE_ID as Z,PUBLIC_RBAC_SCOPE_ITEM as ee}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ge,PUBLIC_API_DEFINITIONS_FOLDER as Ie}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as Pe,OPENAPI_SHARED_DATA_PREFIX as Se}from"../../constants/plugins/openapi-docs.js";import{envConfig as te}from"../../config/env-config.js";import{logger as O}from"../../tools/notifiers/logger.js";import{searchResolver as De}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as ye,shouldAddRoute as Ae}from"./utils.js";import{getTemplatePath as U}from"./get-template-path.js";import{storeDefinitionBundles as Re}from"./store-definition-bundles.js";import{definitionLoader as ke,definitionsLoader as ve}from"./load-definition.js";import{getAiDocumentsStore as _e}from"./search/get-ai-search-documents.js";import{buildInstanceMetadata as Ee,fetchRegistryApiIdByPath as Te,filterInstancesForApiVersion as be,getResolvedApiVersion as xe,hasTemplateVariables as Ce,loadLinkedInstancesByApiId as Oe,patchOpenApiDefinitionWithVariables as Fe,resolveApiIdForDefinition as we}from"./instances.js";import{fromCurrentDir as Be}from"../../utils/paths.js";import{telemetryTraceStep as Me}from"../../../cli/telemetry/helpers/trace-step.js";const j="openapi-spec-download";async function at(){let n=[],s={},a={},m=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":ve,"load-oas":ke},processContent:async(e,r)=>{await Me("build.plugin.openapi_docs",async f=>{e.createRequestHandler(j,Be(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:Ie+"/*",requestHandlerId:j,httpMethod:"all",[C]:ee,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ge+"/*",requestHandlerId:j,httpMethod:"all",[C]:ee,getStaticData:async()=>({props:{}})});const h=e.createTemplate(Z,U("../../../client/templates/openapi-docs/template.js")),g=e.registerServerPropsGetter(Z,U("./get-server-props.js")),p=e.registerServerPropsGetter(Pe,U("./get-server-props-custom-fields.js")),c=await r.getConfig();f?.setAttribute("config",JSON.stringify(c.openapi||{}));const F=c.rules?.["custom-fields-schema"];s={},a={};const w=O.startTiming("Loading openapi definitions..."),A=await e.loadOpenApiDefinitions(r);O.infoTime(w,"Loading openapi definitions...");const B=await Te(),_=await Oe(r);n=A.map(({markdocChunks:P,relativePath:u,customOutputRelativeFile:I,isVirtual:d,realRelativePath:M})=>({chunks:P,relativePath:u,realRelativePath:M,isVirtual:I!=null||d})),Re(A,e.outdir);const E={};for(const P of A||[]){const{definition:u,config:I,relativePath:d,customOutputRelativeFile:M,contentItems:oe,flatItems:L,parser:$,options:q,rawOptions:ne,hash:ae}=P,T=M||d,{definition:ie}=$||{},{info:D}=ie||{},l=we(P,B),se={...D?.["x-metadata"]||{},...l?{apiId:l}:{}};l&&(u.info={...u.info,"x-metadata":{...u.info?.["x-metadata"]||{},apiId:l}});const N=!!I.openapi?.excludeFromSearch||!!I.theme?.openapi?.excludeFromSearch||!!c.openapi?.excludeFromSearch||!!c.theme?.openapi?.excludeFromSearch,z={title:D?.title,description:D?.description,summary:D?.summary,...I.metadata,...se},re=xe(P),b=l?be(_.get(l)||[],re):[],K=Le(u,b),W=K.map(t=>({key:t.key,title:t.title,summary:t.summary,tags:t.tags,routePrefix:t.routePrefix,routeSuffixesByItemId:{}})),ce=new Map(W.map(t=>[t.key,t])),R={untagged:[],tagged:new Map};for(const t of L){const{operationDefinition:o}=t;if(o){const{tags:k}=o;if(k)for(const y of k)R.tagged.has(y)||R.tagged.set(y,[]),R.tagged.get(y)?.push(t);else R.untagged.push(t)}}for(const t of K){const o=[],k={},y=ce.get(t.key);if(!y)continue;const pe=t.routePrefix?`${T.replace(/\.[^.]+$/,"")}/${t.routePrefix}`:T;for(const i of L){const{id:v,href:S,operationDefinition:Q}=i;if(te.isDevelopMode){const x=Q?.pointer;x&&(k[`#${x}`]=Ne(i.href,t.routePrefix))}if(!Ae({item:i}))continue;const H=i,me=H.type==="section"&&!!H.infoDefinition,X=$e(S,"");y.routeSuffixesByItemId[v]=X;const he=Q?.[C];o.push({excludeFromSearch:N,slugSuffix:X,fsPath:pe,metadata:{subType:"openapi-operation"},httpVerb:i?.httpVerb||"",path:d,templateId:h,[C]:he||I.rbac,getAiDocumentsStore:_e({parser:$,options:q,info:D,tagOperations:R,openapiContentItem:H,metadata:z,relativePath:d,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:me,excludeFromSearch:N}),getStaticData:async x=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:x.baseSlug,seo:i["x-metadata"]?.seo||{title:i.name,description:i.description},itemId:v,disableAutoScroll:!0}})})}if(!o.length)continue;const J=t.key!==""&&!!t.sourceInstance,de=J&&l&&t.sourceInstance?Ee(t.sourceInstance,l):{},le=J?{}:{...b.length>0?{instanceCount:b.length}:{},...b.length===0&&Ce(u)?{isTemplate:!0}:{}},V=t.definition?.info?.title;o[0]={...o[0],metadata:{type:"openapi",...z,...de,...le},hasClientRoutes:!0,getSidebar:(i,v)=>{const S=[];return ye({contentItems:oe,sidebarItems:S,routeSlug:i.slug,navItem:v}),V&&S.length>0&&S[0]&&!v?.label&&(S[0].label=V),S},getNavText:()=>V||D?.title,getSearchDocuments:De($,q,L,e.getSearchFacets,e.setSearchFacets,N)},l&&t.key===""&&(E[l]={slug:o[0]?.slug||""});const fe=o[0];o[0]=o[o.length-1],o[o.length-1]=fe;const ue=te.isDevelopMode?d:void 0,G=`${Se}${T}::${t.id}`;a[d]=[...a[d]||[],G],s[G]={fsPath:T,definition:t.definition,options:ne,instances:W,currentInstanceKey:t.key,sourcePath:ue,routesMapping:k,hash:ae};for(const i of o)e.addRoute({...i,sharedData:[{id:G,key:"openAPIDocsStore"}],serverPropsGetterIds:F?[g,p]:[g]})}}e.setGlobalData({apiProducts:E})})},afterRoutesCreated:async(e,r)=>{const f=O.startTiming("Parsing openapi markdoc chunks..."),h=new Set;for(const{chunks:p,relativePath:c,isVirtual:F,realRelativePath:w}of n){const A=(await r.cache.load(w,"load-oas")).compoundHash,B=a[c]||[];await r.cache.load(c,{loader:async function(){for(const{node:E,markdown:P,key:u,relativePath:I}of p){const{ast:d}=await e.parseMarkdoc({content:P,relativePath:I,isVirtual:F},r,{sharedDataIds:B});E[`x-parsed-md-${u}`]={result:d}}},name:"openapi-markdoc-inline-parser"},[A]);for(const{pointer:_}of p)h.add(_)}O.infoTime(f,"Parsing openapi markdoc chunks...");const g=m.difference(h);for(const p of g)r.cache.delete(p);m=h;for(const[p,c]of Object.entries(s))await e.createSharedData(p,{...c,baseSlug:e.getRouteByFsPath(c.fsPath)?.baseSlug},c.hash)}}}function Le(n,s){const a=[{id:"default",key:"",title:"Default",routePrefix:"",definition:n}],m=new Set;for(const e of s){const r=Ve(e.key)||"instance";let f=`instances/${r}`,h=2;for(;m.has(f);)f=`instances/${r}-${h}`,h++;m.add(f);const g=Fe(n,e.variables),p=e.title?{...g,info:{...g.info||{},title:e.title}}:g;a.push({id:`instance-${f.replace(/[\/:]/g,"-")}`,key:e.key,title:e.title,summary:e.summary,tags:e.tags,routePrefix:f,definition:p,sourceInstance:e})}return a}function $e(n,s){const a=n.split("#")[0]+"/";return s?Y("/",s,a):a}function Ne(n,s){if(!s)return n;const[a="",m]=n.split("#"),e=Y("/",s,a||"/");return m?`${e}#${m}`:e}function Ve(n){return n.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}export{at as openAPIDocsPlugin};
1
+ import{REDOCLY_TEAMS_RBAC as O}from"@redocly/config";import{combineUrls as Y}from"@redocly/theme/core/utils";import{OPENAPI_DOCS_TEMPLATE_ID as Z,PUBLIC_RBAC_SCOPE_ITEM as ee}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as Ie,PUBLIC_API_DEFINITIONS_FOLDER as Pe}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as Se,OPENAPI_SHARED_DATA_PREFIX as ye}from"../../constants/plugins/openapi-docs.js";import{envConfig as te}from"../../config/env-config.js";import{logger as x}from"../../tools/notifiers/logger.js";import{searchResolver as De}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as Ae,shouldAddRoute as Re}from"./utils.js";import{getTemplatePath as U}from"./get-template-path.js";import{storeDefinitionBundles as ke}from"./store-definition-bundles.js";import{definitionLoader as ve,definitionsLoader as Ee}from"./load-definition.js";import{getAiDocumentsStore as _e}from"./search/get-ai-search-documents.js";import{buildInstanceMetadata as xe,fetchRegistryApiIdByPath as Te,filterInstancesForApiVersion as be,getResolvedApiVersion as Ce,hasTemplateVariables as oe,loadLinkedInstancesByApiId as Oe,patchOpenApiDefinitionWithVariables as Fe,resolveApiIdForDefinition as we}from"./instances.js";import{fromCurrentDir as Be}from"../../utils/paths.js";import{telemetryTraceStep as Me}from"../../../cli/telemetry/helpers/trace-step.js";const j="openapi-spec-download";async function at(){let n=[],r={},a={},m=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":Ee,"load-oas":ve},processContent:async(e,c)=>{await Me("build.plugin.openapi_docs",async u=>{e.createRequestHandler(j,Be(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:Pe+"/*",requestHandlerId:j,httpMethod:"all",[O]:ee,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:Ie+"/*",requestHandlerId:j,httpMethod:"all",[O]:ee,getStaticData:async()=>({props:{}})});const h=e.createTemplate(Z,U("../../../client/templates/openapi-docs/template.js")),g=e.registerServerPropsGetter(Z,U("./get-server-props.js")),p=e.registerServerPropsGetter(Se,U("./get-server-props-custom-fields.js")),d=await c.getConfig();u?.setAttribute("config",JSON.stringify(d.openapi||{}));const F=d.rules?.["custom-fields-schema"];r={},a={};const w=x.startTiming("Loading openapi definitions..."),A=await e.loadOpenApiDefinitions(c);x.infoTime(w,"Loading openapi definitions...");const B=await Te(),T=await Oe(c);n=A.map(({markdocChunks:P,relativePath:l,customOutputRelativeFile:I,isVirtual:f,realRelativePath:M})=>({chunks:P,relativePath:l,realRelativePath:M,isVirtual:I!=null||f})),ke(A,e.outdir);const b={};for(const P of A||[]){const{definition:l,config:I,relativePath:f,customOutputRelativeFile:M,contentItems:ne,flatItems:L,parser:$,options:q,rawOptions:ae,hash:ie}=P,R=M||f,{definition:se}=$||{},{info:S}=se||{},i=we(P,B),re={...S?.["x-metadata"]||{},...i?{apiId:i}:{}};i&&(l.info={...l.info,"x-metadata":{...l.info?.["x-metadata"]||{},apiId:i}});const N=!!I.openapi?.excludeFromSearch||!!I.theme?.openapi?.excludeFromSearch||!!d.openapi?.excludeFromSearch||!!d.theme?.openapi?.excludeFromSearch,z={title:S?.title,description:S?.description,summary:S?.summary,...I.metadata,...re},ce=Ce(P),k=i?be(T.get(i)||[],ce):[];if(oe(l)&&k.length===0){const t=S?.["x-metadata"]?.apiId?"x-metadata":"registry";x.warn(`Template detected for "${R}" but no linked instances found.`+(i?` Resolved apiId="${i}" (source: ${t}). Ensure entity relations reference this exact key.`:" No apiId resolved. Add info.x-metadata.apiId to your API definition."))}const K=Le(l,k),W=K.map(t=>({key:t.key,title:t.title,summary:t.summary,tags:t.tags,routePrefix:t.routePrefix,routeSuffixesByItemId:{}})),de=new Map(W.map(t=>[t.key,t])),v={untagged:[],tagged:new Map};for(const t of L){const{operationDefinition:o}=t;if(o){const{tags:E}=o;if(E)for(const D of E)v.tagged.has(D)||v.tagged.set(D,[]),v.tagged.get(D)?.push(t);else v.untagged.push(t)}}for(const t of K){const o=[],E={},D=de.get(t.key);if(!D)continue;const pe=t.routePrefix?`${R.replace(/\.[^.]+$/,"")}/${t.routePrefix}`:R;for(const s of L){const{id:_,href:y,operationDefinition:Q}=s;if(te.isDevelopMode){const C=Q?.pointer;C&&(E[`#${C}`]=Ne(s.href,t.routePrefix))}if(!Re({item:s}))continue;const H=s,he=H.type==="section"&&!!H.infoDefinition,X=$e(y,"");D.routeSuffixesByItemId[_]=X;const ge=Q?.[O];o.push({excludeFromSearch:N,slugSuffix:X,fsPath:pe,metadata:{subType:"openapi-operation"},httpVerb:s?.httpVerb||"",path:f,templateId:h,[O]:ge||I.rbac,getAiDocumentsStore:_e({parser:$,options:q,info:S,tagOperations:v,openapiContentItem:H,metadata:z,relativePath:f,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:he,excludeFromSearch:N}),getStaticData:async C=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:C.baseSlug,seo:s["x-metadata"]?.seo||{title:s.name,description:s.description},itemId:_,disableAutoScroll:!0}})})}if(!o.length)continue;const J=t.key!==""&&!!t.sourceInstance,le=J&&i&&t.sourceInstance?xe(t.sourceInstance,i):{},fe=J?{}:{...k.length>0?{instanceCount:k.length}:{},...k.length===0&&oe(l)?{isTemplate:!0}:{}},V=t.definition?.info?.title;o[0]={...o[0],metadata:{type:"openapi",...z,...le,...fe},hasClientRoutes:!0,getSidebar:(s,_)=>{const y=[];return Ae({contentItems:ne,sidebarItems:y,routeSlug:s.slug,navItem:_}),V&&y.length>0&&y[0]&&!_?.label&&(y[0].label=V),y},getNavText:()=>V||S?.title,getSearchDocuments:De($,q,L,e.getSearchFacets,e.setSearchFacets,N)},i&&t.key===""&&(b[i]={slug:o[0]?.slug||""});const ue=o[0];o[0]=o[o.length-1],o[o.length-1]=ue;const me=te.isDevelopMode?f:void 0,G=`${ye}${R}::${t.id}`;a[f]=[...a[f]||[],G],r[G]={fsPath:R,definition:t.definition,options:ae,instances:W,currentInstanceKey:t.key,sourcePath:me,routesMapping:E,hash:ie};for(const s of o)e.addRoute({...s,sharedData:[{id:G,key:"openAPIDocsStore"}],serverPropsGetterIds:F?[g,p]:[g]})}}e.setGlobalData({apiProducts:b})})},afterRoutesCreated:async(e,c)=>{const u=x.startTiming("Parsing openapi markdoc chunks..."),h=new Set;for(const{chunks:p,relativePath:d,isVirtual:F,realRelativePath:w}of n){const A=(await c.cache.load(w,"load-oas")).compoundHash,B=a[d]||[];await c.cache.load(d,{loader:async function(){for(const{node:b,markdown:P,key:l,relativePath:I}of p){const{ast:f}=await e.parseMarkdoc({content:P,relativePath:I,isVirtual:F},c,{sharedDataIds:B});b[`x-parsed-md-${l}`]={result:f}}},name:"openapi-markdoc-inline-parser"},[A]);for(const{pointer:T}of p)h.add(T)}x.infoTime(u,"Parsing openapi markdoc chunks...");const g=m.difference(h);for(const p of g)c.cache.delete(p);m=h;for(const[p,d]of Object.entries(r))await e.createSharedData(p,{...d,baseSlug:e.getRouteByFsPath(d.fsPath)?.baseSlug},d.hash)}}}function Le(n,r){const a=[{id:"default",key:"",title:"Default",routePrefix:"",definition:n}],m=new Set;for(const e of r){const c=Ve(e.key)||"instance";let u=`instances/${c}`,h=2;for(;m.has(u);)u=`instances/${c}-${h}`,h++;m.add(u);const g=Fe(n,e.variables),p=e.title?{...g,info:{...g.info||{},title:e.title}}:g;a.push({id:`instance-${u.replace(/[\/:]/g,"-")}`,key:e.key,title:e.title,summary:e.summary,tags:e.tags,routePrefix:u,definition:p,sourceInstance:e})}return a}function $e(n,r){const a=n.split("#")[0]+"/";return r?Y("/",r,a):a}function Ne(n,r){if(!r)return n;const[a="",m]=n.split("#"),e=Y("/",r,a||"/");return m?`${e}#${m}`:e}function Ve(n){return n.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}export{at as openAPIDocsPlugin};
@@ -1 +1 @@
1
- import A from"path";import{VERSION_NOT_SPECIFIED as d}from"@redocly/theme/core/constants";import{CATALOG_ENTITIES_FILES_REGEX as w,ENTITY_SCHEMA_EXCLUDED_FOLDERS as C}from"../../constants/plugins/catalog-entities.js";import{REGISTRY_APIS_API_URL as I}from"../../constants/common.js";import{logger as y}from"../../tools/notifiers/logger.js";import{readEnvVariable as h}from"../../utils/envs/read-env-variable.js";import{resolveEntityVersion as E}from"../catalog-entities/utils/resolve-entity-version.js";import{parsePathVersions as S}from"../../../utils/path/parse-path-versions.js";const O=/\$\{([^}|]+)(?:\|([^}]*))?\}/g,D=/^\$\{([^}|]+)(?:\|([^}]*))?\}$/,P="${";async function H(){const e=new Map;if(!I)return e;const t=h("REGISTRY_API_KEY")||"",n=h("REDOCLY_LOCAL_DEV_TOKEN")||"";if(!t&&!n)return y.warnProd("Cannot fetch API registry entries for OpenAPI instances: authentication token is missing"),e;try{const r=`${I}?limit=5000&fields=id,contentPath,fsPath`,i=t?{Authorization:`Bearer ${t}`}:{Cookie:`accessToken=${n}`},o=await fetch(r,{headers:i});if(o.status!==200)return y.warnProd(`Failed to fetch API registry entries for OpenAPI instances. API response status: ${o.status}. Request URL: ${r}`),e;const a=await o.json();for(const s of a.items||[]){if(!s?.id)continue;const f=s.contentPath||s.fsPath;if(!f||typeof f!="string")continue;const c=u(f);c&&e.set(c,s.id)}}catch(r){const i=r instanceof Error?r.message:String(r);y.warnProd(`Failed to fetch API registry entries for OpenAPI instances: ${i}`)}return e}function W(e,t){const n=e.definition.info?.["x-metadata"]?.apiId;if(typeof n=="string"&&n.trim())return n.trim();const r=new Set;for(const i of[e.relativePath,e.realRelativePath])for(const o of F(i))r.add(o);for(const i of r){const o=t.get(i);if(o)return o}}async function Q(e){const t=new Map,n=e.fs.scan(w).filter(({relativePath:r})=>N(r));for(const{relativePath:r}of n){let i;try{i=(await e.cache.load(r,"yaml")).data}catch(a){const s=a instanceof Error?a.message:String(a);e.logger.warn(`Failed to parse entity file ${r}: ${s}`);continue}const o=Array.isArray(i)?i:[i];for(const a of o){const s=a;if(!s||typeof s!="object")continue;const f=M(s);if(!f)continue;const c=typeof s.key=="string"?s.key.trim():"";if(!c)continue;const p=E(s.version,r);if(!p.success){e.logger.warn(`Skipping entity ${c} in ${r}: version "${p.fileVersion}" conflicts with folder version "${p.folderVersion}"`);continue}const T=p.version??d,g=z(s.relations);if(!g.length)continue;const $={key:c,title:typeof s.title=="string"?s.title:void 0,summary:typeof s.summary=="string"?s.summary:void 0,tags:Array.isArray(s.tags)?s.tags.filter(l=>typeof l=="string"):void 0,version:T,variables:f};for(const l of g){const k=t.get(l)||[],L=K([...k,$]);t.set(l,L)}}}return t}function ee(e){const t=e.definition.info?.version,n=E(t,e.realRelativePath);return n.success?n.version??d:d}function te(e,t){return e.filter(n=>B(n.version,t)).sort((n,r)=>{const i=n.title||n.key,o=r.title||r.key;return i.localeCompare(o)})}function j(e,t){return m(e,t)}function V(e){if(typeof e=="string")return e.includes(P);if(Array.isArray(e))return e.some(t=>V(t));if(e&&typeof e=="object"){for(const t of Object.keys(e))if(t.includes(P)||V(e[t]))return!0}return!1}function m(e,t){return typeof e=="string"?b(e,t):Array.isArray(e)?e.map(n=>m(n,t)):e&&typeof e=="object"?Object.entries(e).reduce((n,[r,i])=>{const o=b(r,t),a=typeof o=="string"?o:R(o);return n[a]=m(i,t),n},{}):e}function b(e,t){const n=e.match(D);if(n){const r=_(n[1]||"",t,n[2]);return r.found?r.value:e}return e.replace(O,(r,i,o)=>{const a=_(i,t,o);return a.found?R(a.value):r})}function _(e,t,n){const r=x(e);for(const a of r)if(Object.prototype.hasOwnProperty.call(t,a))return{found:!0,value:t[a]};const i=e.trim().toLowerCase(),o=Object.keys(t).find(a=>a.trim().toLowerCase()===i);return o?{found:!0,value:t[o]}:n!==void 0?{found:!0,value:n}:{found:!1,value:void 0}}function x(e){const t=e.trim(),n=t.replace(/_/g,"-").replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),r=t.replace(/-/g,"_").replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase(),i=t.replace(/[-_]+([a-zA-Z0-9])/g,(o,a)=>a.toUpperCase());return Array.from(new Set([t,n,r,i]))}function R(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean"||typeof e=="bigint")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function F(e){const t=u(e),n=new Set;if(t){n.add(t);const i=u(A.posix.dirname(t));i&&n.add(i)}const r=S(e);if(r?.filePathInVersion){const i=u(r.filePathInVersion);if(i){n.add(i);const o=u(A.posix.dirname(i));o&&n.add(o)}}return Array.from(n)}function u(e){return e?e.replace(/^\/+/,"").replace(/\/+$/,"").trim():""}function M(e){if(!e.metadata||typeof e.metadata!="object")return;const t=e.metadata;if(!(!t.variables||typeof t.variables!="object"||Array.isArray(t.variables)))return t.variables}function z(e){return Array.isArray(e)?e.map(t=>t).filter(t=>t?.type==="implements"&&typeof t.key=="string").map(t=>t.key):[]}function B(e,t){return e===d||t===d?!0:e===t}function K(e){const t=new Map;for(const n of e)t.set(`${n.key}:${n.version}`,n);return Array.from(t.values())}function N(e){return!C.some(t=>e.includes(t))}function ne(e,t){return{isInstance:!0,parentApiId:t,entityKey:e.key,entityTitle:e.title,entitySummary:e.summary,entityTags:e.tags,instanceVariables:e.variables}}function re(e,t){const n=j(e,t.variables);return t.title&&n&&typeof n=="object"?{...n,info:{...n.info,title:t.title}}:n}export{re as applyInstanceToDefinition,ne as buildInstanceMetadata,H as fetchRegistryApiIdByPath,te as filterInstancesForApiVersion,ee as getResolvedApiVersion,V as hasTemplateVariables,Q as loadLinkedInstancesByApiId,j as patchOpenApiDefinitionWithVariables,W as resolveApiIdForDefinition};
1
+ import A from"path";import{VERSION_NOT_SPECIFIED as d}from"@redocly/theme/core/constants";import{CATALOG_ENTITIES_FILES_REGEX as w,ENTITY_SCHEMA_EXCLUDED_FOLDERS as C}from"../../constants/plugins/catalog-entities.js";import{REGISTRY_APIS_API_URL as I}from"../../constants/common.js";import{logger as y}from"../../tools/notifiers/logger.js";import{readEnvVariable as h}from"../../utils/envs/read-env-variable.js";import{resolveEntityVersion as E}from"../catalog-entities/utils/resolve-entity-version.js";import{parsePathVersions as S}from"../../../utils/path/parse-path-versions.js";const O=/\$\{([^}|]+)(?:\|([^}]*))?\}/g,D=/^\$\{([^}|]+)(?:\|([^}]*))?\}$/,P="${";async function H(){const e=new Map;if(!I)return e;const t=h("REGISTRY_API_KEY")||"",n=h("REDOCLY_LOCAL_DEV_TOKEN")||"";if(!t&&!n)return y.warnProd("Cannot fetch API registry entries for OpenAPI instances: authentication token is missing"),e;try{const r=`${I}?limit=6000&fields=id,contentPath`,i=t?{Authorization:`Bearer ${t}`}:{Cookie:`accessToken=${n}`},o=await fetch(r,{headers:i});if(o.status!==200)return y.warnProd(`Failed to fetch API registry entries for OpenAPI instances. API response status: ${o.status}. Request URL: ${r}`),e;const s=await o.json();for(const a of s.items||[]){if(!a?.id)continue;const c=a.contentPath;if(!c||typeof c!="string")continue;const f=u(c);f&&e.set(f,a.id)}}catch(r){const i=r instanceof Error?r.message:String(r);y.warnProd(`Failed to fetch API registry entries for OpenAPI instances: ${i}`)}return e}function W(e,t){const n=e.definition.info?.["x-metadata"]?.apiId;if(typeof n=="string"&&n.trim())return n.trim();const r=new Set;for(const i of[e.relativePath,e.realRelativePath])for(const o of F(i))r.add(o);for(const i of r){const o=t.get(i);if(o)return o}}async function Q(e){const t=new Map,n=e.fs.scan(w).filter(({relativePath:r})=>N(r));for(const{relativePath:r}of n){let i;try{i=(await e.cache.load(r,"yaml")).data}catch(s){const a=s instanceof Error?s.message:String(s);e.logger.warn(`Failed to parse entity file ${r}: ${a}`);continue}const o=Array.isArray(i)?i:[i];for(const s of o){const a=s;if(!a||typeof a!="object")continue;const c=M(a);if(!c)continue;const f=typeof a.key=="string"?a.key.trim():"";if(!f)continue;const p=E(a.version,r);if(!p.success){e.logger.warn(`Skipping entity ${f} in ${r}: version "${p.fileVersion}" conflicts with folder version "${p.folderVersion}"`);continue}const T=p.version??d,g=z(a.relations);if(!g.length)continue;const $={key:f,title:typeof a.title=="string"?a.title:void 0,summary:typeof a.summary=="string"?a.summary:void 0,tags:Array.isArray(a.tags)?a.tags.filter(l=>typeof l=="string"):void 0,version:T,variables:c};for(const l of g){const k=t.get(l)||[],L=K([...k,$]);t.set(l,L)}}}return t}function ee(e){const t=e.definition.info?.version,n=E(t,e.realRelativePath);return n.success?n.version??d:d}function te(e,t){return e.filter(n=>B(n.version,t)).sort((n,r)=>{const i=n.title||n.key,o=r.title||r.key;return i.localeCompare(o)})}function j(e,t){return m(e,t)}function V(e){if(typeof e=="string")return e.includes(P);if(Array.isArray(e))return e.some(t=>V(t));if(e&&typeof e=="object"){for(const t of Object.keys(e))if(t.includes(P)||V(e[t]))return!0}return!1}function m(e,t){return typeof e=="string"?b(e,t):Array.isArray(e)?e.map(n=>m(n,t)):e&&typeof e=="object"?Object.entries(e).reduce((n,[r,i])=>{const o=b(r,t),s=typeof o=="string"?o:R(o);return n[s]=m(i,t),n},{}):e}function b(e,t){const n=e.match(D);if(n){const r=_(n[1]||"",t,n[2]);return r.found?r.value:e}return e.replace(O,(r,i,o)=>{const s=_(i,t,o);return s.found?R(s.value):r})}function _(e,t,n){const r=x(e);for(const s of r)if(Object.prototype.hasOwnProperty.call(t,s))return{found:!0,value:t[s]};const i=e.trim().toLowerCase(),o=Object.keys(t).find(s=>s.trim().toLowerCase()===i);return o?{found:!0,value:t[o]}:n!==void 0?{found:!0,value:n}:{found:!1,value:void 0}}function x(e){const t=e.trim(),n=t.replace(/_/g,"-").replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase(),r=t.replace(/-/g,"_").replace(/([a-z0-9])([A-Z])/g,"$1_$2").toLowerCase(),i=t.replace(/[-_]+([a-zA-Z0-9])/g,(o,s)=>s.toUpperCase());return Array.from(new Set([t,n,r,i]))}function R(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean"||typeof e=="bigint")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function F(e){const t=u(e),n=new Set;if(t){n.add(t);const i=u(A.posix.dirname(t));i&&n.add(i)}const r=S(e);if(r?.filePathInVersion){const i=u(r.filePathInVersion);if(i){n.add(i);const o=u(A.posix.dirname(i));o&&n.add(o)}}return Array.from(n)}function u(e){return e?e.replace(/^\/+/,"").replace(/\/+$/,"").trim():""}function M(e){if(!e.metadata||typeof e.metadata!="object")return;const t=e.metadata;if(!(!t.variables||typeof t.variables!="object"||Array.isArray(t.variables)))return t.variables}function z(e){return Array.isArray(e)?e.map(t=>t).filter(t=>t?.type==="implements"&&typeof t.key=="string").map(t=>t.key):[]}function B(e,t){return e===d||t===d?!0:e===t}function K(e){const t=new Map;for(const n of e)t.set(`${n.key}:${n.version}`,n);return Array.from(t.values())}function N(e){return!C.some(t=>e.includes(t))}function ne(e,t){return{isInstance:!0,parentApiId:t,entityKey:e.key,entityTitle:e.title,entitySummary:e.summary,entityTags:e.tags,instanceVariables:e.variables}}function re(e,t){const n=j(e,t.variables);return t.title&&n&&typeof n=="object"?{...n,info:{...n.info,title:t.title}}:n}export{re as applyInstanceToDefinition,ne as buildInstanceMetadata,H as fetchRegistryApiIdByPath,te as filterInstancesForApiVersion,ee as getResolvedApiVersion,V as hasTemplateVariables,Q as loadLinkedInstancesByApiId,j as patchOpenApiDefinitionWithVariables,W as resolveApiIdForDefinition};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/realm",
3
- "version": "0.130.0-custom.17",
3
+ "version": "0.130.0-custom.18",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -92,13 +92,13 @@
92
92
  "yaml-ast-parser": "0.0.43",
93
93
  "zod": "^3.25.76",
94
94
  "@redocly/asyncapi-docs": "1.7.0-custom.2",
95
- "@redocly/graphql-docs": "1.7.0-custom.2",
96
- "@redocly/portal-plugin-mock-server": "0.16.0-next.4",
95
+ "@redocly/config": "0.43.0-custom.1",
97
96
  "@redocly/portal-legacy-ui": "0.14.0-next.0",
98
- "@redocly/realm-asyncapi-sdk": "0.9.0-next.1",
99
97
  "@redocly/openapi-docs": "3.18.0-custom.1",
100
98
  "@redocly/theme": "0.62.0-custom.2",
101
- "@redocly/config": "0.43.0-custom.1"
99
+ "@redocly/realm-asyncapi-sdk": "0.9.0-next.1",
100
+ "@redocly/graphql-docs": "1.7.0-custom.2",
101
+ "@redocly/portal-plugin-mock-server": "0.16.0-next.4"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "react": "^19.2.4",