@redocly/realm 0.130.0-custom.21 → 0.130.0-custom.23

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{parseYaml as s}from"@redocly/openapi-core";import{logger as i}from"../../../tools/notifiers/logger.js";const l=async(t,n)=>{try{const r=await n.fs.read(t);if(!r)return null;const e=s(r),o=Array.isArray(e)?e:[e];return{path:t,entities:o}}catch(r){return i.error(`Error reading file ${t}:`,r),null}};export{l as extractFileContent};
1
+ import{parseYaml as i}from"@redocly/openapi-core";import{logger as a}from"../../../tools/notifiers/logger.js";import{validateNoDuplicateEntityKeys as s}from"../../openapi-docs/instances.js";const m=async(r,o)=>{let t;try{const e=await o.fs.read(r);if(!e)return null;t=i(e)}catch(e){return a.error(`Error reading file ${r}:`,e),null}const n=Array.isArray(t)?t:[t];return s(n,r),{path:r,entities:n}};export{m as extractFileContent};
@@ -1 +1 @@
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 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 w}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 ve,definitionsLoader as ke}from"./load-definition.js";import{getAiDocumentsStore as _e}from"./search/get-ai-search-documents.js";import{buildInstanceMetadata as be,fetchRegistryApiIdByPath as Ee,filterInstancesForApiVersion as Te,getResolvedApiVersion as Fe,hasTemplateVariables as xe,loadLinkedInstancesByApiId as Ce,patchOpenApiDefinitionWithVariables as Oe,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 a=[],r={},i={},f=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":ke,"load-oas":ve},processContent:async(e,c)=>{await Me("build.plugin.openapi_docs",async l=>{e.createRequestHandler(j,Be(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:Ie+"/*",requestHandlerId:j,httpMethod:"all",[O]:ee,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ge+"/*",requestHandlerId:j,httpMethod:"all",[O]:ee,getStaticData:async()=>({props:{}})});const u=e.createTemplate(Z,U("../../../client/templates/openapi-docs/template.js")),m=e.registerServerPropsGetter(Z,U("./get-server-props.js")),p=e.registerServerPropsGetter(Pe,U("./get-server-props-custom-fields.js")),n=await c.getConfig();l?.setAttribute("config",JSON.stringify(n.openapi||{}));const P=n.rules?.["custom-fields-schema"];r={},i={};const v=w.startTiming("Loading openapi definitions..."),h=await e.loadOpenApiDefinitions(c);w.infoTime(v,"Loading openapi definitions...");const B=await Ee(),E=await Ce(c);a=h.map(({markdocChunks:S,relativePath:y,customOutputRelativeFile:g,isVirtual:d,realRelativePath:M})=>({chunks:S,relativePath:y,realRelativePath:M,isVirtual:g!=null||d})),Re(h,e.outdir);const T={};for(const S of h||[]){const{definition:y,config:g,relativePath:d,customOutputRelativeFile:M,contentItems:oe,flatItems:L,parser:$,options:q,rawOptions:ne,hash:ae}=S,F=M||d,{definition:ie}=$||{},{info:A}=ie||{},I=we(S,B),se={...A?.["x-metadata"]||{}},N=!!g.openapi?.excludeFromSearch||!!g.theme?.openapi?.excludeFromSearch||!!n.openapi?.excludeFromSearch||!!n.theme?.openapi?.excludeFromSearch,z={title:A?.title,description:A?.description,summary:A?.summary,...g.metadata,...se},re=Fe(S),x=I?Te(E.get(I)||[],re):[],K=Le(y,x),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])),k={untagged:[],tagged:new Map};for(const t of L){const{operationDefinition:o}=t;if(o){const{tags:_}=o;if(_)for(const R of _)k.tagged.has(R)||k.tagged.set(R,[]),k.tagged.get(R)?.push(t);else k.untagged.push(t)}}for(const t of K){const o=[],_={},R=ce.get(t.key);if(!R)continue;const pe=t.routePrefix?`${F.replace(/\.[^.]+$/,"")}/${t.routePrefix}`:F;for(const s of L){const{id:b,href:D,operationDefinition:Q}=s;if(te.isDevelopMode){const C=Q?.pointer;C&&(_[`#${C}`]=Ne(s.href,t.routePrefix))}if(!Ae({item:s}))continue;const H=s,me=H.type==="section"&&!!H.infoDefinition,X=$e(D,"");R.routeSuffixesByItemId[b]=X;const he=Q?.[O];o.push({excludeFromSearch:N,slugSuffix:X,fsPath:pe,metadata:{subType:"openapi-operation"},httpVerb:s?.httpVerb||"",path:d,templateId:u,[O]:he||g.rbac,getAiDocumentsStore:_e({parser:$,options:q,info:A,tagOperations:k,openapiContentItem:H,metadata:z,relativePath:d,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:me,excludeFromSearch:N}),getStaticData:async C=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:C.baseSlug,seo:s["x-metadata"]?.seo||{title:s.name,description:s.description},itemId:b,disableAutoScroll:!0}})})}if(!o.length)continue;const J=t.key!==""&&!!t.sourceInstance,de=J&&I&&t.sourceInstance?be(t.sourceInstance,I):{},le=J?{}:{...x.length>0?{instanceCount:x.length}:{},...x.length===0&&xe(y)?{isTemplate:!0}:{}},V=t.definition?.info?.title;o[0]={...o[0],metadata:{type:"openapi",...z,...de,...le,...I?{apiId:I}:{}},hasClientRoutes:!0,getSidebar:(s,b)=>{const D=[];return ye({contentItems:oe,sidebarItems:D,routeSlug:s.slug,navItem:b}),V&&D.length>0&&D[0]&&!b?.label&&(D[0].label=V),D},getNavText:()=>V||A?.title,getSearchDocuments:De($,q,L,e.getSearchFacets,e.setSearchFacets,N)},I&&t.key===""&&(T[I]={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}${F}::${t.id}`;i[d]=[...i[d]||[],G],r[G]={fsPath:F,definition:t.definition,options:ne,instances:W,currentInstanceKey:t.key,sourcePath:ue,routesMapping:_,hash:ae};for(const s of o)e.addRoute({...s,sharedData:[{id:G,key:"openAPIDocsStore"}],serverPropsGetterIds:P?[m,p]:[m]})}}e.setGlobalData({apiProducts:T})})},afterRoutesCreated:async(e,c)=>{const l=w.startTiming("Parsing openapi markdoc chunks..."),u=new Set;for(const{chunks:p,relativePath:n,isVirtual:P,realRelativePath:v}of a){const h=(await c.cache.load(v,"load-oas")).compoundHash,B=i[n]||[];await c.cache.load(n,{loader:async function(){for(const{node:T,markdown:S,key:y,relativePath:g}of p){const{ast:d}=await e.parseMarkdoc({content:S,relativePath:g,isVirtual:P},c,{sharedDataIds:B});T[`x-parsed-md-${y}`]={result:d}}},name:"openapi-markdoc-inline-parser"},[h]);for(const{pointer:E}of p)u.add(E)}w.infoTime(l,"Parsing openapi markdoc chunks...");const m=f.difference(u);for(const p of m)c.cache.delete(p);f=u;for(const[p,n]of Object.entries(r)){for(const P of n.instances||[]){const v=P.routePrefix?`${n.fsPath.replace(/\.[^.]+$/,"")}/${P.routePrefix}`:n.fsPath,h=e.getRouteByFsPath(v);h&&(P.baseSlug=h.baseSlug)}await e.createSharedData(p,{...n,baseSlug:e.getRouteByFsPath(n.fsPath)?.baseSlug},n.hash)}}}}function Le(a,r){const i=[{id:"default",key:"",title:"Default",routePrefix:"",definition:a}],f=new Set;for(const e of r){const c=Ve(e.key)||"instance";let l=`instances/${c}`,u=2;for(;f.has(l);)l=`instances/${c}-${u}`,u++;f.add(l);const m=Oe(a,e.variables),p=e.title?{...m,info:{...m.info||{},title:e.title}}:m;i.push({id:`instance-${l.replace(/[\/:]/g,"-")}`,key:e.key,title:e.title,summary:e.summary,tags:e.tags,routePrefix:l,definition:p,sourceInstance:e})}return i}function $e(a,r){const i=a.split("#")[0]+"/";return r?Y("/",r,i):i}function Ne(a,r){if(!r)return a;const[i="",f]=a.split("#"),e=Y("/",r,i||"/");return f?`${e}#${f}`:e}function Ve(a){return a.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 Z}from"@redocly/theme/core/utils";import{OPENAPI_DOCS_TEMPLATE_ID as ee,PUBLIC_RBAC_SCOPE_ITEM as te}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 oe}from"../../config/env-config.js";import{logger as w}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,storeDefinitionBundle as ve}from"./store-definition-bundles.js";import{definitionLoader as ke,definitionsLoader as _e}from"./load-definition.js";import{getAiDocumentsStore as be}from"./search/get-ai-search-documents.js";import{buildInstanceMetadata as Ee,fetchRegistryApiIdByPath as Te,filterInstancesForApiVersion as xe,getResolvedApiVersion as Fe,hasTemplateVariables as Ce,loadLinkedInstancesByApiId as Oe,patchOpenApiDefinitionWithVariables as we,resolveApiIdForDefinition as Be}from"./instances.js";import{fromCurrentDir as Me}from"../../utils/paths.js";import{telemetryTraceStep as Le}from"../../../cli/telemetry/helpers/trace-step.js";const j="openapi-spec-download";async function it(){let a=[],r={},i={},f=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":_e,"load-oas":ke},processContent:async(e,c)=>{await Le("build.plugin.openapi_docs",async l=>{e.createRequestHandler(j,Me(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:Ie+"/*",requestHandlerId:j,httpMethod:"all",[O]:te,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ge+"/*",requestHandlerId:j,httpMethod:"all",[O]:te,getStaticData:async()=>({props:{}})});const u=e.createTemplate(ee,U("../../../client/templates/openapi-docs/template.js")),m=e.registerServerPropsGetter(ee,U("./get-server-props.js")),p=e.registerServerPropsGetter(Pe,U("./get-server-props-custom-fields.js")),n=await c.getConfig();l?.setAttribute("config",JSON.stringify(n.openapi||{}));const P=n.rules?.["custom-fields-schema"];r={},i={};const v=w.startTiming("Loading openapi definitions..."),h=await e.loadOpenApiDefinitions(c);w.infoTime(v,"Loading openapi definitions...");const B=await Te(),E=await Oe(c);a=h.map(({markdocChunks:S,relativePath:y,customOutputRelativeFile:g,isVirtual:d,realRelativePath:M})=>({chunks:S,relativePath:y,realRelativePath:M,isVirtual:g!=null||d})),Re(h,e.outdir);const T={};for(const S of h||[]){const{definition:y,config:g,relativePath:d,customOutputRelativeFile:M,contentItems:ne,flatItems:L,parser:$,options:q,rawOptions:ae,hash:ie}=S,x=M||d,{definition:se}=$||{},{info:A}=se||{},I=Be(S,B),re={...A?.["x-metadata"]||{}},N=!!g.openapi?.excludeFromSearch||!!g.theme?.openapi?.excludeFromSearch||!!n.openapi?.excludeFromSearch||!!n.theme?.openapi?.excludeFromSearch,z={title:A?.title,description:A?.description,summary:A?.summary,...g.metadata,...re},ce=Fe(S),F=I?xe(E.get(I)||[],ce):[],K=$e(y,F),W=K.map(t=>({key:t.key,title:t.title,summary:t.summary,tags:t.tags,routePrefix:t.routePrefix,routeSuffixesByItemId:{}})),pe=new Map(W.map(t=>[t.key,t])),k={untagged:[],tagged:new Map};for(const t of L){const{operationDefinition:o}=t;if(o){const{tags:_}=o;if(_)for(const R of _)k.tagged.has(R)||k.tagged.set(R,[]),k.tagged.get(R)?.push(t);else k.untagged.push(t)}}for(const t of K){const o=[],_={},R=pe.get(t.key);if(!R)continue;const J=t.routePrefix?`${x.replace(/\.[^.]+$/,"")}/${t.routePrefix}`:x;t.routePrefix&&ve(t.definition,J,e.outdir);for(const s of L){const{id:b,href:D,operationDefinition:X}=s;if(oe.isDevelopMode){const C=X?.pointer;C&&(_[`#${C}`]=Ve(s.href,t.routePrefix))}if(!Ae({item:s}))continue;const H=s,me=H.type==="section"&&!!H.infoDefinition,Y=Ne(D,"");R.routeSuffixesByItemId[b]=Y;const he=X?.[O];o.push({excludeFromSearch:N,slugSuffix:Y,fsPath:J,metadata:{subType:"openapi-operation"},httpVerb:s?.httpVerb||"",path:d,templateId:u,[O]:he||g.rbac,getAiDocumentsStore:be({parser:$,options:q,info:A,tagOperations:k,openapiContentItem:H,metadata:z,relativePath:d,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:me,excludeFromSearch:N}),getStaticData:async C=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:C.baseSlug,seo:s["x-metadata"]?.seo||{title:s.name,description:s.description},itemId:b,disableAutoScroll:!0}})})}if(!o.length)continue;const Q=t.key!==""&&!!t.sourceInstance,de=Q&&I&&t.sourceInstance?Ee(t.sourceInstance,I):{},le=Q?{}:{...F.length>0?{instanceCount:F.length}:{},...F.length===0&&Ce(y)?{isTemplate:!0}:{}},V=t.definition?.info?.title;o[0]={...o[0],metadata:{type:"openapi",...z,...de,...le,...I?{apiId:I}:{}},hasClientRoutes:!0,getSidebar:(s,b)=>{const D=[];return ye({contentItems:ne,sidebarItems:D,routeSlug:s.slug,navItem:b}),V&&D.length>0&&D[0]&&!b?.label&&(D[0].label=V),D},getNavText:()=>V||A?.title,getSearchDocuments:De($,q,L,e.getSearchFacets,e.setSearchFacets,N)},I&&t.key===""&&(T[I]={slug:o[0]?.slug||""});const fe=o[0];o[0]=o[o.length-1],o[o.length-1]=fe;const ue=oe.isDevelopMode?d:void 0,G=`${Se}${x}::${t.id}`;i[d]=[...i[d]||[],G],r[G]={fsPath:x,definition:t.definition,options:ae,instances:W,currentInstanceKey:t.key,sourcePath:ue,routesMapping:_,hash:ie};for(const s of o)e.addRoute({...s,sharedData:[{id:G,key:"openAPIDocsStore"}],serverPropsGetterIds:P?[m,p]:[m]})}}e.setGlobalData({apiProducts:T})})},afterRoutesCreated:async(e,c)=>{const l=w.startTiming("Parsing openapi markdoc chunks..."),u=new Set;for(const{chunks:p,relativePath:n,isVirtual:P,realRelativePath:v}of a){const h=(await c.cache.load(v,"load-oas")).compoundHash,B=i[n]||[];await c.cache.load(n,{loader:async function(){for(const{node:T,markdown:S,key:y,relativePath:g}of p){const{ast:d}=await e.parseMarkdoc({content:S,relativePath:g,isVirtual:P},c,{sharedDataIds:B});T[`x-parsed-md-${y}`]={result:d}}},name:"openapi-markdoc-inline-parser"},[h]);for(const{pointer:E}of p)u.add(E)}w.infoTime(l,"Parsing openapi markdoc chunks...");const m=f.difference(u);for(const p of m)c.cache.delete(p);f=u;for(const[p,n]of Object.entries(r)){for(const P of n.instances||[]){const v=P.routePrefix?`${n.fsPath.replace(/\.[^.]+$/,"")}/${P.routePrefix}`:n.fsPath,h=e.getRouteByFsPath(v);h&&(P.baseSlug=h.baseSlug)}await e.createSharedData(p,{...n,baseSlug:e.getRouteByFsPath(n.fsPath)?.baseSlug},n.hash)}}}}function $e(a,r){const i=[{id:"default",key:"",title:"Default",routePrefix:"",definition:a}],f=new Set;for(const e of r){const c=Ge(e.key)||"instance";let l=`instances/${c}`,u=2;for(;f.has(l);)l=`instances/${c}-${u}`,u++;f.add(l);const m=we(a,e.variables),p=e.title?{...m,info:{...m.info||{},title:e.title}}:m;i.push({id:`instance-${l.replace(/[\/:]/g,"-")}`,key:e.key,title:e.title,summary:e.summary,tags:e.tags,routePrefix:l,definition:p,sourceInstance:e})}return i}function Ne(a,r){const i=a.split("#")[0]+"/";return r?Z("/",r,i):i}function Ve(a,r){if(!r)return a;const[i="",f]=a.split("#"),e=Z("/",r,i||"/");return f?`${e}#${f}`:e}function Ge(a){return a.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+/,"").replace(/-+$/,"")}export{it as openAPIDocsPlugin};
@@ -28,6 +28,7 @@ export declare function patchOpenApiDefinitionWithVariables<T = unknown>(definit
28
28
  * Checks both string values and object keys (template vars can appear in keys).
29
29
  */
30
30
  export declare function hasTemplateVariables(value: unknown): boolean;
31
+ export declare function validateNoDuplicateEntityKeys(entities: unknown[], filePath: string): void;
31
32
  export declare function buildInstanceMetadata(instance: OpenApiLinkedInstance, parentApiId: string): OpenApiInstanceMetadata;
32
33
  export declare function applyInstanceToDefinition<T = unknown>(definition: T, instance: OpenApiLinkedInstance): T;
33
34
  //# sourceMappingURL=instances.d.ts.map
@@ -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=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};
1
+ import A from"path";import{VERSION_NOT_SPECIFIED as u}from"@redocly/theme/core/constants";import{CATALOG_ENTITIES_FILES_REGEX as L,ENTITY_SCHEMA_EXCLUDED_FOLDERS as C}from"../../constants/plugins/catalog-entities.js";import{REGISTRY_APIS_API_URL as h}from"../../constants/common.js";import{logger as l}from"../../tools/notifiers/logger.js";import{readEnvVariable as I}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 W(){const e=new Map;if(!h)return e;const t=I("REGISTRY_API_KEY")||"",n=I("REDOCLY_LOCAL_DEV_TOKEN")||"";if(!t&&!n)return l.warnProd("Cannot fetch API registry entries for OpenAPI instances: authentication token is missing"),e;try{const r=`${h}?limit=6000&fields=id,contentPath`,i=t?{Authorization:`Bearer ${t}`}:{Cookie:`accessToken=${n}`},o=await fetch(r,{headers:i});if(o.status!==200)return l.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=d(c);f&&e.set(f,a.id)}}catch(r){const i=r instanceof Error?r.message:String(r);l.warnProd(`Failed to fetch API registry entries for OpenAPI instances: ${i}`)}return e}function Q(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 M(i))r.add(o);for(const i of r){const o=t.get(i);if(o)return o}}async function ee(e){const t=new Map,n=e.fs.scan(L).filter(({relativePath:r})=>v(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];B(o,r);for(const s of o){const a=s;if(!a||typeof a!="object")continue;const c=F(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 k=p.version??u,g=K(a.relations);if(!g.length)continue;const R={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(y=>typeof y=="string"):void 0,version:k,variables:c};for(const y of g){const T=t.get(y)||[],w=N([...T,R]);t.set(y,w)}}}return t}function te(e){const t=e.definition.info?.version,n=E(t,e.realRelativePath);return n.success?n.version??u:u}function ne(e,t){return e.filter(n=>z(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 b(e){if(typeof e=="string")return e.includes(P);if(Array.isArray(e))return e.some(t=>b(t));if(e&&typeof e=="object"){for(const t of Object.keys(e))if(t.includes(P)||b(e[t]))return!0}return!1}function m(e,t){return typeof e=="string"?V(e,t):Array.isArray(e)?e.map(n=>m(n,t)):e&&typeof e=="object"?Object.entries(e).reduce((n,[r,i])=>{const o=V(r,t),s=typeof o=="string"?o:$(o);return n[s]=m(i,t),n},{}):e}function V(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?$(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 $(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 M(e){const t=d(e),n=new Set;if(t){n.add(t);const i=d(A.posix.dirname(t));i&&n.add(i)}const r=S(e);if(r?.filePathInVersion){const i=d(r.filePathInVersion);if(i){n.add(i);const o=d(A.posix.dirname(i));o&&n.add(o)}}return Array.from(n)}function d(e){return e?e.replace(/^\/+/,"").replace(/\/+$/,"").trim():""}function F(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 K(e){return Array.isArray(e)?e.map(t=>t).filter(t=>t?.type==="implements"&&typeof t.key=="string").map(t=>t.key):[]}function z(e,t){return e===u||t===u?!0:e===t}function N(e){const t=new Map;for(const n of e)t.set(`${n.key}:${n.version}`,n);return Array.from(t.values())}function v(e){return!C.some(t=>e.includes(t))}function B(e,t){const n=new Map;for(const i of e){if(!i||typeof i!="object")continue;const o=i.key;if(typeof o!="string"||!o.trim())continue;const s=o.trim();n.set(s,(n.get(s)||0)+1)}const r=Array.from(n.entries()).filter(([,i])=>i>1).map(([i,o])=>`"${i}" (${o} times)`);if(r.length>0)throw new Error(`Duplicate entity keys in ${t}: ${r.join(", ")}. Each entity must have a unique key within a file.`)}function re(e,t){return{isInstance:!0,parentApiId:t,entityKey:e.key,entityTitle:e.title,entitySummary:e.summary,entityTags:e.tags,instanceVariables:e.variables}}function ie(e,t){const n=j(e,t.variables);return t.title&&n&&typeof n=="object"?{...n,info:{...n.info,title:t.title}}:n}export{ie as applyInstanceToDefinition,re as buildInstanceMetadata,W as fetchRegistryApiIdByPath,ne as filterInstancesForApiVersion,te as getResolvedApiVersion,b as hasTemplateVariables,ee as loadLinkedInstancesByApiId,j as patchOpenApiDefinitionWithVariables,Q as resolveApiIdForDefinition,B as validateNoDuplicateEntityKeys};
@@ -1,4 +1,5 @@
1
1
  import type { BundledDefinition } from './load-definition';
2
2
  export declare function storeDefinitionBundles(definitions: BundledDefinition[], outDir: string): void;
3
+ export declare function storeDefinitionBundle(definition: unknown, relativePath: string, outDir: string): void;
3
4
  export declare function replaceFileExtension(filePath: string, fileExt: string): string;
4
5
  //# sourceMappingURL=store-definition-bundles.d.ts.map
@@ -1 +1 @@
1
- import{writeFileSync as u}from"fs";import o from"path";import{dump as x}from"js-yaml";import{PUBLIC_API_DEFINITIONS_FOLDER as g,PUBLIC_STATIC_FOLDER as c}from"../../constants/common.js";import{logger as h}from"../../tools/notifiers/logger.js";import{ensureDir as D}from"../../utils/fs.js";const a=new Map;function j(i,t){const r=g.slice(1);try{for(const n of i){const{definition:m,originalDefinition:p,relativePath:e,hash:s}=n,f=p||m;if(a.get(e)!==s){if(e.startsWith(c+"/")){const d=o.posix.extname(e);l({outDir:t,definitionFolder:".",relativePath:e.replace(c+"/",""),definitionString:d===".json"?JSON.stringify(f,null,2):x(f)}),a.set(e,s);continue}l({outDir:t,definitionFolder:r,relativePath:F(e,".json"),definitionString:JSON.stringify(f,null,2)}),a.set(e,s)}}}catch(n){h.error("failed to store definition bundles",n)}}function F(i,t){const r=o.posix.dirname(i),n=o.posix.basename(i,o.posix.extname(i))+t;return o.posix.join(r,n)}function l({outDir:i,definitionString:t,relativePath:r,definitionFolder:n}){u(D(o.resolve(i,`${n}/${r}`)),t,"utf8")}export{F as replaceFileExtension,j as storeDefinitionBundles};
1
+ import{writeFileSync as S}from"fs";import r from"path";import{dump as h}from"js-yaml";import{PUBLIC_API_DEFINITIONS_FOLDER as d,PUBLIC_STATIC_FOLDER as p}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{ensureDir as D}from"../../utils/fs.js";const l=new Map;function v(i,n){const t=d.slice(1);try{for(const e of i){const{definition:s,originalDefinition:x,relativePath:o,hash:f}=e,c=x||s;if(l.get(o)!==f){if(o.startsWith(p+"/")){const g=r.posix.extname(o);a({outDir:n,definitionFolder:".",relativePath:o.replace(p+"/",""),definitionString:g===".json"?JSON.stringify(c,null,2):h(c)}),l.set(o,f);continue}a({outDir:n,definitionFolder:t,relativePath:u(o,".json"),definitionString:JSON.stringify(c,null,2)}),l.set(o,f)}}}catch(e){m.error("failed to store definition bundles",e)}}function _(i,n,t){const e=d.slice(1);try{a({outDir:t,definitionFolder:e,relativePath:u(n,".json"),definitionString:JSON.stringify(i,null,2)})}catch(s){m.error(`failed to store definition bundle for ${n}`,s)}}function u(i,n){const t=r.posix.dirname(i),e=r.posix.basename(i,r.posix.extname(i))+n;return r.posix.join(t,e)}function a({outDir:i,definitionString:n,relativePath:t,definitionFolder:e}){S(D(r.resolve(i,`${e}/${t}`)),n,"utf8")}export{u as replaceFileExtension,_ as storeDefinitionBundle,v as storeDefinitionBundles};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/realm",
3
- "version": "0.130.0-custom.21",
3
+ "version": "0.130.0-custom.23",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -91,14 +91,14 @@
91
91
  "xpath": "0.0.34",
92
92
  "yaml-ast-parser": "0.0.43",
93
93
  "zod": "^3.25.76",
94
- "@redocly/asyncapi-docs": "1.7.0-custom.2",
95
- "@redocly/openapi-docs": "3.18.0-custom.1",
96
- "@redocly/graphql-docs": "1.7.0-custom.2",
97
94
  "@redocly/config": "0.43.0-custom.1",
95
+ "@redocly/graphql-docs": "1.7.0-custom.2",
96
+ "@redocly/asyncapi-docs": "1.7.0-custom.2",
98
97
  "@redocly/portal-plugin-mock-server": "0.16.0-next.4",
99
- "@redocly/portal-legacy-ui": "0.14.0-next.0",
100
98
  "@redocly/realm-asyncapi-sdk": "0.9.0-next.1",
101
- "@redocly/theme": "0.62.0-custom.2"
99
+ "@redocly/portal-legacy-ui": "0.14.0-next.0",
100
+ "@redocly/theme": "0.62.0-custom.2",
101
+ "@redocly/openapi-docs": "3.18.0-custom.1"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "react": "^19.2.4",