@redocly/revel 0.130.0-next.2 → 0.130.0-next.3

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/cli/eject/resolveEjectParams.js +1 -1
  3. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +2 -2
  4. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  5. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +8 -0
  6. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.js +1 -0
  7. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-read-model.js +1 -1
  8. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.d.ts +2 -2
  9. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.js +14 -14
  10. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +2 -2
  11. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +1 -1
  12. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +2 -2
  13. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  14. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.d.ts +2 -1
  15. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  16. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -1
  17. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  18. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  19. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +4 -3
  20. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  21. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  22. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +1 -1
  23. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  24. package/dist/server/plugins/catalog-entities/get-server-props.js +1 -1
  25. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  26. package/dist/server/plugins/catalog-entities/schemas/database-schemas.d.ts +3 -0
  27. package/dist/server/plugins/catalog-entities/schemas/database-schemas.js +1 -1
  28. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.d.ts +12 -0
  29. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.js +1 -1
  30. package/dist/server/plugins/catalog-entities/schemas/read-model-schemas.d.ts +1 -0
  31. package/dist/server/plugins/catalog-entities/types/extractors.d.ts +4 -4
  32. package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
  33. package/dist/server/plugins/default-theme/index.js +1 -1
  34. package/dist/server/plugins/search/ai-indexer/prepare-ai-search-documents.js +1 -1
  35. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  36. package/dist/server/plugins/sso/index.js +1 -1
  37. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.d.ts +143 -0
  38. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js +1 -0
  39. package/dist/server/utils/rbac.d.ts +11 -7
  40. package/dist/server/utils/rbac.js +1 -1
  41. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  42. package/package.json +5 -5
@@ -1 +1 @@
1
- import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as u}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as f}from"@redocly/theme/core/constants";import{resolveEntityVersion as v}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as h}from"../../../utils/catalog-data-collector.js";const g=3;class w{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&h.addExtractor(this.specType),await E(t,g,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){h.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE);return}const a=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(e.realRelativePath);process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true"&&(await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:Array.from(a).map(s=>s.split(":")[0])}),a.clear());const o=new Date().toISOString(),l=this.#a(e);await this.processApiDescription(e,o,l,a),await this.#i(a,e.realRelativePath,o,e.hash),h.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#i=async(t,e,i,r)=>{if(t.size===0||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")return;const a=Array.from(t).map(s=>{const[n,p]=s.split(":");return{key:n,version:p}}),o=Array.from(new Set(a.map(({key:s})=>s))),l=a.map(({key:s,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:s},{field:"version",operator:"equal",value:n}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:i,fileHash:r,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#a(t){const e=t.document?.info?.version??t.definition?.info?.version??null,i=v(e,t.realRelativePath);return i.success?i.version??f:f}}export{w as BaseApiEntitiesExtractor};
1
+ import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as u}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as f}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as g}from"../../../../../utils/rbac.js";import{resolveEntityVersion as v}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as h}from"../../../utils/catalog-data-collector.js";const y=3;class _{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&h.addExtractor(this.specType),await E(t,y,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){h.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE);return}const a=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(e.realRelativePath);process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true"&&(await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:Array.from(a).map(s=>s.split(":")[0])}),a.clear());const o=new Date().toISOString(),n=this.#a(e);await this.processApiDescription(e,o,n,a),await this.#i(a,e.realRelativePath,o,e.hash),h.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#i=async(t,e,i,r)=>{if(t.size===0||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")return;const a=Array.from(t).map(s=>{const[l,p]=s.split(":");return{key:l,version:p}}),o=Array.from(new Set(a.map(({key:s})=>s))),n=a.map(({key:s,version:l})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:s},{field:"version",operator:"equal",value:l}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:i,fileHash:r,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:n},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#a(t){const e=t.document?.info?.version??t.definition?.info?.version??null,i=v(e,t.realRelativePath);return i.success?i.version??f:f}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().rbac,i=this.actions.getRouteByFsPath(t);return g(i||{fsPath:t},e||{})}}export{_ as BaseApiEntitiesExtractor};
@@ -1,3 +1,3 @@
1
- import{buildSchema as R,isObjectType as g,isScalarType as O,isEnumType as D,isInterfaceType as S,isUnionType as w,isInputObjectType as E,getNamedType as u,printType as L}from"graphql";import{removeLeadingSlash as v}from"@redocly/theme/core/utils";import{toKebabCase as m}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as A}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as T}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as b}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as j}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as K}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as N}from"./base.js";const $=15,I=15,F=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class Q extends N{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:n,metadata:r}=a.data,s=R(n),o=j(n);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:o,schema:s,content:n,metadata:r})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t,e){const a=v(t.realRelativePath),n=t.relativePath.replace(/\.(gql|graphql)$/,""),r=this.#s(n.split("/").pop()||"GraphQL Schema"),s=a.replace(/\.(gql|graphql)$/,""),o=m(s.replace(/[\\/]/g,"-")),p=this.#c(t.metadata?.tags),c=t.metadata?.["x-redocly-catalog-key"],i=typeof c=="string"&&c.trim()?m(c.trim()):o;return{type:this.type,key:i,title:r,summary:t.metadata?.description||null,tags:p.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,n){const{schema:r}=t;if(!r)return;const s=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:s,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,revision:e}),n.delete(`${s.key}:${a}`),await Promise.all([this.#a(t,s.key,s.version,a,e,n),this.#y(t,s.key,s.version,a,e,n)])}#a=async(t,e,a,n,r,s)=>{const{schema:o}=t,p=o.getTypeMap(),c=this.#r(o),i=Object.entries(p).filter(([h])=>!h.startsWith("__")&&!F.has(h)&&!c.has(h));if(i.length===0)return;const l=await b(i,I,async([h,y])=>{const f=await this.#l({typeName:h,type:y,description:t,parentKey:e,parentVersion:a,parentRevision:r});s.delete(`${f.entityKey}:${n}`),f.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:f.entityKey,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:r,targetRevision:r})},this.#t);l.count.failed>0&&this.#t.warn(`Schema processing completed with ${l.count.failed} failures out of ${i.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:i,parentRevision:r})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&A(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${m(t)}`;#n=t=>g(t)?"object":S(t)?"interface":w(t)?"union":D(t)?"enum":E(t)?"input":O(t)?"scalar":"unknown";#r=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const n=t.getMutationType();n&&e.add(n.name);const r=t.getSubscriptionType();return r&&e.add(r.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"QUERY",rootTypeName:a.name})}const n=t.getMutationType();if(n){const s=n.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"MUTATION",rootTypeName:n.name})}const r=t.getSubscriptionType();if(r){const s=r.getFields();for(const[o,p]of Object.entries(s))e.push({fieldName:o,field:p,operationType:"SUBSCRIBE",rootTypeName:r.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const o=u(s.type);o&&!o.name.startsWith("__")&&a.push(this.#e(o.name,e))}const n=[],r=u(t.type);return r&&!r.name.startsWith("__")&&n.push(this.#e(r.name,e)),{inputTypes:a,returnTypes:n}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:n,parentVersion:r,parentRevision:s})=>{const o=this.#e(t,n),p=e.description??null,c=this.#n(e),i={type:"data-schema",key:o,title:t,summary:p,tags:["graphql"],metadata:{specType:this.specType,typeKind:c,sdl:this.#p(e,a.schema)},version:r};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:a.realRelativePath,fileHash:a.hash,revision:s})};#p=(t,e)=>{const a=new Set,n=[],r=new Set(["String","ID","Int","Float","Boolean"]),s=c=>{if(!c)return;const i=c.name;if(i.startsWith("__")||r.has(i)||a.has(i))return;const l=e.getType(i);l&&(a.add(i),n.push(l))};for(s(t);n.length>0;){const c=n.pop();if(g(c)){for(const l of c.getInterfaces?.()??[])s(l);const i=c.getFields();for(const l of Object.values(i)){s(u(l.type));for(const h of l.args??[])s(u(h.type))}}else if(S(c)){const i=c.getFields();for(const l of Object.values(i))s(u(l.type))}else if(w(c))for(const i of c.getTypes())s(i);else if(E(c)){const i=c.getFields();for(const l of Object.values(i))s(u(l.type))}}const o=[t.name,...[...a].filter(c=>c!==t.name)],p=[];for(const c of o){const i=e.getType(c);i&&p.push(L(i))}return p.join(`
1
+ import{buildSchema as O,isObjectType as T,isScalarType as D,isEnumType as v,isInterfaceType as w,isUnionType as E,isInputObjectType as b,getNamedType as u,printType as L}from"graphql";import{removeLeadingSlash as A}from"@redocly/theme/core/utils";import{toKebabCase as g}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as j}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as d}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as $}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as K}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as F}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as N}from"./base.js";const R=15,I=15,P=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class U extends N{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:i,metadata:r}=a.data,s=O(i),n=K(i);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:n,schema:s,content:i,metadata:r})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t,e){const a=A(t.realRelativePath),i=t.relativePath.replace(/\.(gql|graphql)$/,""),r=this.#s(i.split("/").pop()||"GraphQL Schema"),s=a.replace(/\.(gql|graphql)$/,""),n=g(s.replace(/[\\/]/g,"-")),p=this.#c(t.metadata?.tags),o=t.metadata?.["x-redocly-catalog-key"],l=typeof o=="string"&&o.trim()?g(o.trim()):n;return{type:this.type,key:l,title:r,summary:t.metadata?.description||null,tags:p.concat("graphql"),metadata:{specType:this.specType,descriptionFile:a},version:e}}async processApiDescription(t,e,a,i){const{schema:r}=t;if(!r)return;const s=this.getRbacTeamsForDefinition(t.relativePath),n=this.mapApiDescriptionToEntity(t,a);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:n,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0,revision:e,rbacTeams:s}),i.delete(`${n.key}:${a}`),await Promise.all([this.#a(t,n.key,n.version,a,e,i,s),this.#y(t,n.key,n.version,a,e,i,s)])}#a=async(t,e,a,i,r,s,n)=>{const{schema:p}=t,o=p.getTypeMap(),l=this.#i(p),c=Object.entries(o).filter(([y])=>!y.startsWith("__")&&!P.has(y)&&!l.has(y));if(c.length===0)return;const h=await $(c,I,async([y,m])=>{const f=await this.#l({typeName:y,type:m,description:t,parentKey:e,parentVersion:a,parentRevision:r,rbacTeams:n});s.delete(`${f.entityKey}:${i}`),f.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:f.entityKey,fileHash:t.hash,sourceVersion:a,targetVersion:a,sourceRevision:r,targetRevision:r})},this.#t);h.count.failed>0&&this.#t.warn(`Schema processing completed with ${h.count.failed} failures out of ${c.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:c,parentRevision:r})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&j(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${g(t)}`;#n=t=>T(t)?"object":w(t)?"interface":E(t)?"union":v(t)?"enum":b(t)?"input":D(t)?"scalar":"unknown";#i=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const i=t.getMutationType();i&&e.add(i.name);const r=t.getSubscriptionType();return r&&e.add(r.name),e};#r(t){const e=[],a=t.getQueryType();if(a){const s=a.getFields();for(const[n,p]of Object.entries(s))e.push({fieldName:n,field:p,operationType:"QUERY",rootTypeName:a.name})}const i=t.getMutationType();if(i){const s=i.getFields();for(const[n,p]of Object.entries(s))e.push({fieldName:n,field:p,operationType:"MUTATION",rootTypeName:i.name})}const r=t.getSubscriptionType();if(r){const s=r.getFields();for(const[n,p]of Object.entries(s))e.push({fieldName:n,field:p,operationType:"SUBSCRIBE",rootTypeName:r.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const s of t.args){const n=u(s.type);n&&!n.name.startsWith("__")&&a.push(this.#e(n.name,e))}const i=[],r=u(t.type);return r&&!r.name.startsWith("__")&&i.push(this.#e(r.name,e)),{inputTypes:a,returnTypes:i}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:i,parentVersion:r,parentRevision:s,rbacTeams:n})=>{const p=this.#e(t,i),o=e.description??null,l=this.#n(e),c={type:"data-schema",key:p,title:t,summary:o,tags:["graphql"],metadata:{specType:this.specType,typeKind:l,sdl:this.#p(e,a.schema)},version:r};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:a.realRelativePath,fileHash:a.hash,revision:s,rbacTeams:n})};#p=(t,e)=>{const a=new Set,i=[],r=new Set(["String","ID","Int","Float","Boolean"]),s=o=>{if(!o)return;const l=o.name;if(l.startsWith("__")||r.has(l)||a.has(l))return;const c=e.getType(l);c&&(a.add(l),i.push(c))};for(s(t);i.length>0;){const o=i.pop();if(T(o)){for(const c of o.getInterfaces?.()??[])s(c);const l=o.getFields();for(const c of Object.values(l)){s(u(c.type));for(const h of c.args??[])s(u(h.type))}}else if(w(o)){const l=o.getFields();for(const c of Object.values(l))s(u(c.type))}else if(E(o))for(const l of o.getTypes())s(l);else if(b(o)){const l=o.getFields();for(const c of Object.values(l))s(u(c.type))}}const n=[t.name,...[...a].filter(o=>o!==t.name)],p=[];for(const o of n){const l=e.getType(o);l&&p.push(L(l))}return p.join(`
2
2
 
3
- `)};#h=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:n})=>{const r=a.filter(([,s])=>g(s));r.length!==0&&await T(r,I,async([s,o])=>{const c=o.getInterfaces?.()??[];if(!c.length)return;const i=this.#e(s,e);await T([...c],5,async l=>{const h=this.#e(l.name,e);try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:i,type:"implements",targetKey:h,fileHash:t.hash,sourceRevision:n,targetRevision:n})}catch(y){this.#t.warn(`Failed to create 'implements' relation ${i} -> ${h}: ${y instanceof Error?y.message:"Unknown error"}`)}})})};#y=async(t,e,a,n,r,s)=>{const{schema:o}=t,p=this.#i(o);if(p.length===0)return;const i=(await b(p,$,async({fieldName:l,field:h,operationType:y,rootTypeName:f})=>{const d=await this.#f(l,h,y,f,t,e,a,r);d&&s.delete(`${d}:${n}`)},this.#t)).count.failed;i>0&&this.#t.warn(`Operation extraction completed with ${i} failures out of ${p.length} operations for ${e}`)};#f=async(t,e,a,n,r,s,o,p)=>{const{inputTypes:c,returnTypes:i}=this.#o(e,s),l=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:c,returnTypes:i,description:r,descriptionUniqueKey:s,descriptionVersion:o,parentRevision:p});return l.result==="created"&&await this.#m({apiOperationKey:l.entityKey,inputTypes:c,returnTypes:i,descriptionUniqueKey:s,description:r,descriptionVersion:o,parentRevision:p}),l.entityKey??null};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:n,inputTypes:r,returnTypes:s,description:o,descriptionUniqueKey:p,descriptionVersion:c,parentRevision:i})=>{const l=t,y={type:"api-operation",key:`${p}-${m(`${a.toLowerCase()}-${t}`)}`,title:l,summary:e.description?K(e.description):null,tags:["graphql"],metadata:{method:a,path:`${n}.${t}`,payload:r,responses:s},version:c};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:y,sourceFile:o.realRelativePath,fileHash:o.hash,revision:i})};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:n,description:r,descriptionVersion:s,parentRevision:o})=>{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"partOf",targetKey:n,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:o,targetRevision:o});const p=[...new Set(e)],c=[...new Set(a)],i=[...p.map(l=>({key:l,relationType:"uses"})),...c.map(l=>({key:l,relationType:"returns"}))];await T(i,$,async({key:l,relationType:h})=>{try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:h,targetKey:l,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:o,targetRevision:o})}catch(y){this.#t.warn(`Failed to create relation between operation ${t} and type ${l} (${h}): ${y instanceof Error?y.message:"Unknown error"}`)}})}}export{Q as GraphqlEntitiesExtractor};
3
+ `)};#h=async({description:t,descriptionUniqueKey:e,userTypes:a,parentRevision:i})=>{const r=a.filter(([,s])=>T(s));r.length!==0&&await d(r,I,async([s,n])=>{const o=n.getInterfaces?.()??[];if(!o.length)return;const l=this.#e(s,e);await d([...o],5,async c=>{const h=this.#e(c.name,e);try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:l,type:"implements",targetKey:h,fileHash:t.hash,sourceRevision:i,targetRevision:i})}catch(y){this.#t.warn(`Failed to create 'implements' relation ${l} -> ${h}: ${y instanceof Error?y.message:"Unknown error"}`)}})})};#y=async(t,e,a,i,r,s,n)=>{const{schema:p}=t,o=this.#r(p);if(o.length===0)return;const c=(await $(o,R,async({fieldName:h,field:y,operationType:m,rootTypeName:f})=>{const S=await this.#f(h,y,m,f,t,e,a,r,n);S&&s.delete(`${S}:${i}`)},this.#t)).count.failed;c>0&&this.#t.warn(`Operation extraction completed with ${c} failures out of ${o.length} operations for ${e}`)};#f=async(t,e,a,i,r,s,n,p,o)=>{const{inputTypes:l,returnTypes:c}=this.#o(e,s),h=await this.#u({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:l,returnTypes:c,description:r,descriptionUniqueKey:s,descriptionVersion:n,parentRevision:p,rbacTeams:o});return h.result==="created"&&await this.#m({apiOperationKey:h.entityKey,inputTypes:l,returnTypes:c,descriptionUniqueKey:s,description:r,descriptionVersion:n,parentRevision:p}),h.entityKey??null};#u=async({fieldName:t,field:e,operationType:a,rootTypeName:i,inputTypes:r,returnTypes:s,description:n,descriptionUniqueKey:p,descriptionVersion:o,parentRevision:l,rbacTeams:c})=>{const h=t,m={type:"api-operation",key:`${p}-${g(`${a.toLowerCase()}-${t}`)}`,title:h,summary:e.description?F(e.description):null,tags:["graphql"],metadata:{method:a,path:`${i}.${t}`,payload:r,responses:s},version:o};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:m,sourceFile:n.realRelativePath,fileHash:n.hash,revision:l,rbacTeams:c})};#m=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:i,description:r,descriptionVersion:s,parentRevision:n})=>{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"partOf",targetKey:i,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n});const p=[...new Set(e)],o=[...new Set(a)],l=[...p.map(c=>({key:c,relationType:"uses"})),...o.map(c=>({key:c,relationType:"returns"}))];await d(l,R,async({key:c,relationType:h})=>{try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:h,targetKey:c,fileHash:r.hash,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n})}catch(y){this.#t.warn(`Failed to create relation between operation ${t} and type ${c} (${h}): ${y instanceof Error?y.message:"Unknown error"}`)}})}}export{U as GraphqlEntitiesExtractor};
@@ -1,5 +1,5 @@
1
+ import { type EntityFileSchema } from '@redocly/config';
1
2
  import type { BundledDefinition } from '../../../../openapi-docs/load-definition';
2
- import type { EntityFileSchema } from '@redocly/config';
3
3
  import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
4
4
  import { BaseApiEntitiesExtractor } from './base.js';
5
5
  export declare class OpenApiEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
@@ -1 +1 @@
1
- import{removeLeadingSlash as S}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as u}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as O}from"../../../../../utils/async/promise-map-limit-with-status.js";import{removeMarkdocTags as g}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as d}from"./base.js";import{OpenapiSchemaResolver as $}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as N}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as x}from"../../../entities/validate-entity.js";import{isValidTagName as E}from"../../../utils/is-valid-tag-name.js";const v=["get","post","put","delete","patch"],w=15,R=15;class F extends d{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return await this.actions.loadOpenApiDefinitions(this.context)}mapApiDescriptionToEntity(e,o){const s=S(e.realRelativePath),n=e.definition.info.title,t=s.replace(/\.[^.]+$/,""),a=p(t.replace(/[\\/]/g,"-")),r=e.definition["x-redocly-catalog-key"],i=typeof r=="string"&&r.trim()?p(r.trim()):a;return{type:this.type,key:i,title:n,summary:g(e.definition.info.description),tags:e.definition.tags?.filter(c=>c.name&&E(c.name)).map(c=>c.name),metadata:{specType:this.specType,descriptionFile:s},version:o}}async processApiDescription(e,o,s,n){if($.clearSchemaCache(),!e?.definition?.paths)return;const t=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:t,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,revision:o}),n.delete(`${t.key}:${s}`),await this.#n(e,t.key,t.version,s,o,n);const a=this.#s(e.definition.paths);if(a.length!==0){const i=(await O(a,w,async({operation:c,path:h,method:l})=>{if(!c.operationId)return;const f=await this.#r(c,h,l,e,t.key,t.version,o);f&&n.delete(`${f}:${s}`)},this.#e)).count.failed;i>0&&this.#e.warn(`Extraction completed with ${i} failures out of ${a.length} operations for ${t.key}`)}}#s(e){return Object.entries(e).flatMap(([o,s])=>v.filter(n=>s[n]).map(n=>{const t=s[n];if(!t)throw new Error(`Operation not found for method ${n} on path ${o}`);return{operation:t,path:o,method:n.toUpperCase()}}))}async#n(e,o,s,n,t,a){const r=e.definition.components?.schemas;if(!r)return;const i=Object.entries(r);i.length!==0&&await u(i,R,async([c,h])=>{const l=await this.#o({schemaName:c,schema:h,description:e,parentKey:o,parentVersion:s,parentRevision:t});a.delete(`${l.entityKey}:${n}`),l.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,sourceVersion:s,sourceRevision:t,type:"uses",targetKey:l.entityKey,targetVersion:s,targetRevision:t,fileHash:e.hash})})}async#o({schemaName:e,schema:o,description:s,parentKey:n,parentVersion:t,parentRevision:a}){const r=$.resolveSchemaRefs(o,s),i=JSON.stringify(r),c={type:"data-schema",key:`${n}-${p(e)}`,title:e,summary:r.description??r.title??null,tags:[],metadata:{specType:this.specType,schema:i},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:c,sourceFile:s.realRelativePath,fileHash:s.hash,revision:a})}async#r(e,o,s,n,t,a,r){const i=await Promise.all([this.#h(e.requestBody??null,n),this.#m(e.responses??{},n)]),c=i[0].schemaNames,h=i[1].schemaNames;i[0].errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${i[0].errors.join(", ")}`),i[1].errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${i[1].errors.join(", ")}`);const l=c.map(y=>`${t}-${p(y)}`),f=h.map(y=>`${t}-${p(y)}`),m=await this.#p({path:o,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:f,description:n,parentKey:t,parentVersion:a,parentRevision:r});return m.result==="created"&&await Promise.all([this.#i(c,e.operationId??"",n.hash,t,a,r),this.#c(h,e.operationId??"",n.hash,t,a,r),this.#f({apiOperationKey:m.entityKey,operationRelations:e["x-catalog-relations"],descriptionUniqueKey:t,description:n,parentVersion:a,parentRevision:r})]),m.entityKey??null}async#i(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}async#c(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}#h(e,o){const s=[],n=[];try{if(e&&"content"in e&&e.content)for(const t of Object.values(e.content)){if(!t.schema?.$ref)continue;const a=this.#t(t.schema.$ref);a?.componentType==="schemas"&&a.componentName&&s.push(a.componentName)}if(e&&e.$ref){const t=this.#t(e.$ref);if(t?.componentType==="requestBodies"&&t.componentName){const a=o.definition.components?.requestBodies?.[t.componentName];if(a&&"content"in a)for(const r of Object.values(a.content??{})){if(!r.schema?.$ref)continue;const i=this.#t(r.schema.$ref);i?.componentType==="schemas"&&i.componentName&&s.push(i.componentName)}}}}catch(t){n.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#m(e,o){const s=[],n=[];try{for(const t of Object.values(e)){if(t&&"content"in t&&t.content)for(const a of Object.values(t.content)){if(!a.schema?.$ref)continue;const r=this.#t(a.schema.$ref);r?.componentType==="schemas"&&r.componentName&&s.push(r.componentName)}if(t&&t.$ref){const a=this.#t(t.$ref);if(a?.componentType==="responses"&&a.componentName){const r=o.definition.components?.responses?.[a.componentName];if(r&&"content"in r)for(const i of Object.values(r.content??{})){if(!i.schema?.$ref)continue;const c=this.#t(i.schema.$ref);c?.componentType==="schemas"&&c.componentName&&s.push(c.componentName)}}}}}catch(t){n.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#t(e){try{return N(e)}catch{return{componentType:"",componentName:null}}}async#a(e,o,s,n,t,a){return e.length===0?[]:await u(e,R,async r=>await this.#l({operationId:o,schemaName:r,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}))}async#l({operationId:e,schemaName:o,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}){const r=`${n}-${p(o)}`;try{return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:`${n}-${p(e)}`,type:"uses",targetKey:r,fileHash:s,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),r}catch(i){throw this.#e.error(`Failed to create relation between operation ${e} and schema ${o}: ${i instanceof Error?i.message:"Unknown error"}`),i}}async#p({path:e,method:o,operation:s,requestBodySchemasKeys:n,responseSchemasKeys:t,description:a,parentKey:r,parentVersion:i,parentRevision:c}){const h=`${s.operationId}`,f={type:"api-operation",key:`${r}-${p(h)}`,title:h,summary:g(s.summary),tags:s.tags?.filter(m=>E(m)),metadata:{path:e,method:o,payload:n,responses:t},version:i};try{return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:f,sourceFile:a.realRelativePath,fileHash:a.hash,revision:c})}catch(m){throw this.#e.error(`Failed to create API operation entity for ${h}: ${m instanceof Error?m.message:"Unknown error"}`),m}}async#f({apiOperationKey:e,operationRelations:o,descriptionUniqueKey:s,description:n,parentVersion:t,parentRevision:a}){try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:s,fileHash:n.hash,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),await this.#y(e,o,t,a)}catch(r){this.#e.error(`Failed to create API operation relations for ${e}: ${r instanceof Error?r.message:"Unknown error"}`)}}async#y(e,o,s,n){o?.length&&await u(o,w,async t=>{try{x(t),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:t.type,targetKey:t.key,sourceVersion:s,targetVersion:s,sourceRevision:n,targetRevision:n})}catch(a){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${a instanceof Error?a.message:"Unknown error"}`)}})}}export{F as OpenApiEntitiesExtractor};
1
+ import{REDOCLY_TEAMS_RBAC as g}from"@redocly/config";import{removeLeadingSlash as b}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as $}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as N}from"../../../../../utils/async/promise-map-limit-with-status.js";import{extractTeamsFromScopeItems as E}from"../../../../../utils/rbac.js";import{removeMarkdocTags as R}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as T}from"./base.js";import{OpenapiSchemaResolver as w}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as v}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as x}from"../../../entities/validate-entity.js";import{isValidTagName as S}from"../../../utils/is-valid-tag-name.js";const A=["get","post","put","delete","patch"],O=15,d=15;class V extends T{#e;constructor(e){super("openapi",e),this.#e=e.context.logger}async loadApiDescriptions(){return await this.actions.loadOpenApiDefinitions(this.context)}mapApiDescriptionToEntity(e,o){const s=b(e.realRelativePath),n=e.definition.info.title,t=s.replace(/\.[^.]+$/,""),a=f(t.replace(/[\\/]/g,"-")),r=e.definition["x-redocly-catalog-key"],i=typeof r=="string"&&r.trim()?f(r.trim()):a;return{type:this.type,key:i,title:n,summary:R(e.definition.info.description),tags:e.definition.tags?.filter(c=>c.name&&S(c.name)).map(c=>c.name),metadata:{specType:this.specType,descriptionFile:s},version:o}}async processApiDescription(e,o,s,n){if(w.clearSchemaCache(),!e?.definition?.paths)return;const t=this.getRbacTeamsForDefinition(e.relativePath),a=this.mapApiDescriptionToEntity(e,s);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:e.realRelativePath,fileHash:e.hash,isRootEntity:!0,revision:o,rbacTeams:t}),n.delete(`${a.key}:${s}`),await this.#n(e,a.key,a.version,s,o,n,t);const r=this.#s(e.definition.paths);if(r.length!==0){const c=(await N(r,O,async({operation:h,path:m,method:l})=>{if(!h.operationId)return;const y=await this.#r(h,m,l,e,a.key,a.version,o,t);y&&n.delete(`${y}:${s}`)},this.#e)).count.failed;c>0&&this.#e.warn(`Extraction completed with ${c} failures out of ${r.length} operations for ${a.key}`)}}#s(e){return Object.entries(e).flatMap(([o,s])=>A.filter(n=>s[n]).map(n=>{const t=s[n];if(!t)throw new Error(`Operation not found for method ${n} on path ${o}`);return{operation:t,path:o,method:n.toUpperCase()}}))}async#n(e,o,s,n,t,a,r){const i=e.definition.components?.schemas;if(!i)return;const c=Object.entries(i);c.length!==0&&await $(c,d,async([h,m])=>{const l=await this.#o({schemaName:h,schema:m,description:e,parentKey:o,parentVersion:s,parentRevision:t,rbacTeams:r});a.delete(`${l.entityKey}:${n}`),l.result==="created"&&await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,sourceVersion:s,sourceRevision:t,type:"uses",targetKey:l.entityKey,targetVersion:s,targetRevision:t,fileHash:e.hash})})}async#o({schemaName:e,schema:o,description:s,parentKey:n,parentVersion:t,parentRevision:a,rbacTeams:r}){const i=w.resolveSchemaRefs(o,s),c=JSON.stringify(i),h=i[g]?E(i[g]):r,m={type:"data-schema",key:`${n}-${f(e)}`,title:e,summary:i.description??i.title??null,tags:[],metadata:{specType:this.specType,schema:c},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:m,sourceFile:s.realRelativePath,fileHash:s.hash,revision:a,rbacTeams:h})}async#r(e,o,s,n,t,a,r,i){const c=await Promise.all([this.#m(e.requestBody??null,n),this.#h(e.responses??{},n)]),h=c[0].schemaNames,m=c[1].schemaNames;c[0].errors.length>0&&this.#e.warn(`Schema extraction errors for operation ${e.operationId}: ${c[0].errors.join(", ")}`),c[1].errors.length>0&&this.#e.warn(`Response schema extraction errors for operation ${e.operationId}: ${c[1].errors.join(", ")}`);const l=h.map(p=>`${t}-${f(p)}`),y=m.map(p=>`${t}-${f(p)}`),u=await this.#p({path:o,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:y,description:n,parentKey:t,parentVersion:a,parentRevision:r,rbacTeams:i});return u.result==="created"&&await Promise.all([this.#i(h,e.operationId??"",n.hash,t,a,r),this.#c(m,e.operationId??"",n.hash,t,a,r),this.#f({apiOperationKey:u.entityKey,operationRelations:e["x-catalog-relations"],descriptionUniqueKey:t,description:n,parentVersion:a,parentRevision:r})]),u.entityKey??null}async#i(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}async#c(e,o,s,n,t,a){return e.length===0||!o?[]:await this.#a(e,o,s,n,t,a)}#m(e,o){const s=[],n=[];try{if(e&&"content"in e&&e.content)for(const t of Object.values(e.content)){if(!t.schema?.$ref)continue;const a=this.#t(t.schema.$ref);a?.componentType==="schemas"&&a.componentName&&s.push(a.componentName)}if(e&&e.$ref){const t=this.#t(e.$ref);if(t?.componentType==="requestBodies"&&t.componentName){const a=o.definition.components?.requestBodies?.[t.componentName];if(a&&"content"in a)for(const r of Object.values(a.content??{})){if(!r.schema?.$ref)continue;const i=this.#t(r.schema.$ref);i?.componentType==="schemas"&&i.componentName&&s.push(i.componentName)}}}}catch(t){n.push(`Failed to extract request body schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#h(e,o){const s=[],n=[];try{for(const t of Object.values(e)){if(t&&"content"in t&&t.content)for(const a of Object.values(t.content)){if(!a.schema?.$ref)continue;const r=this.#t(a.schema.$ref);r?.componentType==="schemas"&&r.componentName&&s.push(r.componentName)}if(t&&t.$ref){const a=this.#t(t.$ref);if(a?.componentType==="responses"&&a.componentName){const r=o.definition.components?.responses?.[a.componentName];if(r&&"content"in r)for(const i of Object.values(r.content??{})){if(!i.schema?.$ref)continue;const c=this.#t(i.schema.$ref);c?.componentType==="schemas"&&c.componentName&&s.push(c.componentName)}}}}}catch(t){n.push(`Failed to extract response schemas: ${t instanceof Error?t.message:"Unknown error"}`)}return{schemaNames:[...new Set(s)],errors:n}}#t(e){try{return v(e)}catch{return{componentType:"",componentName:null}}}async#a(e,o,s,n,t,a){return e.length===0?[]:await $(e,d,async r=>await this.#l({operationId:o,schemaName:r,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}))}async#l({operationId:e,schemaName:o,descriptionHash:s,parentKey:n,parentVersion:t,parentRevision:a}){const r=`${n}-${f(o)}`;try{return await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:`${n}-${f(e)}`,type:"uses",targetKey:r,fileHash:s,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),r}catch(i){throw this.#e.error(`Failed to create relation between operation ${e} and schema ${o}: ${i instanceof Error?i.message:"Unknown error"}`),i}}async#p({path:e,method:o,operation:s,requestBodySchemasKeys:n,responseSchemasKeys:t,description:a,parentKey:r,parentVersion:i,parentRevision:c,rbacTeams:h}){const m=`${s.operationId}`,l=`${r}-${f(m)}`,y=s[g]?E(s[g]):h,u={type:"api-operation",key:l,title:m,summary:R(s.summary),tags:s.tags?.filter(p=>S(p)),metadata:{path:e,method:o,payload:n,responses:t},version:i};try{return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:u,sourceFile:a.realRelativePath,fileHash:a.hash,revision:c,rbacTeams:y})}catch(p){throw this.#e.error(`Failed to create API operation entity for ${m}: ${p instanceof Error?p.message:"Unknown error"}`),p}}async#f({apiOperationKey:e,operationRelations:o,descriptionUniqueKey:s,description:n,parentVersion:t,parentRevision:a}){try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"partOf",targetKey:s,fileHash:n.hash,sourceVersion:t,targetVersion:t,sourceRevision:a,targetRevision:a}),await this.#y(e,o,t,a)}catch(r){this.#e.error(`Failed to create API operation relations for ${e}: ${r instanceof Error?r.message:"Unknown error"}`)}}async#y(e,o,s,n){o?.length&&await $(o,O,async t=>{try{x(t),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:t.type,targetKey:t.key,sourceVersion:s,targetVersion:"",sourceRevision:n,targetRevision:""})}catch(a){this.context.logger.warn(`Error creating entity relation for operation ${e} based on custom property: ${a instanceof Error?a.message:"Unknown error"}`)}})}}export{V as OpenApiEntitiesExtractor};
@@ -1 +1 @@
1
- import{sha1 as b}from"../../utils/crypto/sha1.js";import{isValidSanitizedString as E}from"../../utils/validate-and-sanitize-string";import{CatalogEntitiesService as h}from"./database/catalog-entities-service.js";import{createPaginationParamsValidator as F}from"../../providers/database/pagination/schemas";import{parseSearch as A}from"../../providers/database/pagination/search";import{OPERATORS as C}from"../../providers/database/pagination/constants.js";import{CacheService as I}from"../../persistence/cache/services/cache-service.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as w,CATALOG_FILTERS_CACHE_TTL_IN_SECONDS as D}from"../../constants/plugins/catalog-entities.js";import{isValidIsoDate as T}from"../../utils/is-valid-iso-date.js";const Z={all:"all",domains:"domain",services:"service",teams:"team",users:"user","api-descriptions":"api-description","data-schemas":"data-schema"},R={team:{field:"type",operator:"equal",value:"user"},"api-description":{field:"type",operator:"equal",value:"api-operation"}},V=async({entitiesTypes:e,serverOutDir:s,catalogConfig:t,queries:a={}})=>{const n=await h.getInstance({baseDbDir:s}),c=K.concat("domains","owners"),r=F(c).parse(a),p=t.excludes?.map(i=>i.key)??[],d=e.filter(i=>i!=="all"),l=k(d,p);return r.filter?r.filter={op:C.AND,conditions:[r.filter,l]}:r.filter=l,await n.getEntitiesWithRelations({sort:[{field:"type",order:"ASC"}],limit:10,...r})},_=async(e,s,t)=>{const a=await h.getInstance({baseDbDir:s});let n=null;const c=t?.revision;c&&T(c)&&(n=c);const r=t?.version;if(!E(r,{pattern:/^[a-zA-Z0-9._-]+$/,maxLength:100,allowEmpty:!0}))return null;const p=await a.getEntityWithRelationsByKey(e,{revision:n,version:r});if(!p)return null;const d=p.type==="data-schema"?await a.getRelatedEntities(e,{limit:1,filter:{field:"type",operator:"equal",value:"api-description"}}).then(f=>f.items?.[0]??null):null,l=R[p.type]??void 0,u=q(l,r,n),i=await a.getRelatedEntities(e,{limit:10,sort:[{field:"title",order:"ASC"}],filter:u,search:t?.search?A(t?.search,["key","type","title","summary"]):void 0});return{status:"success",entity:p,relatedEntity:d,relations:i}},N=e=>{const s=JSON.stringify({entitiesTypes:e.entitiesTypes.sort(),filtersConfig:e.filtersConfig});return b(s)},P=async({serverOutDir:e,entitiesTypes:s,filtersConfig:t})=>{if(!t||t.length===0)return{};const a=N({entitiesTypes:s,filtersConfig:t}),n=await I.getInstance({baseDbDir:e}),c=await n.get({key:a,namespace:w});if(c)return c;const r=await h.getInstance({baseDbDir:e}),p=[],d=new Map;for(const i of t)!i.options||i.options.length===0?p.push(i.property):d.set(i.property,i.options);const l=await r.getCatalogFilters({entitiesTypes:s,emptyFilters:p}),u={};for(const i of t){const f=d.get(i.property);if(!f){const o=l[i.property];u[i.property]=o&&o.length>0?o:[];continue}const y=(await r.getCatalogFilters({entitiesTypes:s,emptyFilters:[i.property]}))[i.property];if(!y){u[i.property]=[];continue}const g=new Map;for(const o of y){const m=o.value.toLowerCase().trim();g.set(m,{originalValue:o.value,count:o.count})}u[i.property]=f.map(o=>{const m=o.toLowerCase().trim(),S=g.get(m);return{value:S?.originalValue??o,count:S?.count??0}}).filter(o=>o.count>0).sort((o,m)=>o.value.localeCompare(m.value))}return await n.set({key:a,value:u,namespace:w,ttlInSeconds:D}),u},L=async(e,{props:s},t,{serverOutDir:a,getRouteSharedDataByFsPath:n})=>{const c=s?.catalogConfig||{};if(!e.params||!s?.catalogConfig)return{status:"notFound"};const[r,p,d]=e.params;if(!r)return{status:"notFound"};const l=O(c,r),u=l?.includes?.map(g=>g.type)??[];if(!l)return{status:"notFound"};if(!d&&p!=="entities"){if(l.hide)return{status:"notFound"};const g=await P({entitiesTypes:u,serverOutDir:a,filtersConfig:l.filters}),o=e.queries?.viewMode??"table";return{status:"success",catalogSwitcherItems:M(c,l),entitiesTypes:u,entities:await V({entitiesTypes:u,serverOutDir:a,catalogConfig:l,queries:e.queries}),catalogConfig:l,filters:g,initialViewMode:o}}const i=await _(d,a,e.queries),f=i?.entity.sourceFile,v=i?.entity.type==="api-description",y=f&&v&&n(f)||{};return i?{status:"success",entity:i.entity,relatedEntity:i.relatedEntity,relations:i.relations,entitiesCatalogConfig:c,catalogConfig:l,sharedDataIds:y}:{status:"notFound"}},O=(e,s)=>Object.values(e.catalogs??{}).find(t=>t&&typeof t=="object"&&"slug"in t&&t.slug===s),M=(e,s)=>Object.values(e.catalogs??{}).filter(t=>!t?.hide).map(t=>({labelTranslationKey:t?.catalogSwitcherLabelTranslationKey??t?.slug??"",slug:t?.slug??"",selected:t?.slug===s.slug})).sort((t,a)=>t.slug.localeCompare(a.slug)),k=(e,s)=>({op:"AND",conditions:[...e.length?[{field:"type",operator:"in",value:e}]:[],...s.length?[{field:"key",operator:"in",value:s,modifier:"not"}]:[]]}),q=(e,s,t)=>{let a=e;if(s!==void 0){const n={field:"version",operator:"equal",value:s};a=a?{op:C.AND,conditions:[a,n]}:n}if(t){const n={field:"revision",operator:"equal",value:t};a=a?{op:C.AND,conditions:[a,n]}:n}return a},K=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"];var $=L;export{$ as default};
1
+ import{sha1 as w}from"../../utils/crypto/sha1.js";import{isValidSanitizedString as F}from"../../utils/validate-and-sanitize-string";import{CatalogEntitiesService as v}from"./database/catalog-entities-service.js";import{createPaginationParamsValidator as E}from"../../providers/database/pagination/schemas";import{parseSearch as A}from"../../providers/database/pagination/search";import{OPERATORS as b}from"../../providers/database/pagination/constants.js";import{CacheService as T}from"../../persistence/cache/services/cache-service.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as S,CATALOG_FILTERS_CACHE_TTL_IN_SECONDS as I}from"../../constants/plugins/catalog-entities.js";import{isValidIsoDate as D}from"../../utils/is-valid-iso-date.js";import{expandTeamsForRead as R}from"../../utils";const Q={all:"all",domains:"domain",services:"service",teams:"team",users:"user","api-descriptions":"api-description","data-schemas":"data-schema"},V={team:{field:"type",operator:"equal",value:"user"},"api-description":{field:"type",operator:"equal",value:"api-operation"}},N=async({entitiesTypes:e,serverOutDir:i,catalogConfig:t,queries:s={},rbacTeams:o})=>{const d=await v.getInstance({baseDbDir:i}),c=x.concat("domains","owners"),l=E(c).parse(s),u=t.excludes?.map(p=>p.key)??[],g=e.filter(p=>p!=="all"),n=q(g,u);return l.filter?l.filter={op:b.AND,conditions:[l.filter,n]}:l.filter=n,await d.getEntitiesWithRelations({sort:[{field:"type",order:"ASC"}],limit:10,...l},o)},P=async(e,i,t,s)=>{const o=await v.getInstance({baseDbDir:i});let d=null;const c=t?.revision;c&&D(c)&&(d=c);const l=t?.version;if(!F(l,{pattern:/^[a-zA-Z0-9._-]+$/,maxLength:100,allowEmpty:!0}))return null;const u=await o.getEntityWithRelationsByKey(e,{revision:d,version:l},s);if(!u)return null;const g=u.type==="data-schema"?await o.getRelatedEntities(e,{limit:1,filter:{field:"type",operator:"equal",value:"api-description"}}).then(f=>f.items?.[0]??null):null,n=V[u.type]??void 0,a=K(n,l,d),p=await o.getRelatedEntities(e,{limit:10,sort:[{field:"title",order:"ASC"}],filter:a,search:t?.search?A(t?.search,["key","type","title","summary"]):void 0});return{status:"success",entity:u,relatedEntity:g,relations:p}},_=e=>{const i=JSON.stringify({entitiesTypes:e.entitiesTypes.sort(),filtersConfig:e.filtersConfig});return w(i)},L=async({serverOutDir:e,entitiesTypes:i,filtersConfig:t})=>{if(!t||t.length===0)return{};const s=_({entitiesTypes:i,filtersConfig:t}),o=await T.getInstance({baseDbDir:e}),d=await o.get({key:s,namespace:S});if(d)return d;const c=await v.getInstance({baseDbDir:e}),l=[],u=new Map;for(const a of t)!a.options||a.options.length===0?l.push(a.property):u.set(a.property,a.options);const g=await c.getCatalogFilters({entitiesTypes:i,emptyFilters:l}),n={};for(const a of t){const p=u.get(a.property);if(!p){const r=g[a.property];n[a.property]=r&&r.length>0?r:[];continue}const y=(await c.getCatalogFilters({entitiesTypes:i,emptyFilters:[a.property]}))[a.property];if(!y){n[a.property]=[];continue}const h=new Map;for(const r of y){const m=r.value.toLowerCase().trim();h.set(m,{originalValue:r.value,count:r.count})}n[a.property]=p.map(r=>{const m=r.toLowerCase().trim(),C=h.get(m);return{value:C?.originalValue??r,count:C?.count??0}}).filter(r=>r.count>0).sort((r,m)=>r.value.localeCompare(m.value))}return await o.set({key:s,value:n,namespace:S,ttlInSeconds:I}),n},O=async(e,{props:i},{variables:t},{serverOutDir:s,getRouteSharedDataByFsPath:o,getConfig:d})=>{const c=i?.catalogConfig||{};if(!e.params||!i?.catalogConfig)return{status:"notFound"};const[l,u,g]=e.params;if(!l)return{status:"notFound"};const n=M(c,l),a=n?.includes?.map(m=>m.type)??[];if(!n)return{status:"notFound"};const p=R(d().rbac||{},t?.rbac.teams||[]);if(!g&&u!=="entities"){if(n.hide)return{status:"notFound"};const m=await L({entitiesTypes:a,serverOutDir:s,filtersConfig:n.filters}),C=e.queries?.viewMode??"table";return{status:"success",catalogSwitcherItems:k(c,n),entitiesTypes:a,entities:await N({entitiesTypes:a,serverOutDir:s,catalogConfig:n,queries:e.queries,rbacTeams:p}),catalogConfig:n,filters:m,initialViewMode:C}}const f=await P(g,s,e.queries,p),y=f?.entity.sourceFile,h=f?.entity.type==="api-description",r=y&&h&&o(y)||{};return f?{status:"success",entity:f.entity,relatedEntity:f.relatedEntity,relations:f.relations,entitiesCatalogConfig:c,catalogConfig:n,sharedDataIds:r}:{status:"notFound"}},M=(e,i)=>Object.values(e.catalogs??{}).find(t=>t&&typeof t=="object"&&"slug"in t&&t.slug===i),k=(e,i)=>Object.values(e.catalogs??{}).filter(t=>!t?.hide).map(t=>({labelTranslationKey:t?.catalogSwitcherLabelTranslationKey??t?.slug??"",slug:t?.slug??"",selected:t?.slug===i.slug})).sort((t,s)=>t.slug.localeCompare(s.slug)),q=(e,i)=>({op:"AND",conditions:[...e.length?[{field:"type",operator:"in",value:e}]:[],...i.length?[{field:"key",operator:"in",value:i,modifier:"not"}]:[]]}),K=(e,i,t)=>{let s=e;if(i!==void 0){const o={field:"version",operator:"equal",value:i};s=s?{op:b.AND,conditions:[s,o]}:o}if(t){const o={field:"revision",operator:"equal",value:t};s=s?{op:b.AND,conditions:[s,o]}:o}return s},x=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"];var U=O;export{U as default};
@@ -1 +1 @@
1
- import{FileType as c}from"../../persistence/file-hashes/types.js";import{telemetryTraceStep as _}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as P}from"./utils/catalog-data-collector.js";import{CATALOG_BASE_SLUG as p,CATALOG_FILTERS_CACHE_NAMESPACE as I,ENTITIES_MAP_GLOBAL_DATA_KEY as v}from"../../constants/plugins/catalog-entities.js";import{CacheService as h}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as E}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as N}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as b}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as L}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as w}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as R}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as G}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as x}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as F}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as B}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const H="catalog-entity-template",M="catalog-entity";let u=!0;async function Y(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(t,i){await _("build.plugin.catalog_entities",async r=>{if(process.env.NEW_CATALOG_ENABLED!=="true")return;const f=await i.getConfig(),s=N(f.entitiesCatalog);if(r?.setAttribute("config",JSON.stringify(s)),!s.show)return;const{logger:l}=i,A=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",a=u&&A,e=await R.getInstance({baseDbDir:t.serverOutDir,removeExisting:a,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),C=await w.getInstance({baseDbDir:t.serverOutDir}),o=new F(C),T=[new x({fileHashManager:o,context:i,catalogEntitiesService:e,catalogConfig:s,shouldCalculateEntities:a}),new B({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.OPENAPI_DESCRIPTION,shouldCalculateEntities:a}),new b({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:a}),new L({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.GRAPHQL_DESCRIPTION,shouldCalculateEntities:a}),new G({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ARAZZO_DESCRIPTION,shouldCalculateEntities:a})];l.info("Starting entities extractors...");const y=l.startTiming();await e.transaction(async()=>{await Promise.all(T.map(async m=>m.extract()))});const d=e.getEntitySources();t.setGlobalData({[v]:d}),await(await h.getInstance({baseDbDir:t.serverOutDir})).deleteByNamespace(I),l.infoTime(y,"Entities extractors finished");const S=t.registerServerPropsGetter(M,E("../get-server-props.js")),D=t.createTemplate(H,E("../template/index.js"));t.addRoute({duplicateInAllLocales:!0,slug:p,fsPath:"",templateId:D,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[S],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:s}})});const[g]=Object.entries(s.catalogs??{}).find(([m,O])=>!O?.hide)||[];g&&t.addRedirect(p,{type:302,to:`${p}/${g}`});const n=await P.getCatalogEntitiesData(e);r?.setAttribute("totalEntities",n.totalEntitiesCount),r?.setAttribute("entitiesCountByType",JSON.stringify(n.countOfEntitiesByType)),r?.setAttribute("totalFilesSkippedByHash",n.totalFilesSkippedByHash),r?.setAttribute("totalProcessedFiles",n.totalProcessedFiles),r?.setAttribute("extractors",n.extractors),l.info("Catalog Entities plugin finished"),u=!1})}}}var rt=Y;export{Y as catalogEntitiesPlugin,rt as default};
1
+ import{FileType as u}from"../../persistence/file-hashes/types.js";import{deepEqual as O}from"../../../utils/object/deep-equal.js";import{telemetryTraceStep as P}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as I}from"./utils/catalog-data-collector.js";import{CATALOG_BASE_SLUG as m,CATALOG_FILTERS_CACHE_NAMESPACE as _,ENTITIES_MAP_GLOBAL_DATA_KEY as b}from"../../constants/plugins/catalog-entities.js";import{CacheService as v}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as f}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as C}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as w}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as N}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as R}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as L}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as G}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as x}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as F}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as H}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const B="catalog-entity-template",M="catalog-entity";let d=!0,A;async function Y(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(t,e){const i=await e.getConfig(),r=C(i.entitiesCatalog);if(!r.show)return;const{logger:o}=e,n=t.registerServerPropsGetter(M,f("../get-server-props.js")),p=t.createTemplate(B,f("../template/index.js"));t.addRoute({duplicateInAllLocales:!0,slug:m,fsPath:"",templateId:p,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[n],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([E,s])=>!s?.hide)||[];l&&t.addRedirect(m,{type:302,to:`${m}/${l}`}),o.info("Catalog Entities plugin finished")},async afterRoutesCreated(t,e){await P("build.plugin.catalog_entities",async i=>{const r=await e.getConfig(),o=C(r.entitiesCatalog);if(i?.setAttribute("config",JSON.stringify(o)),!o.show)return;const{logger:n}=e,p=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",l=d&&p,E=!O(A,r.rbac);A=r.rbac;const s=l&&E,a=await L.getInstance({baseDbDir:t.serverOutDir,removeExisting:l,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),T=await R.getInstance({baseDbDir:t.serverOutDir}),c=new F(T),y=[new x({fileHashManager:c,context:e,catalogEntitiesService:a,catalogConfig:o,shouldCalculateEntities:s}),new H({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.OPENAPI_DESCRIPTION,shouldCalculateEntities:s}),new w({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:s}),new N({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.GRAPHQL_DESCRIPTION,shouldCalculateEntities:s}),new G({actions:t,context:e,catalogEntitiesService:a,fileHashManager:c,fileType:u.ARAZZO_DESCRIPTION,shouldCalculateEntities:s})];n.info("Starting entities extractors...");const h=n.startTiming();await a.transaction(async()=>{await Promise.all(y.map(async D=>D.extract()))});const S=a.getEntitySources();t.setGlobalData({[b]:S}),await(await v.getInstance({baseDbDir:t.serverOutDir})).deleteByNamespace(_),n.infoTime(h,"Entities extractors finished");const g=await I.getCatalogEntitiesData(a);i?.setAttribute("totalEntities",g.totalEntitiesCount),i?.setAttribute("entitiesCountByType",JSON.stringify(g.countOfEntitiesByType)),i?.setAttribute("totalFilesSkippedByHash",g.totalFilesSkippedByHash),i?.setAttribute("totalProcessedFiles",g.totalProcessedFiles),i?.setAttribute("extractors",g.extractors),d=!1})}}}var rt=Y;export{Y as catalogEntitiesPlugin,rt as default};
@@ -129,6 +129,9 @@ export declare const entityDatabaseSchema: {
129
129
  readonly is_deleted: {
130
130
  readonly type: readonly ["boolean", "null"];
131
131
  };
132
+ readonly rbac_teams: {
133
+ readonly type: readonly ["string", "null"];
134
+ };
132
135
  };
133
136
  readonly required: readonly ["id", "organization_id", "project_id", "key", "type", "title", "created_at", "updated_at", "source"];
134
137
  readonly additionalProperties: false;
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]},is_deleted:{type:["boolean","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},r={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1},s={type:"object",properties:{id:{type:"string",minLength:1},key:{type:"string",minLength:1},title:{type:"string",minLength:1},type:{type:"string",minLength:1},summary:{type:["string","null"]},source:{type:"string",minLength:1},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","object","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},direction:{type:"string",enum:["outgoing","incoming"]},relation_field:{type:"string",minLength:1}},required:["id","key","title","type","source","direction","relation_field"],additionalProperties:!1};export{n as entityDatabaseSchema,i as entityRelationDatabaseSchema,r as relatedEntityDatabaseSchema,s as relatedEntityQueryRowDatabaseSchema};
1
+ import{ENTITY_RELATION_TYPES as t}from"@redocly/config";const i={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},source_key:{type:"string"},source_id:{type:["string","null"]},source_version:{type:["string","null"]},source_revision:{type:["string","null"]},source_to_target_relation:{type:"string"},target_key:{type:"string"},target_id:{type:["string","null"]},target_version:{type:["string","null"]},target_revision:{type:["string","null"]},target_to_source_relation:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"}},required:["id","organization_id","project_id","source_key","source_to_target_relation","target_key","target_to_source_relation","created_at","updated_at"],additionalProperties:!1},n={type:"object",properties:{id:{type:"string"},organization_id:{type:"string"},project_id:{type:"string"},key:{type:"string"},type:{type:"string"},title:{type:"string"},summary:{type:["string","null"]},tags:{type:["string","null"]},metadata:{type:["string","null"]},git:{type:["string","null"]},contact:{type:["string","null"]},links:{type:["string","null"]},created_at:{type:"string"},updated_at:{type:"string"},source:{type:"string"},source_file:{type:["string","null"]},file_hash:{type:["string","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},hash:{type:["string","null"]},is_current:{type:["boolean","null"]},is_default_version:{type:["boolean","null"]},is_deleted:{type:["boolean","null"]},rbac_teams:{type:["string","null"]}},required:["id","organization_id","project_id","key","type","title","created_at","updated_at","source"],additionalProperties:!1},r={type:"object",properties:{id:{type:"string"},key:{type:"string"},title:{type:"string"},type:{type:"string"},summary:{type:["string","null"]},source:{type:"string"},relation_role:{type:["string","null"]},relation_type:{type:["string","null"],enum:t},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","null"]},version:{type:["string","null"]}},required:["id","key","title","type","source"],additionalProperties:!1},s={type:"object",properties:{id:{type:"string",minLength:1},key:{type:"string",minLength:1},title:{type:"string",minLength:1},type:{type:"string",minLength:1},summary:{type:["string","null"]},source:{type:"string",minLength:1},source_file:{type:["string","null"]},created_at:{type:["string","null"]},updated_at:{type:["string","null"]},metadata:{type:["string","object","null"]},version:{type:["string","null"]},revision:{type:["string","null"]},direction:{type:"string",enum:["outgoing","incoming"]},relation_field:{type:"string",minLength:1}},required:["id","key","title","type","source","direction","relation_field"],additionalProperties:!1};export{n as entityDatabaseSchema,i as entityRelationDatabaseSchema,r as relatedEntityDatabaseSchema,s as relatedEntityQueryRowDatabaseSchema};
@@ -1,5 +1,16 @@
1
1
  import { type EntityBaseFileSchema } from '@redocly/config';
2
2
  import type { FromSchema } from 'json-schema-to-ts';
3
+ export declare const entityAttributesDtoSchema: {
4
+ readonly type: "object";
5
+ readonly properties: {
6
+ readonly rbacTeams: {
7
+ readonly type: "array";
8
+ readonly items: {
9
+ readonly type: "string";
10
+ };
11
+ };
12
+ };
13
+ };
3
14
  export declare const entityRelationDtoSchema: {
4
15
  readonly type: "object";
5
16
  readonly properties: {
@@ -90,4 +101,5 @@ export declare const entitiesRelationsDtoSchema: {
90
101
  export type EntityRelationDtoSchema = FromSchema<typeof entityRelationDtoSchema>;
91
102
  export type EntitiesRelationsDtoSchema = FromSchema<typeof entitiesRelationsDtoSchema>;
92
103
  export type EntityDtoSchema = EntityBaseFileSchema;
104
+ export type EntityAttributesDtoSchema = FromSchema<typeof entityAttributesDtoSchema>;
93
105
  //# sourceMappingURL=dto-schemas.d.ts.map
@@ -1 +1 @@
1
- import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]},isDeleted:{type:["boolean","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},i={type:"array",items:t};export{i as entitiesRelationsDtoSchema,t as entityRelationDtoSchema};
1
+ import{ENTITY_RELATION_TYPES as e}from"@redocly/config";const n={type:"object",properties:{rbacTeams:{type:"array",items:{type:"string"}}}},t={type:"object",properties:{type:{type:"string",enum:e},sourceKey:{type:"string",minLength:2,maxLength:150},targetKey:{type:"string",minLength:2,maxLength:150},sourceVersion:{type:["string","null"]},sourceRevision:{type:["string","null"]},targetVersion:{type:["string","null"]},targetRevision:{type:["string","null"]},sourceFile:{type:["string","null"]},fileHash:{type:["string","null"]},isDeleted:{type:["boolean","null"]}},required:["type","sourceKey","targetKey"],additionalProperties:!1},i={type:"array",items:t};export{i as entitiesRelationsDtoSchema,n as entityAttributesDtoSchema,t as entityRelationDtoSchema};
@@ -177,6 +177,7 @@ export type EntityReadModelSchema = {
177
177
  object: 'catalogEntity';
178
178
  domains?: RelatedEntitySchema[];
179
179
  owners?: RelatedEntitySchema[];
180
+ rbacTeams?: string[] | null;
180
181
  };
181
182
  export type EntityRevisionSummary = Pick<EntityReadModelSchema, 'version' | 'revision' | 'isCurrent' | 'createdAt' | 'updatedAt' | 'isDefaultVersion' | 'isDeleted'>;
182
183
  //# sourceMappingURL=read-model-schemas.d.ts.map
@@ -1,13 +1,13 @@
1
1
  import type { ApiDescriptionMetadataSchema } from '@redocly/config';
2
- import type { ProcessContentActions } from '../../../types/plugins/common';
3
- import type { LifecycleContext } from '../../../types/plugins/common';
2
+ import type { AfterRoutesCreatedActions } from '../../../types/plugins/common';
3
+ import type { AfterRoutesCreatedLifecycleContext } from '../../../types/plugins/common';
4
4
  import type { CatalogEntitiesService } from '../database/catalog-entities-service.js';
5
5
  import type { FileType } from '../../../persistence/file-hashes/types.js';
6
6
  import type { HashManager } from '../utils/hash-manager.js';
7
7
  export type SpecType = Exclude<ApiDescriptionMetadataSchema['specType'], 'jsonschema' | 'avro' | 'zod' | 'protobuf'>;
8
8
  export type BaseApiEntitiesExtractorParams = {
9
- actions: ProcessContentActions;
10
- context: LifecycleContext;
9
+ actions: AfterRoutesCreatedActions;
10
+ context: AfterRoutesCreatedLifecycleContext;
11
11
  catalogEntitiesService: CatalogEntitiesService;
12
12
  fileHashManager: HashManager;
13
13
  fileType: FileType;
@@ -1 +1 @@
1
- import f from"path";import{combineUrls as p}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as S}from"../../../constants/common.js";import{removeTrailingSlash as d}from"../../../../utils/url/remove-trailing-slash.js";import{slash as b}from"../../../../utils/path/slash.js";import{logger as c}from"../../../tools/notifiers/logger.js";import{getDefaultVersionByPath as v}from"./versions-config-loader.js";import{GithubSlugger as D,slug as E}from"../../../utils/index.js";import{parseBaseName as F}from"../../utils.js";const I=new Set([".jpg",".jpeg",".png",".gif",".webp",".svg",".ico",".avif",".mp3",".wav",".ogg",".m4a",".mp4",".avi",".mov",".webm",".pdf",".doc",".docx",".zip",".rar",".gz",".ttf",".woff",".woff2"]),A=async(i,{fs:e,cache:s})=>{const g=c.startTiming(),o=(await s.load("versions-config","versions-config")).data,t=new Map,n=new Map,r=new Set,l=new D;n.set(".","/"),n.set("/","/");const u=e.scan().sort((a,m)=>m.relativePath.localeCompare(a.relativePath));for(const{relativePath:a}of u){if(I.has(f.posix.extname(a)))continue;const{data:m}=await s.load(a,"is-ignored");if(m)continue;const h=b(a).replace(new RegExp("^(@i18n|@l10n)\\/"),""),w=v(a,o);N(h,{defaultVersion:w,fileSlugs:t,dirSlugs:n,allFileSlugsList:r,githubSlugger:l})}return c.verboseTime(g,"Calculated slugs. Number of file paths processed: "+u.length),{fileSlugs:t,dirSlugs:n}};function N(i,e){const s=e.fileSlugs.get(i);if(s)return s;let g=f.posix.dirname(i);const o=z(g,e)||"",{baseName:t,isIndexFile:n}=F(i),r=e.dirSlugs.has(f.posix.join(g,t));let l;if(!n&&r){const u=E(p(o,t,"/"));e.allFileSlugsList.has(u)||(l=u)}l||(l=n&&e.dirSlugs.get(g)||e.githubSlugger.slug(p(o,t))),l=d(l),e.fileSlugs.set(i,l),e.allFileSlugsList.add(l)}function z(i,e){if(e.dirSlugs.has(i))return e.dirSlugs.get(i);const s=d(f.posix.normalize(i)).split("/");let g="/",o="";for(const t of s){o=f.posix.join(o,t);const n=T(t,e.defaultVersion);let r=e.dirSlugs.get(o)||e.githubSlugger.slug(p("/",g,n));r.endsWith("/")||(r=r+"/"),e.dirSlugs.set(o,r),g=r}return e.dirSlugs.get(i)}function T(i,e){if(!i.startsWith(S))return i;const s=i.substring(S.length);return s===e?"":s}export{I as IGNORED_EXTS,A as contentSlugsLoader};
1
+ import f from"path";import{combineUrls as m}from"@redocly/theme/core/utils";import{VERSION_SEPARATOR as p}from"../../../constants/common.js";import{removeTrailingSlash as d}from"../../../../utils/url/remove-trailing-slash.js";import{slash as b}from"../../../../utils/path/slash.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{parsePathVersions as D}from"../../../../utils/path/parse-path-versions.js";import{getDefaultVersionByPath as N}from"./versions-config-loader.js";import{GithubSlugger as E,slug as v}from"../../../utils/index.js";import{parseBaseName as I}from"../../utils.js";const V=new Set([".jpg",".jpeg",".png",".gif",".webp",".svg",".ico",".avif",".mp3",".wav",".ogg",".m4a",".mp4",".avi",".mov",".webm",".pdf",".doc",".docx",".zip",".rar",".gz",".ttf",".woff",".woff2"]),M=async(i,{fs:e,cache:o})=>{const l=h.startTiming(),s=(await o.load("versions-config","versions-config")).data,g=new Map,r=new Map,n=new Set,a=new E;r.set(".","/"),r.set("/","/");const t=e.scan().sort((u,S)=>S.relativePath.localeCompare(u.relativePath));for(const{relativePath:u}of t){if(V.has(f.posix.extname(u)))continue;const{data:S}=await o.load(u,"is-ignored");if(S)continue;const w=b(u).replace(new RegExp("^(@i18n|@l10n)\\/"),""),F=N(u,s);z(w,{defaultVersion:F,fileSlugs:g,dirSlugs:r,allFileSlugsList:n,githubSlugger:a})}return h.verboseTime(l,"Calculated slugs. Number of file paths processed: "+t.length),{fileSlugs:g,dirSlugs:r}};function z(i,e){const o=e.fileSlugs.get(i);if(o)return o;const l=D(i);let s=f.posix.dirname(i);const g=c(s,e)||"",{baseName:r,isIndexFile:n}=I(i),a=e.dirSlugs.has(f.posix.join(s,r));let t;if(!n&&a){const u=v(m(g,r,"/"));e.allFileSlugsList.has(u)||(t=u)}t||(t=L({isIndexFile:n,baseName:r,dirPath:s,fileVersionProps:l,ctx:e})),t=d(t),e.fileSlugs.set(i,t),e.allFileSlugsList.add(t)}function L({isIndexFile:i,baseName:e,dirPath:o,fileVersionProps:l,ctx:s}){const g=s.dirSlugs.get(o),r=c(o,s)||"";if(i&&g)return g;const n=d(v(m(r,e)));if(l&&s.defaultVersion&&l.versionName===s.defaultVersion&&s.allFileSlugsList.has(n)){const a=d(l.versionFolderPath)||"/",t=c(a,s)||"/";return s.githubSlugger.slug(m(t,l.versionName,e))}return n}function c(i,e){if(e.dirSlugs.has(i))return e.dirSlugs.get(i);const o=d(f.posix.normalize(i)).split("/");let l="/",s="";for(const g of o){s=f.posix.join(s,g);const r=T(g,e.defaultVersion);let n=e.dirSlugs.get(s)||e.githubSlugger.slug(m("/",l,r));n.endsWith("/")||(n=n+"/"),e.dirSlugs.set(s,n),l=n}return e.dirSlugs.get(i)}function T(i,e){if(!i.startsWith(p))return i;const o=i.substring(p.length);return o===e?"":o}export{V as IGNORED_EXTS,M as contentSlugsLoader};
@@ -1 +1 @@
1
- import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEFAULT_SSO_IDP_TITLE as b,DEV_LOGIN_SLUG as g,INVITE_SLUG as T,PUBLIC_RBAC_SCOPE_ITEM as f,UI_ACCESSIBLE_CONFIG_PROPS as D,CONFIG_FILE_NAME as l}from"../../../constants/common.js";import{isDevelopMode as P}from"../../utils/envs/is-develop-mode.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as n}from"../nav-utils.js";import{resolveLogoConfig as F}from"./resolve-logo.js";import{extractTeamNames as _}from"./extract-team-names.js";import{resolveProductsConfig as E}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as O}from"./resolve-catalog-entities.js";import{telemetryTraceStep as A}from"../../../cli/telemetry/helpers/trace-step.js";async function q(i){return{id:"Default Theme",async processContent(e){await A("build.plugin.default_theme",async()=>{const t=v(e),a=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,o=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:T,[c]:f,fsPath:T,templateId:o}),i.devLogin&&a){let r={frontmatter:{},seo:{title:"Login page"},authIdps:t.filter(u=>u.title!=b),rbac:{teams:_(e.getConfig().rbac)}};const p=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:g,[c]:f,fsPath:g,templateId:p,getStaticData:async()=>({props:r})})}else if(t.length>1){let r={frontmatter:{},seo:{title:"Login page"},authIdps:t};const p=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:g,[c]:f,fsPath:g,templateId:p,getStaticData:async()=>({props:r})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),P()&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:a,outdir:o}=e,r=e.getConfig(),{navbar:p,footer:u,userMenu:m,search:I,breadcrumbs:C,products:S}=r,L=Object.keys(r?.ssoDirect||{}).length>0,d=y(r),h={navFile:l,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...j(r),navbar:await n(p,a,e,t,h),footer:await n(u,a,e,t,h),breadcrumbs:{...C,prefixItems:await n(C?.prefixItems||[],a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},userMenu:{...m,hide:m?.hide??!L,menu:await n(m?.items,a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},logo:await F(r.logo,l,o,t.fs),auth:{idpsInfo:v(e),devLogin:i.devLogin&&L},products:await E(S,e,t),search:{...I,suggestedPages:await n(I?.suggestedPages,a,e,t,{navFile:l,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await O(r.entitiesCatalog,l,o,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(i){const e=i.getConfig().ssoDirect;return Object.entries(e||{}).map(([a,o])=>({idpId:a,type:o.type,title:o.title}))}function j(i){const e={};for(const t of D)i[t]&&(e[t]=i[t]);return e}export{q as defaultThemePlugin,j as pickUiAccessibleConfig};
1
+ import{REDOCLY_TEAMS_RBAC as c}from"@redocly/config";import{DEV_LOGIN_SLUG as u,INVITE_SLUG as T,PUBLIC_RBAC_SCOPE_ITEM as m,UI_ACCESSIBLE_CONFIG_PROPS as b,CONFIG_FILE_NAME as n,DEFAULT_SSO_IDP_TITLE as P}from"../../../constants/common.js";import{isDevelopMode as _}from"../../utils/envs/is-develop-mode.js";import{getTemplatePath as s}from"./get-template-path.js";import{resolveLinksFromConfig as p}from"../nav-utils.js";import{resolveLogoConfig as F}from"./resolve-logo.js";import{extractTeamNames as E}from"./extract-team-names.js";import{resolveProductsConfig as O}from"./resolve-products-config.js";import{getExcludedFromLinkCheckerPatterns as y}from"../sidebars/utils.js";import{resolveEntitiesCatalogConfig as A}from"./resolve-catalog-entities.js";import{telemetryTraceStep as j}from"../../../cli/telemetry/helpers/trace-step.js";async function q(r){return{id:"Default Theme",async processContent(e){await j("build.plugin.default_theme",async()=>{const t=v(e),a=Object.keys(e.getConfig()?.ssoDirect||{}).length>0,i=e.createTemplate("invite",s("../../../../dist/client/app/pages/Invite/Invite.js"));if(e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:T,[c]:m,fsPath:T,templateId:i}),r.devLogin&&a){const o={frontmatter:{},seo:{title:"Login page"},authIdps:f(t),rbac:{teams:E(e.getConfig().rbac)}},l=e.createTemplate("dev-login",s("../../../../dist/client/app/pages/DevLogin/DevLogin.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,excludeFromSearch:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:o})})}else if(t.length>1){const o={frontmatter:{},seo:{title:"Login page"},authIdps:f(t)},l=e.createTemplate("login",s("../../../../dist/client/app/pages/Login/Login.js"));e.addRoute({duplicateInAllLocales:!0,excludeFromSidebar:!0,slug:u,[c]:m,fsPath:u,templateId:l,getStaticData:async()=>({props:o})})}e.createTemplate("404",s("../../../../dist/client/app/pages/404/404.js")),e.createTemplate("403",s("../../../../dist/client/app/pages/403/403.js")),e.createTemplate("403OIDC",s("../../../../dist/client/app/pages/403/403OIDC.js")),_()&&e.createTemplate("compilation-error",s("../../../../dist/client/app/pages/CompilationError/CompilationError.js"))})},async afterRoutesCreated(e,t){const{contentDir:a,outdir:i}=e,o=e.getConfig(),{navbar:l,footer:S,userMenu:g,search:I,breadcrumbs:L,products:D}=o,C=Object.keys(o?.ssoDirect||{}).length>0,d=y(o),h={navFile:n,excludedFromLinkCheckerPatterns:d};e.setGlobalData({...k(o),navbar:await p(l,a,e,t,h),footer:await p(S,a,e,t,h),breadcrumbs:{...L,prefixItems:await p(L?.prefixItems||[],a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},userMenu:{...g,hide:g?.hide??!C,menu:await p(g?.items,a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},logo:await F(o.logo,n,i,t.fs),auth:{idpsInfo:f(v(e)),devLogin:r.devLogin&&C},products:await O(D,e,t),search:{...I,suggestedPages:await p(I?.suggestedPages,a,e,t,{navFile:n,excludedFromLinkCheckerPatterns:d})},entitiesCatalog:await A(o.entitiesCatalog,n,i,t.fs),headScriptTags:void 0,linkTags:void 0,postBodyScriptTags:void 0,preBodyScriptTags:void 0})}}}function v(r){const e=r.getConfig().ssoDirect;return Object.entries(e||{}).map(([a,i])=>({idpId:a,type:i.type,title:i.title}))}function f(r){return process.env.LOCALHOST_LOGIN==="true"?r:r.filter(t=>t.title!==P)}function k(r){const e={};for(const t of b)r[t]&&(e[t]=r[t]);return e}export{q as defaultThemePlugin,k as pickUiAccessibleConfig};
@@ -1 +1 @@
1
- import p from"node:path";import{existsSync as b}from"node:fs";import{writeFile as x,access as v,rm as N,constants as X}from"fs/promises";import{REDOCLY_ROUTE_RBAC as S,REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import $ from"picomatch";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as j}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as k}from"../../../constants/common.js";import{isBuildMode as B}from"../../../utils/envs/is-build-mode.js";import{logger as a}from"../../../tools/notifiers/logger.js";import{shaHexShort as G}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as M}from"../../../utils/async/promise-map-limit.js";import{ensureDir as A}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as H,extractTeamsForSearch as U,getRbacTeamsForSearch as Y}from"../../../utils/rbac.js";import{validateLLMsTxtConfig as J,generateLLMsTxt as K,getLLMsTxtMdSlug as V}from"../llmstxt/index.js";const P=20,R="llms.txt:";async function pt(t,i,{aiSearchEnabled:e,llmstxtEnabled:r}){const s=p.join(t.outdir,k);if(!r){try{await v(s,X.W_OK),await N(s)}catch{}if(!e)return}e&&a.info("Preparing AI search documents..."),r&&a.info(`${R} Generating llms.txt files...`);const L=a.startTiming(),c=a.startTiming(),f=t.getGlobalConfig("seo"),l=f?.llmstxt,T=p.resolve(t.outdir,j),u=t.getConfig(),w=u.rbac??{},C=t.getAllRoutes(),F=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||_,O=(l?.excludeFiles||[]).map(o=>$(o)),d=[];if(await M(C,P,async o=>{if(o.excludeFromSearch)return;const y=await W(o,t),h=await q(o,y,i,t);if(h){if(r)for(const n of await h.getLLMsTxts()){if(O.some(m=>m(n.fsPath)))continue;const g=p.join(t.outdir,V(n.slug));A(g),await x(g,n.content),n.includeInLLMsTxt&&H(o,u)&&d.push(n)}if(e&&B()){const n=await h.getSearchDocuments();if(!n.length)return;const g=z(o,w),m=o.versions?.find(({active:I})=>I),E=m&&{folder:m.folderId,label:m.label,default:m.default};await Q(n,o.fsPath,g,T,F,E)}}}),e&&a.infoTime(c,"AI search documents prepared"),d.length)try{J(l);const o=await K(d,l,{title:f?.title,description:f?.description},i);A(s),await x(s,o),a.infoTime(L,`${R} files generated`)}catch(o){a.error(`${R} Failed to generate llms.txt file. ${o.message}`)}}async function W(t,i){return t.getStaticData?t.getStaticData(t,{...i,contentDir:i.contentDir,parseMarkdoc:(e,r,s)=>i.parseMarkdoc(e,r,s)}):{}}async function q(t,i,e,r){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[D]:t[D],[S]:t[S]},e,r)}function z(t,i){const e=U(t?.[D]);return e?.length?e:Y(t,i)}async function Q(t,i,e,r,s,L){await M(t,P,async c=>{const f=`${G(i+c.content)}.json`,l=A(p.join(r,f)),T=c.locale===_?s:c.locale;b(l)||await x(l,JSON.stringify({...c,rbacTeams:e||[],version:L,locale:T}),"utf-8")})}export{pt as prepareAiSearchDocuments};
1
+ import p from"node:path";import{existsSync as b}from"node:fs";import{writeFile as D,access as v,rm as N,constants as X}from"fs/promises";import{REDOCLY_ROUTE_RBAC as S,REDOCLY_TEAMS_RBAC as R}from"@redocly/config";import $ from"picomatch";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as j}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as k}from"../../../constants/common.js";import{isBuildMode as B}from"../../../utils/envs/is-build-mode.js";import{logger as a}from"../../../tools/notifiers/logger.js";import{shaHexShort as G}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as M}from"../../../utils/async/promise-map-limit.js";import{ensureDir as A}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as H,extractTeamsFromScopeItems as U,getRbacTeamsListForResource as Y}from"../../../utils/rbac.js";import{validateLLMsTxtConfig as J,generateLLMsTxt as K,getLLMsTxtMdSlug as V}from"../llmstxt/index.js";const P=20,h="llms.txt:";async function pt(t,i,{aiSearchEnabled:e,llmstxtEnabled:r}){const s=p.join(t.outdir,k);if(!r){try{await v(s,X.W_OK),await N(s)}catch{}if(!e)return}e&&a.info("Preparing AI search documents..."),r&&a.info(`${h} Generating llms.txt files...`);const L=a.startTiming(),c=a.startTiming(),f=t.getGlobalConfig("seo"),l=f?.llmstxt,T=p.resolve(t.outdir,j),u=t.getConfig(),w=u.rbac??{},C=t.getAllRoutes(),F=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||_,I=(l?.excludeFiles||[]).map(o=>$(o)),d=[];if(await M(C,P,async o=>{if(o.excludeFromSearch)return;const O=await W(o,t),x=await q(o,O,i,t);if(x){if(r)for(const n of await x.getLLMsTxts()){if(I.some(m=>m(n.fsPath)))continue;const g=p.join(t.outdir,V(n.slug));A(g),await D(g,n.content),n.includeInLLMsTxt&&H(o,u)&&d.push(n)}if(e&&B()){const n=await x.getSearchDocuments();if(!n.length)return;const g=z(o,w),m=o.versions?.find(({active:E})=>E),y=m&&{folder:m.folderId,label:m.label,default:m.default};await Q(n,o.fsPath,g,T,F,y)}}}),e&&a.infoTime(c,"AI search documents prepared"),d.length)try{J(l);const o=await K(d,l,{title:f?.title,description:f?.description},i);A(s),await D(s,o),a.infoTime(L,`${h} files generated`)}catch(o){a.error(`${h} Failed to generate llms.txt file. ${o.message}`)}}async function W(t,i){return t.getStaticData?t.getStaticData(t,{...i,contentDir:i.contentDir,parseMarkdoc:(e,r,s)=>i.parseMarkdoc(e,r,s)}):{}}async function q(t,i,e,r){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[R]:t[R],[S]:t[S]},e,r)}function z(t,i){const e=U(t?.[R]);return e?.length?e:Y(t,i)}async function Q(t,i,e,r,s,L){await M(t,P,async c=>{const f=`${G(i+c.content)}.json`,l=A(p.join(r,f)),T=c.locale===_?s:c.locale;b(l)||await D(l,JSON.stringify({...c,rbacTeams:e||[],version:L,locale:T}),"utf-8")})}export{pt as prepareAiSearchDocuments};
@@ -1 +1 @@
1
- import{REDOCLY_ROUTE_RBAC as T,REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{existsSync as O}from"fs";import{rm as $}from"node:fs/promises";import{DEFAULT_LOCALE_PLACEHOLDER as y}from"../../../../constants/common.js";import{SEARCH_DATA_EXPORT_FOLDER as S}from"../../../constants/plugins/search.js";import{isBuildMode as A}from"../../../utils/envs/is-build-mode.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{extractTeamsForSearch as M,getRbacTeamsForSearch as P}from"../../../utils/index.js";import{getSearchDocumentGroup as B}from"../utils.js";import{telemetry as I}from"../../../../cli/telemetry/index.js";import{telemetryTraceStep as _}from"../../../../cli/telemetry/helpers/trace-step.js";async function J(b,t,l){await _("build.plugin.search.prepare_search_documents",async()=>{n.info("Preparing search documents and create indexes..."),A()&&O(`${t.outdir}/${S}`)&&await $(`${t.outdir}/${S}`,{recursive:!0});const F=n.startTiming(),R=t.getConfig().rbac,v=[y,...b.localeFolders.map(a=>a.toLowerCase())];for(const a of v)await _("build.plugin.search.prepare_search_documents.locale",async s=>{const w=t.getAllRoutesForLocale(a);let g=0,h=0;for(const r of w){if(g++,r.excludeFromSearch)continue;const f=new Map,{product:m}=r,C=await r.getStaticData?.(r,{...t,contentDir:t.contentDir,parseMarkdoc:(c,e,u)=>t.parseMarkdoc(c,e,u)})||{},i=await r.getSearchDocuments?.(r,{...C,[p]:r[p],[T]:r[T]},t),o=r.versions?.find(c=>c.active),L=P(r,R??{});if(i){if(i&&i.length){h+=i.length;for(const c in i){let e=i[c];const u=M(e?.[p]),D=u?.length?u:L,x=e.tags||[];e={...e,...o&&{version:o.version,isDefaultVersion:o.default,versionFolderId:o.folderId},...m&&{product:m},rbacTeams:D,tags:[...x,...D,...o?o.default?["v:default"]:[`v:${o.folderId}:${o.version}`]:["v:default"],...m?[`p:${m.name}`]:[]],url:e.url&&(e.path&&e.path.length>1?e.url:e.url.split("#")[0])};const d=B(e.facets);if(d){const E=f.get(d)??[];f.set(d,[...E,e])}}}for(const[c,e]of f)await l.addDocuments(e,{locale:a,group:c,outDir:t.outdir})}}s?.setAttribute("locale",a),s?.setAttribute("totalDocuments",g),s?.setAttribute("totalSearchDocuments",h)});if(l.cleanupFacetValues(t),n.infoTime(F,"Search indexes created"),A()){n.info("Writing out search data...");const a=n.startTiming();await l.export(t.outdir);const s=n.infoTime(a,"Search data written");s&&I.sendTimingPerformedMessage(s)}})}export{J as prepareSearchDocuments};
1
+ import{REDOCLY_ROUTE_RBAC as T,REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{existsSync as O}from"fs";import{rm as $}from"node:fs/promises";import{DEFAULT_LOCALE_PLACEHOLDER as y}from"../../../../constants/common.js";import{SEARCH_DATA_EXPORT_FOLDER as S}from"../../../constants/plugins/search.js";import{isBuildMode as A}from"../../../utils/envs/is-build-mode.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{extractTeamsFromScopeItems as M,getRbacTeamsListForResource as P}from"../../../utils/index.js";import{getSearchDocumentGroup as I}from"../utils.js";import{telemetry as B}from"../../../../cli/telemetry/index.js";import{telemetryTraceStep as R}from"../../../../cli/telemetry/helpers/trace-step.js";async function J(_,t,l){await R("build.plugin.search.prepare_search_documents",async()=>{n.info("Preparing search documents and create indexes..."),A()&&O(`${t.outdir}/${S}`)&&await $(`${t.outdir}/${S}`,{recursive:!0});const b=n.startTiming(),F=t.getConfig().rbac,v=[y,..._.localeFolders.map(a=>a.toLowerCase())];for(const a of v)await R("build.plugin.search.prepare_search_documents.locale",async c=>{const L=t.getAllRoutesForLocale(a);let g=0,D=0;for(const r of L){if(g++,r.excludeFromSearch)continue;const f=new Map,{product:m}=r,w=await r.getStaticData?.(r,{...t,contentDir:t.contentDir,parseMarkdoc:(s,e,u)=>t.parseMarkdoc(s,e,u)})||{},i=await r.getSearchDocuments?.(r,{...w,[p]:r[p],[T]:r[T]},t),o=r.versions?.find(s=>s.active),C=P(r,F??{});if(i){if(i&&i.length){D+=i.length;for(const s in i){let e=i[s];const u=M(e?.[p]),h=u?.length?u:C,x=e.tags||[];e={...e,...o&&{version:o.version,isDefaultVersion:o.default,versionFolderId:o.folderId},...m&&{product:m},rbacTeams:h,tags:[...x,...h,...o?o.default?["v:default"]:[`v:${o.folderId}:${o.version}`]:["v:default"],...m?[`p:${m.name}`]:[]],url:e.url&&(e.path&&e.path.length>1?e.url:e.url.split("#")[0])};const d=I(e.facets);if(d){const E=f.get(d)??[];f.set(d,[...E,e])}}}for(const[s,e]of f)await l.addDocuments(e,{locale:a,group:s,outDir:t.outdir})}}c?.setAttribute("locale",a),c?.setAttribute("totalDocuments",g),c?.setAttribute("totalSearchDocuments",D)});if(l.cleanupFacetValues(t),n.infoTime(b,"Search indexes created"),A()){n.info("Writing out search data...");const a=n.startTiming();await l.export(t.outdir);const c=n.infoTime(a,"Search data written");c&&B.sendTimingPerformedMessage(c)}})}export{J as prepareSearchDocuments};
@@ -1 +1 @@
1
- import{DEFAULT_SSO_IDP_TITLE as d}from"../../../constants/common.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const f="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",y="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function O(g){return{id:"sso",async processContent(e){await u("build.plugin.sso",async c=>{const o=e.getConfig();if(c?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(o.sso||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0||o.sso&&Array.isArray(o.sso)&&!o.sso.length)return;const a=!!(o.rbac&&typeof o.rbac=="object"&&Object.keys(o.rbac).length!==0),p=o.requiresLogin;if(!a&&!p)return;let n=f,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?y:"";const s=o.residency;if(s){const r=s.endsWith("/")?s.slice(0,-1):s;n=`${r.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?`${r}/api/sso/oidc/introspect`:""}let t="AUTO";o.sso&&(Array.isArray(o.sso)?t=o.sso.join(","):t=o.sso);const l={oidc:{title:d,type:"OIDC",configurationUrl:n,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:{login_hint:"{{ process.env.ORG_ID }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORG_ID }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{O as ssoPlugin};
1
+ import{DEFAULT_SSO_IDP_TITLE as d}from"../../../constants/common.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const f="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",y="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function O(g){return{id:"sso",async processContent(e){await u("build.plugin.sso",async c=>{const o=e.getConfig();if(c?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(o.sso||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0||o.sso&&Array.isArray(o.sso)&&!o.sso.length)return;const a=!!(o.rbac&&typeof o.rbac=="object"&&Object.keys(o.rbac).length!==0),p=o.requiresLogin;if(!a&&!p)return;let n=f,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?y:"";const s=o.residency;if(s){const r=s.endsWith("/")?s.slice(0,-1):s;n=`${r.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?`${r}/api/sso/oidc/introspect`:""}let t="AUTO";o.sso&&(Array.isArray(o.sso)?t=o.sso.join(","):t=o.sso);const l={oidc:{title:d,type:"OIDC",configurationUrl:n,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:{login_hint:"{{ process.env.ORG_SLUG }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORG_ID }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{O as ssoPlugin};
@@ -0,0 +1,143 @@
1
+ export declare const entitiesAttributesTable: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
2
+ name: "entities_attributes";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
6
+ name: "id";
7
+ tableName: "entities_attributes";
8
+ dataType: "string";
9
+ columnType: "SQLiteText";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: false;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: [string, ...string[]];
18
+ baseColumn: never;
19
+ identity: undefined;
20
+ generated: undefined;
21
+ }, {}, {
22
+ length: number | undefined;
23
+ }>;
24
+ organizationId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
25
+ name: "organization_id";
26
+ tableName: "entities_attributes";
27
+ dataType: "string";
28
+ columnType: "SQLiteText";
29
+ data: string;
30
+ driverParam: string;
31
+ notNull: true;
32
+ hasDefault: false;
33
+ isPrimaryKey: false;
34
+ isAutoincrement: false;
35
+ hasRuntimeDefault: false;
36
+ enumValues: [string, ...string[]];
37
+ baseColumn: never;
38
+ identity: undefined;
39
+ generated: undefined;
40
+ }, {}, {
41
+ length: number | undefined;
42
+ }>;
43
+ projectId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
44
+ name: "project_id";
45
+ tableName: "entities_attributes";
46
+ dataType: "string";
47
+ columnType: "SQLiteText";
48
+ data: string;
49
+ driverParam: string;
50
+ notNull: true;
51
+ hasDefault: false;
52
+ isPrimaryKey: false;
53
+ isAutoincrement: false;
54
+ hasRuntimeDefault: false;
55
+ enumValues: [string, ...string[]];
56
+ baseColumn: never;
57
+ identity: undefined;
58
+ generated: undefined;
59
+ }, {}, {
60
+ length: number | undefined;
61
+ }>;
62
+ entityKey: import("drizzle-orm/sqlite-core").SQLiteColumn<{
63
+ name: "entity_key";
64
+ tableName: "entities_attributes";
65
+ dataType: "string";
66
+ columnType: "SQLiteText";
67
+ data: string;
68
+ driverParam: string;
69
+ notNull: true;
70
+ hasDefault: false;
71
+ isPrimaryKey: false;
72
+ isAutoincrement: false;
73
+ hasRuntimeDefault: false;
74
+ enumValues: [string, ...string[]];
75
+ baseColumn: never;
76
+ identity: undefined;
77
+ generated: undefined;
78
+ }, {}, {
79
+ length: number | undefined;
80
+ }>;
81
+ rbacTeams: import("drizzle-orm/sqlite-core").SQLiteColumn<{
82
+ name: "rbac_teams";
83
+ tableName: "entities_attributes";
84
+ dataType: "string";
85
+ columnType: "SQLiteText";
86
+ data: string;
87
+ driverParam: string;
88
+ notNull: false;
89
+ hasDefault: false;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: [string, ...string[]];
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {
98
+ length: number | undefined;
99
+ }>;
100
+ createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
101
+ name: "created_at";
102
+ tableName: "entities_attributes";
103
+ dataType: "string";
104
+ columnType: "SQLiteText";
105
+ data: string;
106
+ driverParam: string;
107
+ notNull: true;
108
+ hasDefault: false;
109
+ isPrimaryKey: false;
110
+ isAutoincrement: false;
111
+ hasRuntimeDefault: false;
112
+ enumValues: [string, ...string[]];
113
+ baseColumn: never;
114
+ identity: undefined;
115
+ generated: undefined;
116
+ }, {}, {
117
+ length: number | undefined;
118
+ }>;
119
+ updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
120
+ name: "updated_at";
121
+ tableName: "entities_attributes";
122
+ dataType: "string";
123
+ columnType: "SQLiteText";
124
+ data: string;
125
+ driverParam: string;
126
+ notNull: true;
127
+ hasDefault: false;
128
+ isPrimaryKey: false;
129
+ isAutoincrement: false;
130
+ hasRuntimeDefault: false;
131
+ enumValues: [string, ...string[]];
132
+ baseColumn: never;
133
+ identity: undefined;
134
+ generated: undefined;
135
+ }, {}, {
136
+ length: number | undefined;
137
+ }>;
138
+ };
139
+ dialect: "sqlite";
140
+ }>;
141
+ export type DatabaseEntityAttributes = typeof entitiesAttributesTable.$inferSelect;
142
+ export type DatabaseEntityAttributesDto = typeof entitiesAttributesTable.$inferInsert;
143
+ //# sourceMappingURL=entities-attributes-table.d.ts.map
@@ -0,0 +1 @@
1
+ import{sqliteTable as i,text as t,uniqueIndex as a}from"drizzle-orm/sqlite-core";const o=i("entities_attributes",{id:t("id").primaryKey(),organizationId:t("organization_id").notNull(),projectId:t("project_id").notNull(),entityKey:t("entity_key").notNull(),rbacTeams:t("rbac_teams"),createdAt:t("created_at").notNull(),updatedAt:t("updated_at").notNull()},e=>[a("idx_entities_attributes_key").on(e.entityKey)]);export{o as entitiesAttributesTable};
@@ -1,15 +1,16 @@
1
1
  import '../node-crypto-polyfill.js';
2
2
  import { REDOCLY_TEAMS_RBAC, REDOCLY_ROUTE_RBAC } from '@redocly/config';
3
- import type { PageProps, PageStaticData, RbacConfig, RbacScopeItems, RedoclyConfig, SsoConfig } from '@redocly/config';
4
- import type { AuthDetails, PageRouteDetails } from '../types';
3
+ import type { RbacConfig, RbacScopeItems, RedoclyConfig, SsoConfig } from '@redocly/config';
4
+ import type { AuthDetails } from '../types';
5
5
  import type { ContentFs } from '../fs/content-fs.js';
6
6
  import type { RbacFeatures } from '../../constants/common.js';
7
7
  export type ProjectRole = 'NONE' | 'READ' | 'TRIAGE' | 'WRITE' | 'MAINTAIN' | 'ADMIN';
8
8
  export declare const PROJECT_ROLES_ORDERED_BY_ACCESS_LEVEL: string[];
9
9
  export declare function getHigherRole(a: ProjectRole, b: ProjectRole): ProjectRole;
10
- export declare function getAllowedTeamsForRoute(rbacConfig: RbacConfig | undefined, resource: {
11
- [REDOCLY_ROUTE_RBAC]?: PageRouteDetails<PageStaticData, PageProps>[typeof REDOCLY_ROUTE_RBAC];
12
- } | undefined): RbacScopeItems;
10
+ export declare function getScopeItemsForResource(rbacConfig: RbacConfig | undefined, resource: {
11
+ fsPath?: string;
12
+ slug?: string;
13
+ }): RbacScopeItems;
13
14
  export declare function canAccessFeature(feature: RbacFeatures, auth: AuthDetails, rbacConfig?: RbacConfig, requiresLogin?: boolean): boolean;
14
15
  export declare function isResourcePubliclyAccessible(resource: {
15
16
  slug: string;
@@ -84,7 +85,10 @@ export declare const normalizeRbacConfig: (rbacConfig: RbacConfig) => {
84
85
  } | undefined;
85
86
  } | undefined;
86
87
  };
87
- export declare function getRbacTeamsForSearch(route: PageRouteDetails<PageStaticData, PageProps>, rbacConfig: RbacConfig): string[];
88
- export declare function extractTeamsForSearch(scopeItems: RbacScopeItems | undefined): string[];
88
+ export declare function getRbacTeamsListForResource(resource: {
89
+ fsPath?: string;
90
+ slug?: string;
91
+ }, rbacConfig: RbacConfig): string[];
92
+ export declare function extractTeamsFromScopeItems(scopeItems: RbacScopeItems | undefined): string[];
89
93
  export declare function expandTeamsForRead(rbacConfig: RbacConfig, teamNames: string[]): string[];
90
94
  //# sourceMappingURL=rbac.d.ts.map