@redocly/reef 0.130.0-next.8 → 0.130.0

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 (117) hide show
  1. package/CHANGELOG.md +133 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/develop.js +1 -1
  4. package/dist/cli/stats/collectors/openapi.js +1 -1
  5. package/dist/client/ErrorBoundary.js +1 -1
  6. package/dist/client/app/Sidebar/RequestAccessButton.js +2 -2
  7. package/dist/client/app/Sidebar/Sidebar.js +2 -2
  8. package/dist/client/app/hooks/catalog/useCatalogClassic.js +1 -1
  9. package/dist/client/app/hooks/catalog/useCatalogFilter.js +1 -1
  10. package/dist/client/app/hooks/catalog/useCatalogViewMode.js +1 -1
  11. package/dist/client/app/hooks/catalog/useSearchTracker.js +1 -1
  12. package/dist/client/app/hooks/usePageTimeTracker.js +1 -1
  13. package/dist/client/app/hooks/useRouteChangeTracker.js +1 -1
  14. package/dist/client/app/pages/DevLogin/DevLogin.js +1 -1
  15. package/dist/client/app/search/message-handlers.d.ts +29 -0
  16. package/dist/client/app/search/message-handlers.js +1 -0
  17. package/dist/client/app/search/sse-parser.d.ts +10 -0
  18. package/dist/client/app/search/sse-parser.js +2 -0
  19. package/dist/client/app/search/useAiSearch.d.ts +9 -11
  20. package/dist/client/app/search/useAiSearch.js +1 -1
  21. package/dist/client/app/search/useSearch.js +1 -1
  22. package/dist/client/constants/ai-search.d.ts +30 -0
  23. package/dist/client/constants/ai-search.js +1 -0
  24. package/dist/client/constants/index.d.ts +2 -0
  25. package/dist/client/constants/index.js +1 -0
  26. package/dist/client/types/ai-search.d.ts +73 -0
  27. package/dist/client/types/ai-search.js +0 -0
  28. package/dist/client/types/index.d.ts +1 -0
  29. package/dist/constants/l10n/langs/ar.js +1 -1
  30. package/dist/constants/l10n/langs/de.js +1 -1
  31. package/dist/constants/l10n/langs/en.js +1 -1
  32. package/dist/constants/l10n/langs/es.js +1 -1
  33. package/dist/constants/l10n/langs/fr.js +1 -1
  34. package/dist/constants/l10n/langs/hi.js +1 -1
  35. package/dist/constants/l10n/langs/it.js +1 -1
  36. package/dist/constants/l10n/langs/ja.js +1 -1
  37. package/dist/constants/l10n/langs/ko.js +1 -1
  38. package/dist/constants/l10n/langs/pl.js +1 -1
  39. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  40. package/dist/constants/l10n/langs/pt.js +1 -1
  41. package/dist/constants/l10n/langs/ru.js +1 -1
  42. package/dist/constants/l10n/langs/uk.js +1 -1
  43. package/dist/constants/l10n/langs/zh.js +1 -1
  44. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  45. package/dist/server/constants/common.js +1 -1
  46. package/dist/server/entitlements/entitlements-provider.js +1 -1
  47. package/dist/server/persistence/kv/services/kv-service.js +1 -1
  48. package/dist/server/plugins/asyncapi-docs/template/AsyncApiDocs.js +5 -3
  49. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +32 -9
  50. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  51. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.d.ts +16 -5
  52. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.js +21 -17
  53. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +35 -9
  54. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +24 -21
  55. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +31 -8
  56. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  57. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  58. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.d.ts +7 -1
  59. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -1
  60. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.d.ts +1 -1
  61. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  62. package/dist/server/plugins/catalog-entities/database/repositories/utils/build-entities-exclusion-filter.d.ts +13 -0
  63. package/dist/server/plugins/catalog-entities/database/repositories/utils/build-entities-exclusion-filter.js +1 -0
  64. package/dist/server/plugins/catalog-entities/database/repositories/utils/build-rbac-filter.d.ts +31 -0
  65. package/dist/server/plugins/catalog-entities/database/repositories/utils/build-rbac-filter.js +9 -0
  66. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  67. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  68. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
  69. package/dist/server/plugins/catalog-entities/get-server-props.js +1 -1
  70. package/dist/server/plugins/catalog-entities/types/openapi.d.ts +11 -0
  71. package/dist/server/plugins/catalog-entities/types/openapi.js +0 -0
  72. package/dist/server/plugins/catalog-entities/types/params.d.ts +6 -0
  73. package/dist/server/plugins/catalog-entities/types/params.js +0 -0
  74. package/dist/server/plugins/catalog-entities/utils/catalog-data-collector.js +1 -1
  75. package/dist/server/plugins/catalog-entities/utils/get-not-accessible-catalog-resources.d.ts +11 -0
  76. package/dist/server/plugins/catalog-entities/utils/get-not-accessible-catalog-resources.js +1 -0
  77. package/dist/server/plugins/config-parser/index.js +1 -1
  78. package/dist/server/plugins/markdown/markdown-static-data-loader.js +1 -1
  79. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +1 -1
  80. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
  81. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
  82. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
  83. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
  84. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  85. package/dist/server/plugins/mcp/handlers/errors.js +1 -1
  86. package/dist/server/plugins/mcp/servers/base-server.js +1 -1
  87. package/dist/server/plugins/openapi-docs/template/OpenAPIDocs.js +8 -4
  88. package/dist/server/plugins/openapi-docs/template/helpers.d.ts +1 -1
  89. package/dist/server/plugins/openapi-docs/template/helpers.js +3 -3
  90. package/dist/server/plugins/scorecard-classic/types.d.ts +3 -3
  91. package/dist/server/plugins/scorecard-classic/types.js +1 -1
  92. package/dist/server/plugins/search/llmstxt/index.js +4 -4
  93. package/dist/server/plugins/sso/index.js +1 -1
  94. package/dist/server/store.js +1 -1
  95. package/dist/server/tools/notifiers/logger.js +1 -1
  96. package/dist/server/tools/notifiers/reporter.js +7 -7
  97. package/dist/server/utils/rbac.d.ts +65 -0
  98. package/dist/server/web-server/auth.js +3 -3
  99. package/dist/server/web-server/middleware/catalogAuthMiddleware.d.ts +4 -6
  100. package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
  101. package/dist/server/web-server/routes/ask-ai.js +1 -1
  102. package/dist/server/web-server/routes/auth.js +1 -1
  103. package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
  104. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  105. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  106. package/dist/server/web-server/routes/catalog/helpers/has-access-to-entity.d.ts +10 -0
  107. package/dist/server/web-server/routes/catalog/helpers/has-access-to-entity.js +1 -0
  108. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  109. package/dist/server/web-server/routes/helpers/get-current-rbac-teams.d.ts +3 -0
  110. package/dist/server/web-server/routes/helpers/get-current-rbac-teams.js +1 -0
  111. package/dist/server/web-server/routes/helpers/get-rbac-restrictions-data-for-catalog.d.ts +11 -0
  112. package/dist/server/web-server/routes/helpers/get-rbac-restrictions-data-for-catalog.js +1 -0
  113. package/dist/server/web-server/routes/index.js +1 -1
  114. package/dist/server/web-server/routes/mcp-oauth.js +1 -1
  115. package/dist/server/web-server/routes/page-data.js +1 -1
  116. package/dist/server/web-server/utils.d.ts +2 -2
  117. package/package.json +16 -16
@@ -1 +1 @@
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
+ import{REDOCLY_TEAMS_RBAC as $}from"@redocly/config";import{removeLeadingSlash as x}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as T}from"../../../../../utils/async/promise-map-limit-with-status.js";import{extractTeamsFromScopeItems as R}from"../../../../../utils/rbac.js";import{removeMarkdocTags as w}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as N}from"./base.js";import{OpenapiSchemaResolver as S}from"../../../utils/openapi-schema-resolver.js";import{extractPartsFromComponentsRef as v}from"../../../utils/extract-parts-from-components-ref.js";import{validateEntityRelation as A}from"../../../entities/validate-entity.js";import{isValidTagName as O}from"../../../utils/is-valid-tag-name.js";const D=["get","post","put","delete","patch"],b=15,d=15;class U extends N{#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=x(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:w(e.definition.info.description),tags:e.definition.tags?.filter(c=>c.name&&O(c.name)).map(c=>c.name),metadata:{specType:this.specType,descriptionFile:s},version:o}}async processApiDescription(e,o,s,n){if(S.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 T(r,b,async({operation:h,path:m,method:l})=>{if(!h.operationId)return;const f=await this.#r(h,m,l,e,a.key,a.version,o,t);f&&n.delete(`${f}:${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])=>D.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 E(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=S.resolveSchemaRefs(o,s),c=JSON.stringify(i),h=i[$]?R(i[$]):r,m=R(i["x-rbac"]),l={type:"data-schema",key:`${n}-${p(e)}`,title:e,summary:i.description??i.title??null,tags:[],metadata:{specType:this.specType,schema:c},version:t};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:l,sourceFile:s.realRelativePath,fileHash:s.hash,revision:a,rbacTeams:m.length?m: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(g=>`${t}-${p(g)}`),f=m.map(g=>`${t}-${p(g)}`),y=await this.#p({path:o,method:s,operation:e,requestBodySchemasKeys:l,responseSchemasKeys:f,description:n,parentKey:t,parentVersion:a,parentRevision:r,rbacTeams:i});return y.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:y.entityKey,operationRelations:e["x-catalog-relations"],descriptionUniqueKey:t,description:n,parentVersion:a,parentRevision:r})]),y.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(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}-${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,rbacTeams:h}){const m=`${s.operationId}`,l=`${r}-${p(m)}`,f=s[$]?R(s[$]):h,y=R(s["x-rbac"]),g={type:"api-operation",key:l,title:m,summary:w(s.summary),tags:s.tags?.filter(u=>O(u)),metadata:{path:e,method:o,payload:n,responses:t},version:i};try{return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:g,sourceFile:a.realRelativePath,fileHash:a.hash,revision:c,rbacTeams:y.length>0?y:f})}catch(u){throw this.#e.error(`Failed to create API operation entity for ${m}: ${u instanceof Error?u.message:"Unknown error"}`),u}}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 E(o,b,async t=>{try{A(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{U as OpenApiEntitiesExtractor};
@@ -1 +1 @@
1
- import{CATALOG_ENTITIES_FILES_REGEX as E,ENTITY_SCHEMA_EXCLUDED_FOLDERS as d}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as l,FileType as a}from"../../../../persistence/file-hashes/types.js";import{OPERATORS as u}from"../../../../providers/database/pagination/constants.js";import{promiseMapLimit as h}from"../../../../utils/async/promise-map-limit.js";import{VERSION_NOT_SPECIFIED as m}from"@redocly/theme/core/constants";import{extractFileContent as p}from"../../entities/extract-file-content.js";import{resolveEntityVersion as g}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as y}from"../../entities/validate-entity.js";import{catalogDataCollector as f}from"../../utils/catalog-data-collector.js";const I=15;class v{#t;#e;#i;#r;#s;constructor({fileHashManager:e,context:t,catalogEntitiesService:i,catalogConfig:o,shouldCalculateEntities:s}){this.#t=e,this.#e=t,this.#i=i,this.#r=o,this.#s=s}async extract(e){try{if(e&&this.#o(e)){await this.#n(e);return}await this.#t.markAllAsOutdated(a.ENTITY_DEFINITION);const i=this.#e.fs.scan(E).filter(({relativePath:o})=>this.#o(o));i.length&&f.addExtractor("fs"),await h(i,I,async({relativePath:o})=>{await this.#n(o)}),await this.#f()}catch(t){this.#e.logger.error("Error extracting entities.",t)}}#o=e=>!!(e.match(E)&&!d.some(t=>e.includes(t)));#n=async e=>{try{const t=await p(e,this.#e);if(!t){this.#e.logger.warn(`Error extracting content from ${e}.`);return}const i=await this.#t.computeFileHash(t);if(!((await this.#t.getByPath(e))?.hash!==i||this.#s||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){f.increaseSkippedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE);return}const r=this.#a(t.entities,e);if(!r)return;const n=await this.#i.getEntityKeysAndVersionsBySourceFile(e);await this.#c(r,e,i,n),await this.#l(n,e),f.increaseProcessedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE)}catch(t){this.#e.logger.warn(`Error processing file "${e}". ${t instanceof Error?t.message:String(t)}.`)}};#a=(e,t)=>{try{return y(e,this.#r)}catch(i){return this.#e.logger.warn(`Error validating entities in "${t}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(e,t,i,o)=>{for(const s of e)try{const r=g(s.version,t);if(!r.success){this.#e.logger.warn(`Entity "${s.key}" in file "${t}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...s,version:r.version};if(await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:t,fileHash:i}),s.key){const c=r.version??m;o.delete(`${s.key}:${c}`)}}catch(r){const n=s.key??"unknown";this.#e.logger.warn(`Error processing entity "${n}" from "${t}". ${r instanceof Error?r.message:String(r)}.`)}};#l=async(e,t)=>{if(e.size===0)return;const i=Array.from(e).map(r=>{const[n,c]=r.split(":");return{key:n,version:c}}),o=Array.from(new Set(i.map(({key:r})=>r))),s=i.map(({key:r,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:r},{field:"version",operator:"equal",value:n}]}));await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:s},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:t}]})};#f=async()=>{const e=await this.#t.getAllOutdated(a.ENTITY_DEFINITION);if(!e||e.length===0)return;const t=await this.#i.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:e.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});!t||t.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:t.items.map(({key:i})=>i)}),await this.#t.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:l.OUTDATED}]}))}}export{v as FsEntitiesExtractor};
1
+ import{CATALOG_ENTITIES_FILES_REGEX as E,ENTITY_SCHEMA_EXCLUDED_FOLDERS as d}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as l,FileType as a}from"../../../../persistence/file-hashes/types.js";import{OPERATORS as u}from"../../../../providers/database/pagination/constants.js";import{promiseMapLimit as m}from"../../../../utils/async/promise-map-limit.js";import{VERSION_NOT_SPECIFIED as p}from"@redocly/theme/core/constants";import{extractFileContent as h}from"../../entities/extract-file-content.js";import{resolveEntityVersion as g}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as y}from"../../entities/validate-entity.js";import{catalogDataCollector as f}from"../../utils/catalog-data-collector.js";const I=15;class v{#t;#e;#i;#r;#s;constructor({fileHashManager:e,context:t,catalogEntitiesService:i,catalogConfig:o,shouldCalculateEntities:s}){this.#t=e,this.#e=t,this.#i=i,this.#r=o,this.#s=s}async extract(e){try{if(e&&this.#o(e)){await this.#n(e);return}await this.#t.markAllAsOutdated(a.ENTITY_DEFINITION);const i=this.#e.fs.scan(E).filter(({relativePath:o})=>this.#o(o));i.length&&f.addExtractor("fs"),await m(i,I,async({relativePath:o})=>{await this.#n(o)}),await this.#f()}catch(t){this.#e.logger.error("Error extracting entities.",t)}}#o=e=>!!(e.match(E)&&!d.some(t=>e.includes(t)));#n=async e=>{try{const t=await h(e,this.#e);if(!t){this.#e.logger.warn(`Error extracting content from ${e}.`);return}const i=await this.#t.computeFileHash(t);if(!((await this.#t.getByPath(e))?.hash!==i||this.#s||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){f.increaseSkippedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE);return}const r=this.#a(t.entities,e);if(!r)return;const n=await this.#i.getEntityKeysAndVersionsBySourceFile(e);await this.#c(r,e,i,n),await this.#l(n,e),f.increaseProcessedFilesCount(),await this.#t.upsert(a.ENTITY_DEFINITION,e,i,l.UP_TO_DATE)}catch(t){this.#e.logger.warn(`Error processing file "${e}". ${t instanceof Error?t.message:String(t)}.`)}};#a=(e,t)=>{try{return y(e,this.#r)}catch(i){return this.#e.logger.warn(`Error validating entities in "${t}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(e,t,i,o)=>{for(const s of e)try{const r=g(s.version,t);if(!r.success){this.#e.logger.warn(`Entity "${s.key}" in file "${t}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...s,version:r.version};if(await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:t,fileHash:i}),s.key){const c=r.version??p;o.delete(`${s.key}:${c}`)}}catch(r){const n=s.key??"unknown";this.#e.logger.warn(`Error processing entity "${n}" from "${t}". ${r instanceof Error?r.message:String(r)}.`)}};#l=async(e,t)=>{if(e.size===0)return;const i=Array.from(e).map(r=>{const[n,c]=r.split(":");return{key:n,version:c}}),o=Array.from(new Set(i.map(({key:r})=>r))),s=i.map(({key:r,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:r},{field:"version",operator:"equal",value:n}]}));await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:s},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:t}]})};#f=async()=>{const e=await this.#t.getAllOutdated(a.ENTITY_DEFINITION);if(!e||e.length===0)return;const t=await this.#i.getEntities({paginationParams:{limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:e.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}}});!t||t.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:t.items.map(({key:i})=>i)}),await this.#t.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:l.OUTDATED}]}))}}export{v as FsEntitiesExtractor};
@@ -1 +1 @@
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
+ import{sha1 as A}from"../../utils/crypto/sha1.js";import{isValidSanitizedString as T}from"../../utils/validate-and-sanitize-string";import{CatalogEntitiesService as w}from"./database/catalog-entities-service.js";import{createPaginationParamsValidator as I}from"../../providers/database/pagination/schemas";import{parseSearch as D}from"../../providers/database/pagination/search";import{OPERATORS as E}from"../../providers/database/pagination/constants.js";import{CacheService as R}from"../../persistence/cache/services/cache-service.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as F,CATALOG_FILTERS_CACHE_TTL_IN_SECONDS as P}from"../../constants/plugins/catalog-entities.js";import{isValidIsoDate as N}from"../../utils/is-valid-iso-date.js";import{expandTeamsForRead as V}from"../../utils";import{getNotAccessibleCatalogResources as _}from"./utils/get-not-accessible-catalog-resources.js";const it={all:"all",domains:"domain",services:"service",teams:"team",users:"user","api-descriptions":"api-description","data-schemas":"data-schema"},L={team:{field:"type",operator:"equal",value:"user"},"api-description":{field:"type",operator:"equal",value:"api-operation"}},O=async({entitiesTypes:e,serverOutDir:a,catalogConfig:i,queries:t={},rbacTeams:n,excludedTypes:p,excludedEntities:c})=>{const u=await w.getInstance({baseDbDir:a}),f=B.concat("domains","owners"),l=I(f).parse(t),o=i.excludes?.map(s=>s.key)??[],g=e.filter(s=>s!=="all"),m=W(g,o);return l.filter?l.filter={op:E.AND,conditions:[l.filter,m]}:l.filter=m,await u.getEntitiesWithRelations({paginationParams:{sort:[{field:"type",order:"ASC"}],limit:10,...l},rbacTeams:n,excludedTypes:p,excludedEntities:c})},M=async({entityKey:e,serverOutDir:a,queries:i,rbacTeams:t,excludedTypes:n,excludedEntities:p})=>{const c=await w.getInstance({baseDbDir:a});let u=null;const f=i?.revision;f&&N(f)&&(u=f);const l=i?.version;if(!T(l,{pattern:/^[a-zA-Z0-9._-]+$/,maxLength:100,allowEmpty:!0}))return null;const o=await c.getEntityWithRelationsByKey({entityKey:e,filter:{revision:u,version:l},rbacTeams:t,excludedTypes:n,excludedEntities:p});if(!o)return null;const g=o.type==="data-schema"?await c.getRelatedEntities({entityKey:e,paginationParams:{limit:1,filter:{field:"type",operator:"equal",value:"api-description"}}}).then(h=>h.items?.[0]??null):null,m=L[o.type]??void 0,d=j(m,l,u),s=await c.getRelatedEntities({entityKey:e,paginationParams:{limit:10,sort:[{field:"title",order:"ASC"}],filter:d,search:i?.search?D(i?.search,["key","type","title","summary"]):void 0},rbacTeams:t,excludedTypes:n,excludedEntities:p});return{status:"success",entity:o,relatedEntity:g,relations:s}},k=e=>{const a=JSON.stringify({entitiesTypes:e.entitiesTypes.sort(),filtersConfig:e.filtersConfig,rbacTeams:e.rbacTeams,excludedTypes:e.excludedTypes,excludedEntities:e.excludedEntities});return A(a)},q=async({serverOutDir:e,entitiesTypes:a,filtersConfig:i,rbacTeams:t,excludedTypes:n,excludedEntities:p})=>{if(!i||i.length===0)return{};const c=k({entitiesTypes:a,filtersConfig:i,rbacTeams:t,excludedTypes:n,excludedEntities:p}),u=await R.getInstance({baseDbDir:e}),f=await u.get({key:c,namespace:F});if(f)return f;const l=await w.getInstance({baseDbDir:e}),o=[],g=new Map;for(const s of i)!s.options||s.options.length===0?o.push(s.property):g.set(s.property,s.options);const m=await l.getCatalogFilters({entitiesTypes:a,emptyFilters:o,rbacTeams:t,excludedTypes:n,excludedEntities:p}),d={};for(const s of i){const h=g.get(s.property);if(!h){const r=m[s.property];d[s.property]=r&&r.length>0?r:[];continue}const b=(await l.getCatalogFilters({entitiesTypes:a,emptyFilters:[s.property],rbacTeams:t,excludedTypes:n,excludedEntities:p}))[s.property];if(!b){d[s.property]=[];continue}const v=new Map;for(const r of b){const y=r.value.toLowerCase().trim();v.set(y,{originalValue:r.value,count:r.count})}d[s.property]=h.map(r=>{const y=r.toLowerCase().trim(),S=v.get(y);return{value:S?.originalValue??r,count:S?.count??0}}).filter(r=>r.count>0).sort((r,y)=>r.value.localeCompare(y.value))}return await u.set({key:c,value:d,namespace:F,ttlInSeconds:P}),d},x=async(e,{props:a},{variables:i},{serverOutDir:t,getRouteSharedDataByFsPath:n,getConfig:p})=>{const c=a?.catalogConfig||{};if(!e.params||!a?.catalogConfig)return{status:"notFound"};const[u,f,l]=e.params;if(!u)return{status:"notFound"};const o=K(c,u),g=o?.includes?.map(y=>y.type)??[];if(!o||o.hide)return{status:"notFound"};const m=V(p().rbac||{},i?.rbac.teams||[]),{catalogs:d,types:s,entities:h}=_({rbacConfig:p().rbac||{},currentRbacTeams:i?.rbac.teams||[]});if(d.includes(u))return{status:"notFound"};if(!l&&f!=="entities"){const y=await q({entitiesTypes:g,serverOutDir:t,filtersConfig:o.filters,rbacTeams:m,excludedTypes:s,excludedEntities:h}),S=e.queries?.viewMode??"table";return{status:"success",catalogSwitcherItems:z(c,o,d),entitiesTypes:g,entities:await O({entitiesTypes:g,serverOutDir:t,catalogConfig:o,queries:e.queries,rbacTeams:m,excludedTypes:s,excludedEntities:h}),catalogConfig:o,filters:y,initialViewMode:S}}const C=await M({entityKey:l,serverOutDir:t,queries:e.queries,rbacTeams:m,excludedTypes:s,excludedEntities:h});if(!C)return{status:"notFound"};const b=C?.entity.sourceFile,v=C?.entity.type==="api-description",r=b&&v&&n(b)||{};return{status:"success",entity:C.entity,relatedEntity:C.relatedEntity,relations:C.relations,entitiesCatalogConfig:c,catalogConfig:o,sharedDataIds:r}},K=(e,a)=>Object.values(e.catalogs??{}).find(i=>i&&typeof i=="object"&&"slug"in i&&i.slug===a),z=(e,a,i)=>Object.values(e.catalogs??{}).filter(t=>!t?.hide&&!i.includes(t?.slug??"")).map(t=>({labelTranslationKey:t?.catalogSwitcherLabelTranslationKey??t?.slug??"",slug:t?.slug??"",selected:t?.slug===a.slug})).sort((t,n)=>t.slug.localeCompare(n.slug)),W=(e,a)=>({op:"AND",conditions:[...e.length?[{field:"type",operator:"in",value:e}]:[],...a.length?[{field:"key",operator:"in",value:a,modifier:"not"}]:[]]}),j=(e,a,i)=>{let t=e;if(a!==void 0){const n={field:"version",operator:"equal",value:a};t=t?{op:E.AND,conditions:[t,n]}:n}if(i){const n={field:"revision",operator:"equal",value:i};t=t?{op:E.AND,conditions:[t,n]}:n}return t},B=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"];var st=x;export{st as default};
@@ -0,0 +1,11 @@
1
+ import type { REDOCLY_TEAMS_RBAC } from '@redocly/config';
2
+ import type { OpenAPIOperation, OpenAPISchema } from '@redocly/openapi-docs';
3
+ export type RedoclyOpenAPISchema = OpenAPISchema & {
4
+ [REDOCLY_TEAMS_RBAC]?: Record<string, string>;
5
+ 'x-rbac'?: Record<string, string>;
6
+ };
7
+ export type RedoclyOpenapiOperation = OpenAPIOperation & {
8
+ [REDOCLY_TEAMS_RBAC]?: Record<string, string>;
9
+ 'x-rbac'?: Record<string, string>;
10
+ };
11
+ //# sourceMappingURL=openapi.d.ts.map
@@ -0,0 +1,6 @@
1
+ export type GetEntityByIdParams = {
2
+ rbacTeams?: string[];
3
+ excludedTypes?: string[];
4
+ excludedEntities?: string[];
5
+ };
6
+ //# sourceMappingURL=params.d.ts.map
@@ -1 +1 @@
1
- const i="error";class n{#t=new Set;#e;#s;#i=0;#o=0;addExtractor(t){this.#t.add(t)}increaseSkippedFilesCount(){this.#i++}increaseProcessedFilesCount(){this.#o++}async getCatalogEntitiesData(t){this.#e=this.#a(t),this.#s=this.#n(t);const[s,e]=await Promise.allSettled([this.#e,this.#s]);return{totalEntitiesCount:s.status==="fulfilled"?s.value:i,countOfEntitiesByType:e.status==="fulfilled"?e.value:i,extractors:Array.from(this.#t),totalFilesSkippedByHash:this.#i,totalProcessedFiles:this.#o}}async#a(t){return(await t.getEntities({limit:1,filter:{field:"is_deleted",operator:"equal",value:!1}})).page.total}async#n(t){return(await t.getEntitiesCountByTypes()).reduce((e,{type:o,count:a})=>(e[o]=a,e),{})}}const r=new n;export{n as CatalogDataCollector,r as catalogDataCollector};
1
+ const i="error";class n{#t=new Set;#e;#s;#i=0;#a=0;addExtractor(t){this.#t.add(t)}increaseSkippedFilesCount(){this.#i++}increaseProcessedFilesCount(){this.#a++}async getCatalogEntitiesData(t){this.#e=this.#o(t),this.#s=this.#n(t);const[s,e]=await Promise.allSettled([this.#e,this.#s]);return{totalEntitiesCount:s.status==="fulfilled"?s.value:i,countOfEntitiesByType:e.status==="fulfilled"?e.value:i,extractors:Array.from(this.#t),totalFilesSkippedByHash:this.#i,totalProcessedFiles:this.#a}}async#o(t){return(await t.getEntities({paginationParams:{limit:1,filter:{field:"is_deleted",operator:"equal",value:!1}}})).page.total}async#n(t){return(await t.getEntitiesCountByTypes()).reduce((e,{type:a,count:o})=>(e[a]=o,e),{})}}const r=new n;export{n as CatalogDataCollector,r as catalogDataCollector};
@@ -0,0 +1,11 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
2
+ export declare function getNotAccessibleCatalogResources({ rbacConfig, currentRbacTeams, accessLevel, }: {
3
+ rbacConfig: RedoclyConfig['rbac'];
4
+ currentRbacTeams: string[];
5
+ accessLevel?: 'READ' | 'WRITE';
6
+ }): {
7
+ catalogs: string[];
8
+ types: string[];
9
+ entities: string[];
10
+ };
11
+ //# sourceMappingURL=get-not-accessible-catalog-resources.d.ts.map
@@ -0,0 +1 @@
1
+ import{RBAC_ALL_OTHER_TEAMS as c}from"../../../../constants/common.js";const g=["read","triage","write","maintain","admin"],r=["write","maintain","admin"];function E({rbacConfig:i,currentRbacTeams:s,accessLevel:n="READ"}){const a=[],f=[],e=[];if(n==="READ")for(const[t,o]of Object.entries(i?.entitiesCatalog?.catalogs??{}))o&&(l(o,s,n)||a.push(t));for(const[t,o]of Object.entries(i?.entitiesCatalog?.entitiesTypes??{}))o&&(l(o,s,n)||f.push(t));i?.entitiesCatalog?.entitiesGroups?.forEach(t=>{l(t.config,s,n)||e.push(...t.entities??[])});for(const[t,o]of Object.entries(i?.entitiesCatalog?.entities??{}))o&&(l(o,s,n)||e.push(t));return{catalogs:[...new Set(a)],types:[...new Set(f)],entities:[...new Set(e)]}}function l(i,s,n){const a=i[c],f=n==="WRITE"?r:g,e=[];for(const t of s)i[t]?e.push(i[t]):a&&e.push(a);return e.length>0&&e.some(t=>f.includes(t.toLowerCase()))}export{E as getNotAccessibleCatalogResources};
@@ -1 +1 @@
1
- import y from"path";import{REDOCLY_ROUTE_RBAC as n,REDOCLY_TEAMS_RBAC as b}from"@redocly/config";import{deepMerge as h}from"../../../utils/object/deep-merge.js";import{buildWildcardRedirectsTree as R}from"../../utils/redirects/build-wildcard-redirects-tree.js";import{formatCustomScripts as m,formatCustomLinks as C}from"./format-custom-tags.js";import{applyL10nToRbacConfig as S,resolveDirectoryHashes as D}from"../../utils/rbac.js";import{copySeoAssets as P}from"./copy-seo-assets.js";import{normalizeRedirectSources as T}from"./normalize-redirect-sources.js";import{applyL10nToRedirects as v}from"./apply-l10n-to-redirects.js";import{DEFAULT_LOADERS as A}from"./loaders/index.js";import{resolveSearchFacets as L}from"./resolve-search-facets.js";import{telemetryTraceStep as w}from"../../../cli/telemetry/helpers/trace-step.js";async function U(){return{id:"Config Parser",loaders:A,async processContent(o,{getConfig:c,fs:i}){await w("build.plugin.config_parser",async t=>{const{contentDir:e,setGlobalConfig:s,setGlobalData:f}=o,r=await c(),a={outdir:o.outdir,contentDir:e},p=await m(r.scripts?.head,a),g=await C(r.links,a),u=await m(r.scripts?.body,a),d=h(r,{headScriptTags:p,linkTags:g,postBodyScriptTags:u});t?.setAttribute("config",JSON.stringify(d));const l=r.redirects?T(r.redirects):{};s({...d,requiresLogin:!!r.requiresLogin,rbac:S(i,r.rbac||{}),directoryPaths:await D(i,r.rbac),seo:r.seo&&await P(r.seo,a.contentDir,a.outdir),redirects:v(l,r.l10n),wildcardRedirectsTree:R(l)}),L(r.search?.filters?.facets||[],o.getSearchFacets,o.setSearchFacets),f({removeAttribution:!!r.removeAttribution})})},async afterRoutesCreated(o){const c=o.getGlobalConfig("rbac"),i=o.getGlobalConfig("directoryPaths");if(!(!c||Object.keys(c).length===0))for(const t of o.getAllRoutes()){if(t.versions&&i)for(const e of t.versions){const s=i[e.folderId],r=s==="."||s==="/"?"":s;e[n]={slug:e.link,fsPath:y.posix.join(r,"@"+e.version,"index.md")}}t[n]||t[b]||(t[n]={slug:t.slug,fsPath:t.fsPath})}}}}export{U as configParserPlugin};
1
+ import R from"path";import{REDOCLY_ROUTE_RBAC as l,REDOCLY_TEAMS_RBAC as m}from"@redocly/config";import{deepMerge as C}from"../../../utils/object/deep-merge.js";import{buildWildcardRedirectsTree as S}from"../../utils/redirects/build-wildcard-redirects-tree.js";import{formatCustomScripts as g,formatCustomLinks as D}from"./format-custom-tags.js";import{applyL10nToRbacConfig as P,resolveDirectoryHashes as T}from"../../utils/rbac.js";import{copySeoAssets as v}from"./copy-seo-assets.js";import{normalizeRedirectSources as A}from"./normalize-redirect-sources.js";import{applyL10nToRedirects as L}from"./apply-l10n-to-redirects.js";import{DEFAULT_LOADERS as w}from"./loaders/index.js";import{resolveSearchFacets as O}from"./resolve-search-facets.js";import{telemetryTraceStep as E}from"../../../cli/telemetry/helpers/trace-step.js";async function H(){return{id:"Config Parser",loaders:w,async processContent(t,{getConfig:n,fs:i}){await E("build.plugin.config_parser",async o=>{const{contentDir:e,setGlobalConfig:a,setGlobalData:d}=t,r=await n(),c={outdir:t.outdir,contentDir:e},u=await g(r.scripts?.head,c),b=await D(r.links,c),y=await g(r.scripts?.body,c),f=C(r,{headScriptTags:u,linkTags:b,postBodyScriptTags:y});o?.setAttribute("config",JSON.stringify(f));const p=r.redirects?A(r.redirects):{},h=f.banner?.map(s=>typeof s=="object"&&s!==null&&s.rbac?{...s,[m]:s.rbac}:s);a({...f,banner:h,requiresLogin:!!r.requiresLogin,rbac:P(i,r.rbac||{}),directoryPaths:await T(i,r.rbac),seo:r.seo&&await v(r.seo,c.contentDir,c.outdir),redirects:L(p,r.l10n),wildcardRedirectsTree:S(p)}),O(r.search?.filters?.facets||[],t.getSearchFacets,t.setSearchFacets),d({removeAttribution:!!r.removeAttribution})})},async afterRoutesCreated(t){const n=t.getGlobalConfig("rbac"),i=t.getGlobalConfig("directoryPaths");if(!(!n||Object.keys(n).length===0))for(const o of t.getAllRoutes()){if(o.versions&&i)for(const e of o.versions){const a=i[e.folderId],r=a==="."||a==="/"?"":a;e[l]={slug:e.link,fsPath:R.posix.join(r,"@"+e.version,"index.md")}}o[l]||o[m]||(o[l]={slug:o.slug,fsPath:o.fsPath})}}}}export{H as configParserPlugin};
@@ -1 +1 @@
1
- import A from"path";import{REDOCLY_TEAMS_RBAC as m,REDOCLY_ROUTE_RBAC as y}from"@redocly/config";import{removeTrailingSlash as R}from"../../../utils/url/remove-trailing-slash.js";import{addLeadingSlash as S}from"../../../utils/url/add-leading-slash.js";import{resolveFrontmatterKeys as P}from"../resolve-frontmatter-keys.js";import{resolveItem as T}from"../nav-utils.js";const C=new WeakMap;async function _(l,i,s,e,a){const o=await s.getConfig(),{ast:d,compoundHash:n,info:c}=await a.parseMarkdoc(l,s),g={...o.markdown?.editPage,...e.markdown?.editPage},t=i.fsPath!=null?s.fs.getFileInfo(i.fsPath):null,f=!g?.hide&&g?.baseUrl?{to:R(g.baseUrl)+S(t?.realRelativePath||i.fsPath||"")}:void 0,k={...o.feedback,...e.feedback},u=e.feedback?{type:k.type||"sentiment",settings:k.settings||{},hide:e.feedback?.hide}:void 0;let w=C.get(d),r=w?.ast;(!r||w?.compoundHash!==n)&&(r=JSON.stringify(d),C.set(d,{ast:r,compoundHash:n}));let h;e.navigation&&(h={...e.navigation,nextButton:await L(e.navigation.nextButton,i,a,s),previousButton:await L(e.navigation.previousButton,i,a,s)});const p=e?.seo?await P(e.seo,["image"],i.fsPath||"",a,s):void 0,v=c.tagList;Array.isArray(v)&&v.includes("code-walkthrough")&&(e.markdown=e.markdown||{},e.markdown.toc={hide:!0},e.footer=e.footer||{},e.footer={hide:!0});const b=e?.seo?.title||await i.getNavText?.();return{ast:r,frontmatter:await P({...e,...u!==void 0?{feedback:u}:{},...p!==void 0?{seo:p}:{},...h!==void 0?{navigation:h}:{}},o.markdown?.frontMatterKeysToResolve||["image","links"],i.fsPath||"",a,s),editPage:f,props:{metadata:{markdoc:{tagList:c.tagList}},seo:{...p,...b?{title:b}:{}}},[m]:i[m],[y]:i[y]}}async function L(l,i,s,e){if(!l||typeof l!="object")return;let a=l,o,d;if("page"in a&&typeof a.page=="string"){const{page:t,...f}=a;a=f,o=t}if("label"in a&&typeof a.label=="string"){const{label:t,...f}=a;a=f,d=t}let n;if(o){const t=await T({page:o},i.fsPath?A.dirname(i.fsPath):".",s,e,{navFile:i.fsPath||""});n=Array.isArray(t)?t[0]:t,n=n?.type!=="error"?n:void 0}const c=n?.routeSlug,g=d??n?.label;return{...a,label:g,link:c}}export{_ as markdownStaticDataLoader};
1
+ import R from"path";import{REDOCLY_TEAMS_RBAC as b,REDOCLY_ROUTE_RBAC as C}from"@redocly/config";import{removeTrailingSlash as S}from"../../../utils/url/remove-trailing-slash.js";import{addLeadingSlash as T}from"../../../utils/url/add-leading-slash.js";import{resolveFrontmatterKeys as m}from"../resolve-frontmatter-keys.js";import{resolveItem as B}from"../nav-utils.js";const A=new WeakMap;async function F(l,i,s,e,a){const d=await s.getConfig(),{ast:t,compoundHash:n,info:c}=await a.parseMarkdoc(l,s),g={...d.markdown?.editPage,...e.markdown?.editPage},o=i.fsPath!=null?s.fs.getFileInfo(i.fsPath):null,f=!g?.hide&&g?.baseUrl?{to:S(g.baseUrl)+T(o?.realRelativePath||i.fsPath||"")}:void 0,u={...d.feedback,...e.feedback},w=e.feedback?{type:u.type||"sentiment",settings:u.settings||{},hide:e.feedback?.hide}:void 0;Array.isArray(e.banner)&&(e.banner=e.banner.map(r=>r&&r.rbac?{...r,[b]:r.rbac}:r));let v=A.get(t),h=v?.ast;(!h||v?.compoundHash!==n)&&(h=JSON.stringify(t),A.set(t,{ast:h,compoundHash:n}));let p;e.navigation&&(p={...e.navigation,nextButton:await L(e.navigation.nextButton,i,a,s),previousButton:await L(e.navigation.previousButton,i,a,s)});const k=e?.seo?await m(e.seo,["image"],i.fsPath||"",a,s):void 0,y=c.tagList;Array.isArray(y)&&y.includes("code-walkthrough")&&(e.markdown=e.markdown||{},e.markdown.toc={hide:!0},e.footer=e.footer||{},e.footer={hide:!0});const P=e?.seo?.title||await i.getNavText?.();return{ast:h,frontmatter:await m({...e,...w!==void 0?{feedback:w}:{},...k!==void 0?{seo:k}:{},...p!==void 0?{navigation:p}:{}},d.markdown?.frontMatterKeysToResolve||["image","links"],i.fsPath||"",a,s),editPage:f,props:{metadata:{markdoc:{tagList:c.tagList}},seo:{...k,...P?{title:P}:{}}},[b]:i[b],[C]:i[C]}}async function L(l,i,s,e){if(!l||typeof l!="object")return;let a=l,d,t;if("page"in a&&typeof a.page=="string"){const{page:o,...f}=a;a=f,d=o}if("label"in a&&typeof a.label=="string"){const{label:o,...f}=a;a=f,t=o}let n;if(d){const o=await B({page:d},i.fsPath?R.dirname(i.fsPath):".",s,e,{navFile:i.fsPath||""});n=Array.isArray(o)?o[0]:o,n=n?.type!=="error"?n:void 0}const c=n?.routeSlug,g=t??n?.label;return{...a,label:g,link:c}}export{F as markdownStaticDataLoader};
@@ -1 +1 @@
1
- import{telemetry as i}from"../../../../telemetry/index.js";import{mcpToolWorkers as n,MCP_TOOL_WORKER_KEY as a}from"../../../../workers/mcp-tool-worker-pool.js";import{findApiDescriptionByName as p}from"../utils.js";import{getApiDescriptionFromFs as u}from"./utils.js";function f(o,t,s){return{toolName:o,args:t,context:s}}class g{schema;constructor(t){this.schema=t}getContext(t){const s={};for(const e of this.requiredContext)s[e]=t[e];return{...s,apiDescriptionsMap:t.apiDescriptionsMap}}register(t){const s=async(e,r)=>{const c=f(this.name,e,this.getContext(t));return await n.exec(a,[c],{timeout:6e4})};t.server.tool(this.name,this.description,this.schema,s)}async execute(t,s){try{const e=await this.executeAction(t,s);return i.sendMcpToolCalledMessage({server_type:"docs",tool:this.name}),e}catch(e){throw i.sendMcpErrorMessage({server_type:"docs",tool:this.name,message:e instanceof Error?e.message:String(e),stack:e instanceof Error&&e.stack||""}),e}}async getApiDefinition(t,s){if(!s.outdir||!s.accessInfo)throw new Error("Missing required context: outdir and accessInfo");const e=p(s.apiDescriptionsMap,t);if(!e)return{success:!1,response:{content:[{type:"text",text:`No API found matching "${t}".`}]}};const r=await u({relativePath:e.relativePath||"",outdir:s.outdir,accessInfo:s.accessInfo});return r?{success:!0,definition:r}:{success:!1,response:{content:[{type:"text",text:`Spec not found from the file system with "${t}".`}]}}}}export{g as DocsMcpTool};
1
+ import{telemetry as i}from"../../../../telemetry/index.js";import{mcpToolWorkers as n,MCP_TOOL_WORKER_KEY as a}from"../../../../workers/mcp-tool-worker-pool.js";import{findApiDescriptionByName as p}from"../utils.js";import{getApiDescriptionFromFs as u}from"./utils.js";function f(o,t,s){return{toolName:o,args:t,context:s}}class g{schema;constructor(t){this.schema=t}getContext(t){const s={};for(const e of this.requiredContext)s[e]=t[e];return{...s,apiDescriptionsMap:t.apiDescriptionsMap}}register(t){const s=async(e,r)=>{const c=f(this.name,e,this.getContext(t));return await n.exec(a,[c],{timeout:6e4})};t.server.tool(this.name,this.description,this.schema,s)}async execute(t,s){try{const e=await this.executeAction(t,s);return i.sendMcpToolCalledMessage([{object:"mcp_server",server_type:"docs",tool:this.name}]),e}catch(e){throw i.sendMcpErrorMessage([{object:"mcp_server",server_type:"docs",tool:this.name,message:e instanceof Error?e.message:String(e),stack:e instanceof Error&&e.stack||""}]),e}}async getApiDefinition(t,s){if(!s.outdir||!s.accessInfo)throw new Error("Missing required context: outdir and accessInfo");const e=p(s.apiDescriptionsMap,t);if(!e)return{success:!1,response:{content:[{type:"text",text:`No API found matching "${t}".`}]}};const r=await u({relativePath:e.relativePath||"",outdir:s.outdir,accessInfo:s.accessInfo});return r?{success:!0,definition:r}:{success:!1,response:{content:[{type:"text",text:`Spec not found from the file system with "${t}".`}]}}}}export{g as DocsMcpTool};
@@ -1 +1 @@
1
- import{resolveParameters as T,resolveRequestBody as y,resolveResponses as P}from"../utils.js";import{isMcpEndpoint as g}from"./utils.js";import{DocsMcpTool as x}from"./docs-mcp-tool.js";import{checkEndpointAndDeleteXMcp as v}from"../../utils/xmcp-utils.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],S={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p,...p.map(r=>r.toLowerCase())],minLength:1}}};class D extends x{name="get-endpoint-info";description="Get comprehensive information about specific endpoint including parameters, security, and examples";requiredContext=["outdir","accessInfo"];constructor(){super(S)}async executeAction(a,c){const{name:d,path:o,method:i}=a,n=await this.getApiDefinition(d,c);if(!n.success)return n.response;const{definition:e}=n,m=o.startsWith("/")?o:`/${o}`,{title:u=""}=e.info||{},s=e.paths?.[m],h=i.toLowerCase();if(!s)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const t=s[h];if(!g(t)||!v(t,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const f=s?.parameters||[],l=t.parameters||[],E={...t,parameters:T({pathParams:f,opParams:l,definition:e}),requestBody:y(t.requestBody,e),responses:P(t.responses,e)};return{content:[{type:"text",text:JSON.stringify({api:u,version:e.info?.version||"",servers:e.servers||[],endpoint:{path:o,method:i.toUpperCase(),...E},globalSecurity:e.security||[],securitySchemes:e.components?.securitySchemes||[]},null,2)}]}}}export{D as GetEndpointInfoTool};
1
+ import{resolveParameters as T,resolveRequestBody as y,resolveResponses as P}from"../utils.js";import{isMcpEndpoint as g}from"./utils.js";import{DocsMcpTool as x}from"./docs-mcp-tool.js";import{checkEndpointAndDeleteXMcp as v}from"../../utils/xmcp-utils.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],S={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p,...p.map(r=>r.toLowerCase())],minLength:1}}};class D extends x{name="get-endpoint-info";description="Get comprehensive information about specific endpoint including parameters, security, and examples";requiredContext=["outdir","accessInfo"];constructor(){super(S)}async executeAction(c,a){const{name:d,path:o,method:i}=c,n=await this.getApiDefinition(d,a);if(!n.success)return n.response;const{definition:e}=n,m=o.startsWith("/")?o:`/${o}`,{title:u=""}=e.info||{},s=e.paths?.[m],h=i.toLowerCase();if(!s)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const t=s[h];if(!g(t)||!v(t,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const l=s?.parameters||[],E=t.parameters||[],f={...t,parameters:T({pathParams:l,opParams:E,definition:e}),requestBody:y(t.requestBody,e),responses:P(t.responses,e)};return{content:[{type:"text",text:JSON.stringify({api:u,version:e.info?.version||"",servers:e.servers||[],endpoint:{path:o,method:i.toUpperCase(),...f},globalSecurity:e.security||[],securitySchemes:e.components?.securitySchemes||[]},null,2)}]}}}export{D as GetEndpointInfoTool};
@@ -1 +1 @@
1
- import{DocsMcpTool as r}from"./docs-mcp-tool.js";import{getEndpointsFromPaths as p}from"./utils.js";const c={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class u extends r{name="get-endpoints";description="Get all endpoints for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(c)}async executeAction(o,i){const{name:s}=o,e=await this.getApiDefinition(s,i);if(!e.success)return e.response;const{definition:t}=e,n=p(t);return n.length===0?{content:[{type:"text",text:"No endpoints found"}]}:{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",servers:t.servers||[],endpoints:n},null,2)}]}}}export{u as GetEndpointsTool};
1
+ import{DocsMcpTool as r}from"./docs-mcp-tool.js";import{getEndpointsFromPaths as c}from"./utils.js";const p={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}};class u extends r{name="get-endpoints";description="Get all endpoints for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(p)}async executeAction(o,i){const{name:s}=o,t=await this.getApiDefinition(s,i);if(!t.success)return t.response;const{definition:e}=t,n=c(e);return n.length===0?{content:[{type:"text",text:"No endpoints found"}]}:{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",servers:e.servers||[],endpoints:n},null,2)}]}}}export{u as GetEndpointsTool};
@@ -1 +1 @@
1
- import{DocsMcpTool as r}from"./docs-mcp-tool.js";const s={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class a extends r{name="get-full-api-description";description="Get the complete OpenAPI description";requiredContext=["outdir","accessInfo"];constructor(){super(s)}async executeAction(i,n){const{name:o}=i,e=await this.getApiDefinition(o,n);if(!e.success)return e.response;const{definition:t}=e;return{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",definition:t},null,2)}]}}}export{a as GetFullApiDescriptionTool};
1
+ import{DocsMcpTool as s}from"./docs-mcp-tool.js";const r={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}};class a extends s{name="get-full-api-description";description="Get the complete OpenAPI description";requiredContext=["outdir","accessInfo"];constructor(){super(r)}async executeAction(i,n){const{name:o}=i,e=await this.getApiDefinition(o,n);if(!e.success)return e.response;const{definition:t}=e;return{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",definition:t},null,2)}]}}}export{a as GetFullApiDescriptionTool};
@@ -1 +1 @@
1
- import{DocsMcpTool as o}from"./docs-mcp-tool.js";const r={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class p extends o{name="get-security-schemes";description="Get the security schemes for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(r)}async executeAction(s,i){const{name:n}=s,t=await this.getApiDefinition(n,i);if(!t.success)return t.response;const{definition:e}=t;return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||[],security:e.security||[]},null,2)}]}}}export{p as GetSecuritySchemesTool};
1
+ import{DocsMcpTool as c}from"./docs-mcp-tool.js";const o={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1}}};class p extends c{name="get-security-schemes";description="Get the security schemes for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(o)}async executeAction(s,i){const{name:n}=s,t=await this.getApiDefinition(n,i);if(!t.success)return t.response;const{definition:e}=t;return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||[],security:e.security||[]},null,2)}]}}}export{p as GetSecuritySchemesTool};
@@ -1 +1 @@
1
- import{createMcpRequestHandler as D}from"./mcp-request-handler.js";import{createDocsMcpServer as v}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as h}from"../utils.js";import{createInternalServerError as y}from"./errors.js";import{McpServerType as m}from"../constants.js";import{telemetry as f}from"../../../telemetry/index.js";import{constructInvalidTokenResponse as A,constructUnauthorizedResponse as L,handleMcpAuth as S,shouldHandleMcpAuth as b}from"../auth/auth-handlers.js";async function I(r,s,i,n){try{f.initialize();const e=s,t=e?.props?.config?.apiDescriptionsMap||{},a=e?.props?.outdir||"",o=e?.props?.config?.mcpDocsServerName||"Docs MCP server",u=new URL(n.url).origin,{user:c,config:{rbac:p={},mcp:l={}}}=r,d=h(t,c,p,r.config.requiresLogin||!1),g=l.docs?.name||o,M={rbac:p,email:c?.email,teams:c?.teams,isAuthenticated:!!c?.isAuthenticated,requiresLogin:r.config.requiresLogin||!1};return await v({name:g,baseUrl:u,headers:i,apiDescriptionsMap:d,outdir:a,accessInfo:M})}catch(e){throw f.sendMcpErrorMessage({server_type:m.Docs,message:e?.message||"",stack:e?.stack||""}),y(e?.message||"Internal server error mcp docs")}}const R=D({createServerInstance:I,serverType:m.Docs}),w=async(r,s,i)=>{const n=!!s?.config?.requiresLogin,e=s?.config?.rbac;if(b(n,e)){const{isAuthenticated:t,isTokenValid:a,currentUser:o}=await S(r,s);if(!t)return L(new URL(r.url).origin);if(!a)return A();o&&(s.user=o)}return R(r,s,i)};var E=w;export{E as default};
1
+ import{createMcpRequestHandler as v}from"./mcp-request-handler.js";import{createDocsMcpServer as D}from"../servers/docs-server.js";import{filterApiDescriptionsByRbac as h}from"../utils.js";import{createInternalServerError as y}from"./errors.js";import{McpServerType as m}from"../constants.js";import{telemetry as f}from"../../../telemetry/index.js";import{constructInvalidTokenResponse as b,constructUnauthorizedResponse as A,handleMcpAuth as L,shouldHandleMcpAuth as S}from"../auth/auth-handlers.js";async function I(r,s,i,n){try{f.initialize();const e=s,t=e?.props?.config?.apiDescriptionsMap||{},a=e?.props?.outdir||"",o=e?.props?.config?.mcpDocsServerName||"Docs MCP server",u=new URL(n.url).origin,{user:c,config:{rbac:p={},mcp:l={}}}=r,d=h(t,c,p,r.config.requiresLogin||!1),g=l.docs?.name||o,M={rbac:p,email:c?.email,teams:c?.teams,isAuthenticated:!!c?.isAuthenticated,requiresLogin:r.config.requiresLogin||!1};return await D({name:g,baseUrl:u,headers:i,apiDescriptionsMap:d,outdir:a,accessInfo:M})}catch(e){throw f.sendMcpErrorMessage([{object:"mcp_server",server_type:m.Docs,message:e?.message||"",stack:e?.stack||""}]),y(e?.message||"Internal server error mcp docs")}}const R=v({createServerInstance:I,serverType:m.Docs}),w=async(r,s,i)=>{const n=!!s?.config?.requiresLogin,e=s?.config?.rbac;if(S(n,e)){const{isAuthenticated:t,isTokenValid:a,currentUser:o}=await L(r,s);if(!t)return A(new URL(r.url).origin);if(!a)return b();o&&(s.user=o)}return R(r,s,i)};var E=w;export{E as default};
@@ -1 +1 @@
1
- import{telemetry as c}from"../../../telemetry/index.js";import{McpErrorCodes as s,McpServerType as d}from"../constants.js";class n extends Error{code;data;requestId;constructor(e,t,o,a){super(t),this.name="McpError",this.code=e,this.data=o,this.requestId=a}createErrorResponse(){const e={jsonrpc:"2.0",error:{code:this.code,message:this.message,...this.data?{data:this.data}:{}},id:this.requestId??null},t=i(this.code);return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}}function i(r){switch(r){case s.InvalidRequest:case s.InvalidParams:return 400;case s.MethodNotFound:return 404;case s.ServerError:return 405;case s.InternalError:default:return 500}}function m(r){return new n(s.ServerError,"Method not allowed",void 0,r).createErrorResponse()}function u(r,e=d.Docs,t){const o=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;return c.sendMcpErrorMessage({server_type:e,message:o,stack:a||""}),new n(s.InternalError,"Internal server error mcp",o,t).createErrorResponse()}function f(r="Invalid request",e){return new n(s.InvalidRequest,r,void 0,e).createErrorResponse()}function h(r="Invalid parameters",e){return new n(s.InvalidParams,r,void 0,e).createErrorResponse()}async function v(r,e,t){try{return await r()}catch(o){return c.sendMcpErrorMessage({server_type:e,message:o?.message||"",stack:o?.stack||""}),t&&t(),u(o,e)}}export{n as McpError,u as createInternalServerError,h as createInvalidParamsError,f as createInvalidRequestError,m as createMethodNotAllowedError,v as withErrorHandling};
1
+ import{telemetry as c}from"../../../telemetry/index.js";import{McpErrorCodes as s,McpServerType as d}from"../constants.js";class n extends Error{code;data;requestId;constructor(e,t,o,a){super(t),this.name="McpError",this.code=e,this.data=o,this.requestId=a}createErrorResponse(){const e={jsonrpc:"2.0",error:{code:this.code,message:this.message,...this.data?{data:this.data}:{}},id:this.requestId??null},t=i(this.code);return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}}function i(r){switch(r){case s.InvalidRequest:case s.InvalidParams:return 400;case s.MethodNotFound:return 404;case s.ServerError:return 405;case s.InternalError:default:return 500}}function m(r){return new n(s.ServerError,"Method not allowed",void 0,r).createErrorResponse()}function p(r,e=d.Docs,t){const o=r instanceof Error?r.message:String(r),a=r instanceof Error?r.stack:void 0;return c.sendMcpErrorMessage([{object:"mcp_server",server_type:e,message:o,stack:a||""}]),new n(s.InternalError,"Internal server error mcp",o,t).createErrorResponse()}function f(r="Invalid request",e){return new n(s.InvalidRequest,r,void 0,e).createErrorResponse()}function h(r="Invalid parameters",e){return new n(s.InvalidParams,r,void 0,e).createErrorResponse()}async function v(r,e,t){try{return await r()}catch(o){return c.sendMcpErrorMessage([{object:"mcp_server",server_type:e,message:o?.message||"",stack:o?.stack||""}]),t&&t(),p(o,e)}}export{n as McpError,p as createInternalServerError,h as createInvalidParamsError,f as createInvalidRequestError,m as createMethodNotAllowedError,v as withErrorHandling};
@@ -1 +1 @@
1
- import{McpServer as t}from"@redocly/mcp-typescript-sdk/server/mcp.js";import{StreamableHTTPServerTransport as s}from"@redocly/mcp-typescript-sdk/server/streamableHttp.js";import{telemetry as i}from"../../../telemetry/index.js";class p{server;transport;#r;#t=!1;constructor(e){this.server=new t(e,{capabilities:{logging:{}}}),this.transport=new s({sessionIdGenerator:void 0})}async initialize(){return this.registerTools(),await this.server.connect(this.transport),{server:this.server,transport:this.transport,cleanup:this.cleanup.bind(this)}}clearCleanupTimeout(){this.#r&&(clearTimeout(this.#r),this.#r=void 0)}#e;async cleanup(){return this.#e?this.#e:(this.#e=this.#s(),this.#e)}async#s(){if(!this.#t){this.#t=!0,this.clearCleanupTimeout();try{this.transport.close()}catch(e){throw i.sendMcpErrorMessage({server_type:this.getServerType(),message:e?.message||"Unknown cleanup error",stack:e?.stack||""}),e}}}}async function h(r,...e){return await new r(...e).initialize()}export{p as BaseMcpServer,h as createMcpServerInstance};
1
+ import{McpServer as t}from"@redocly/mcp-typescript-sdk/server/mcp.js";import{StreamableHTTPServerTransport as s}from"@redocly/mcp-typescript-sdk/server/streamableHttp.js";import{telemetry as i}from"../../../telemetry/index.js";class p{server;transport;#r;#t=!1;constructor(e){this.server=new t(e,{capabilities:{logging:{}}}),this.transport=new s({sessionIdGenerator:void 0})}async initialize(){return this.registerTools(),await this.server.connect(this.transport),{server:this.server,transport:this.transport,cleanup:this.cleanup.bind(this)}}clearCleanupTimeout(){this.#r&&(clearTimeout(this.#r),this.#r=void 0)}#e;async cleanup(){return this.#e?this.#e:(this.#e=this.#s(),this.#e)}async#s(){if(!this.#t){this.#t=!0,this.clearCleanupTimeout();try{this.transport.close()}catch(e){throw i.sendMcpErrorMessage([{object:"mcp_server",server_type:this.getServerType(),message:e?.message||"Unknown cleanup error",stack:e?.stack||""}]),e}}}}async function h(r,...e){return await new r(...e).initialize()}export{p as BaseMcpServer,h as createMcpServerInstance};
@@ -1,14 +1,18 @@
1
- import*as a from"react";import i from"styled-components";import{RedoclyOpenAPIDocs as c}from"@redocly/openapi-docs";import{LayoutVariant as s}from"@redocly/config";import{ThreePanelLayout as m}from"@redocly/theme/layouts/ThreePanelLayout";import{CatalogClassicInfoBlock as p}from"@redocly/theme/components/CatalogClassic/CatalogClassicInfoBlock";import{useUserClaims as u}from"../../../../client/app/hooks";import{usePageSharedData as d}from"../../../../client/providers/page-data/hooks";import{usePatchedStore as f}from"./helpers.js";function h({pageProps:t}){const o=u(),e=d("openAPIDocsStore"),n=a.useMemo(()=>({layout:t.apiOptions?.layout,userClaims:o}),[t.apiOptions?.layout,o]),r=f(e,t);if(!e)return"Something went wrong";const l=t.apiOptions?.layout;return a.createElement(g,null,a.createElement(v,{layout:l},a.createElement(p,{metadata:t.metadata})),a.createElement(c,{store:{options:r.options,definition:r.definition,withState:n}}))}const v=i(m)`
1
+ import*as a from"react";import i from"styled-components";import{RedoclyOpenAPIDocs as c}from"@redocly/openapi-docs";import{LayoutVariant as s}from"@redocly/config";import{ThreePanelLayout as m}from"@redocly/theme/layouts/ThreePanelLayout";import{CatalogClassicInfoBlock as p}from"@redocly/theme/components/CatalogClassic/CatalogClassicInfoBlock";import{useUserClaims as h}from"../../../../client/app/hooks";import{usePageSharedData as u}from"../../../../client/providers/page-data/hooks";import{usePatchedStore as d}from"./helpers.js";function f({pageProps:t}){const o=h(),e=u("openAPIDocsStore"),n=a.useMemo(()=>({layout:t.apiOptions?.layout,userClaims:o}),[t.apiOptions?.layout,o]),r=d(e,t);if(!e)return"Something went wrong";const l=t.apiOptions?.layout;return a.createElement(g,null,a.createElement(v,{layout:l},a.createElement(p,{metadata:t.metadata})),a.createElement(c,{store:{options:r.options,definition:r.definition,withState:n}}))}const v=i(m)`
2
2
  && {
3
3
  padding-right: ${({layout:t})=>t===s.THREE_PANEL?"calc(var(--panel-gap-horizontal) * 2)":"var(--panel-gap-horizontal)"};
4
4
  }
5
5
  `,g=i.div`
6
6
  div[id] {
7
- scroll-margin-top: calc(var(--navbar-height) - var(--panel-gap-vertical));
7
+ scroll-margin-top: calc(
8
+ var(--navbar-height) + var(--banner-height) - var(--panel-gap-vertical)
9
+ );
8
10
  }
9
11
  a[id] {
10
- scroll-margin-top: calc(var(--navbar-height) + var(--panel-gap-vertical));
12
+ scroll-margin-top: calc(
13
+ var(--navbar-height) + var(--banner-height) + var(--panel-gap-vertical)
14
+ );
11
15
  }
12
16
 
13
17
  --sidebar-width: 0px;
14
- `;export{h as default};
18
+ `;export{f as default};
@@ -13,6 +13,6 @@ export declare function joinWithSeparator(base?: string, path?: string, sep?: st
13
13
  export declare function parsePartials(partials?: Record<string, any>): Record<string, Node | Node[]> | undefined;
14
14
  export declare function usePatchedStore(storeJs: OpenAPIDocsStore, { markdown, baseSlug }: PageProps): OpenAPIDocsStore;
15
15
  export declare function safeParseFunction(fnInput: EventFunctionInput): ((event: EventType) => void) | null;
16
- export declare function mergeEvents(userFunction: ((event: EventType) => void) | null, telemetryEvent?: AsyncApiRealmUI.GetEventData<'openapi_docs'>['eventType']): (event: EventType) => void;
16
+ export declare function mergeEvents(userFunction: ((event: EventType) => void) | null, telemetryEvent?: AsyncApiRealmUI.GetEventData<'openapi_docs'>[number]['eventType']): (event: EventType) => void;
17
17
  export {};
18
18
  //# sourceMappingURL=helpers.d.ts.map
@@ -1,5 +1,5 @@
1
- import{useMemo as u}from"react";import{components as l}from"@redocly-markdoc/components";import{Ast as f}from"@markdoc/markdoc";import{PageNavigation as g}from"@redocly/theme/components/PageNavigation/PageNavigation";import{tags as d,components as h}from"@redocly/theme/markdoc/default";import{Breadcrumbs as _}from"@redocly/theme/components/Breadcrumbs/Breadcrumbs";import{withPathPrefix as m}from"@redocly/theme/core/utils";import{OPENAPI_DOCS_TEMPLATE_ID as y,ServerRoutes as w}from"../../../../constants/common.js";import{isBrowser as P}from"../../../../utils/env/is-browser.js";import*as S from"../../markdown/markdoc/custom-components/index.js";import*as v from"../../markdown/markdoc/nodes/index.js";import O from"../../markdown/markdoc/tags/index.js";import{usePageData as C,useSidebarSiblingsData as A}from"../../../../client/providers/page-data/hooks";import{telemetry as E}from"../../../../client/app/telemetry/index.js";import{getMockServerDocsConfig as T}from"./mock-server-config";function V(t="",r="",o="/"){return t.endsWith(o)&&(t=t.slice(0,-o.length)),r.startsWith(o)&&(r=r.slice(o.length)),!t||!r?t+r:t+o+r}function b(t){if(t)return Object.entries(t).reduce((r,[o,e])=>(r[o]=f.fromJSON(JSON.stringify(e)),r),{})}function Y(t,{markdown:r,baseSlug:o}){return u(()=>{const n=P();t.options.oAuth2RedirectURI=n?`${window.location.origin}${m(w.REPLAY_OAUTH2_CALLBACK)}`:null,t.options.routingBasePath=m(o),t.options.mockServer=T(t.options.mockServer,o),t.options.scrollYOffset=n?parseInt(getComputedStyle(document.documentElement).getPropertyValue("--navbar-height"),10):0,t.options.markdocOptions={tags:{...O,...d},nodes:{...v},components:{...S,...h,...l,...globalThis.__LOADER.markdocComponents},...r,partials:b(r?.partials)},t.options.unstable_hooks={...t.options.unstable_hooks,MiddlePanelFooter:()=>{const{templateId:i}=C()||{},{nextPage:s,prevPage:a}=A()||{};return i===y?null:g({nextPage:s,prevPage:a})},MiddlePanelHeader:()=>_({})};const p={codeSamplesLanguageSwitch:"samples_language_switch",codeSamplesCopy:"code_samples_copy",panelToggle:"panel_toggle",targetServerSwitch:"target_server_switch",tryItOpen:"try_it_toggle",tryItSent:"try_it_sent"},c={};for(const[i,s]of Object.entries(p)){const a=F(t.options.events?.[i]);c[i]=I(a,s)}return t.options.events=c,t},[t,r,o])}function F(t){if(typeof window>"u")return null;if(typeof t=="function")return t;if(typeof t!="string")return null;try{const r=t.trim();if(!r.match(/^(\([^)]*\)\s*=>\s*.+|[a-zA-Z_$][\w$]*\s*=>\s*.+)$/))throw new Error("Invalid function format. Only arrow functions allowed.");if(["eval","Function","constructor","prototype","__proto__","import","require","process","global","window","document"].some(n=>r.includes(n)))throw new Error("Function contains prohibited keywords");return new Function("event",`
1
+ import{useMemo as u}from"react";import{components as l}from"@redocly-markdoc/components";import{Ast as f}from"@markdoc/markdoc";import{PageNavigation as d}from"@redocly/theme/components/PageNavigation/PageNavigation";import{tags as g,components as _}from"@redocly/theme/markdoc/default";import{Breadcrumbs as h}from"@redocly/theme/components/Breadcrumbs/Breadcrumbs";import{withPathPrefix as m}from"@redocly/theme/core/utils";import{OPENAPI_DOCS_TEMPLATE_ID as y,ServerRoutes as w}from"../../../../constants/common.js";import{isBrowser as P}from"../../../../utils/env/is-browser.js";import*as S from"../../markdown/markdoc/custom-components/index.js";import*as v from"../../markdown/markdoc/nodes/index.js";import O from"../../markdown/markdoc/tags/index.js";import{usePageData as C,useSidebarSiblingsData as A}from"../../../../client/providers/page-data/hooks";import{telemetry as E}from"../../../../client/app/telemetry/index.js";import{getMockServerDocsConfig as T}from"./mock-server-config";function V(t="",e="",o="/"){return t.endsWith(o)&&(t=t.slice(0,-o.length)),e.startsWith(o)&&(e=e.slice(o.length)),!t||!e?t+e:t+o+e}function b(t){if(t)return Object.entries(t).reduce((e,[o,r])=>(e[o]=f.fromJSON(JSON.stringify(r)),e),{})}function Y(t,{markdown:e,baseSlug:o}){return u(()=>{const n=P();t.options.oAuth2RedirectURI=n?`${window.location.origin}${m(w.REPLAY_OAUTH2_CALLBACK)}`:null,t.options.routingBasePath=m(o),t.options.mockServer=T(t.options.mockServer,o),t.options.scrollYOffset=n?parseInt(getComputedStyle(document.documentElement).getPropertyValue("--navbar-height"),10):0,t.options.markdocOptions={tags:{...O,...g},nodes:{...v},components:{...S,..._,...l,...globalThis.__LOADER.markdocComponents},...e,partials:b(e?.partials)},t.options.unstable_hooks={...t.options.unstable_hooks,MiddlePanelFooter:()=>{const{templateId:i}=C()||{},{nextPage:s,prevPage:a}=A()||{};return i===y?null:d({nextPage:s,prevPage:a})},MiddlePanelHeader:()=>h({})};const p={codeSamplesLanguageSwitch:"samples_language_switch",codeSamplesCopy:"code_samples_copy",panelToggle:"panel_toggle",targetServerSwitch:"target_server_switch",tryItOpen:"try_it_toggle",tryItSent:"try_it_sent"},c={};for(const[i,s]of Object.entries(p)){const a=F(t.options.events?.[i]);c[i]=I(a,s)}return t.options.events=c,t},[t,e,o])}function F(t){if(typeof window>"u")return null;if(typeof t=="function")return t;if(typeof t!="string")return null;try{const e=t.trim();if(!e.match(/^(\([^)]*\)\s*=>\s*.+|[a-zA-Z_$][\w$]*\s*=>\s*.+)$/))throw new Error("Invalid function format. Only arrow functions allowed.");if(["eval","Function","constructor","prototype","__proto__","import","require","process","global","window","document"].some(n=>e.includes(n)))throw new Error("Function contains prohibited keywords");return new Function("event",`
2
2
  'use strict';
3
- const userFn = ${r};
3
+ const userFn = ${e};
4
4
  return userFn(event);
5
- `)}catch(r){return console.error("Function parsing error:",r),null}}function I(t,r){return o=>{if(t)try{t(o)}catch(e){console.error("User event handler error:",e)}if(r)try{E.sendOpenapiDocsMessage({eventType:r,operationHttpVerb:o.operationHttpVerb,operationPath:o.operationPath,lang:"lang"in o?o.lang:void 0,action:o.action,state:"state"in o?o.state:void 0,serverUrl:"serverUrl"in o?o.serverUrl:void 0})}catch{}}}export{V as joinWithSeparator,I as mergeEvents,b as parsePartials,F as safeParseFunction,Y as usePatchedStore};
5
+ `)}catch(e){return console.error("Function parsing error:",e),null}}function I(t,e){return o=>{if(t)try{t(o)}catch(r){console.error("User event handler error:",r)}if(e)try{E.sendOpenapiDocsMessage([{object:"openapi_docs",eventType:e,operationHttpVerb:o.operationHttpVerb,operationPath:o.operationPath,lang:"lang"in o?o.lang:void 0,action:o.action,state:"state"in o?o.state:void 0,serverUrl:"serverUrl"in o?o.serverUrl:void 0}])}catch{}}}export{V as joinWithSeparator,I as mergeEvents,b as parsePartials,F as safeParseFunction,Y as usePatchedStore};
@@ -1,9 +1,9 @@
1
1
  import type { NormalizedProblem } from '@redocly/openapi-core';
2
2
  import type { ProblemWithCodeframe } from './lint';
3
3
  export declare enum ScorecardStatus {
4
- BelowMinimum = "Below minimum",
5
- Highest = "Highest",
6
- Minimum = "Minimum"
4
+ BelowMinimum = "BELOW_MINIMUM",
5
+ Highest = "HIGHEST",
6
+ Minimum = "MINIMUM"
7
7
  }
8
8
  export type ProblemSummary = Pick<NormalizedProblem, 'ruleId' | 'severity'>;
9
9
  export type ScorecardLevel = {
@@ -1 +1 @@
1
- var m;(function(i){i.BelowMinimum="Below minimum",i.Highest="Highest",i.Minimum="Minimum"})(m||(m={}));export{m as ScorecardStatus};
1
+ var i;(function(M){M.BelowMinimum="BELOW_MINIMUM",M.Highest="HIGHEST",M.Minimum="MINIMUM"})(i||(i={}));export{i as ScorecardStatus};
@@ -1,4 +1,4 @@
1
- import a from"picomatch";import{dirname as $,resolve as x}from"node:path";import{access as E,readFile as F,constants as P}from"fs/promises";import{removeTrailingSlash as w}from"../../../../utils/url/remove-trailing-slash.js";import{logger as I}from"../../../tools/notifiers/logger.js";const l="llms.txt",u="Table of contents";async function g(e,t,n={title:l,description:void 0},o){if(!t)return{title:n.title||l,description:n.description,details:void 0,sections:[{title:u,description:void 0,llmstxts:e}]};const s=t.title||n.title||l,r=t.description||n.description,i=await y(t,o),c=t.sections?.map(d=>{const{title:f,description:h,excludeFiles:L,includeFiles:m}=d,T=p(e,{excludeFiles:L,includeFiles:m});return{title:f,description:h,llmstxts:T}});return{title:s,description:r,details:i,sections:c||[{title:u,description:void 0,llmstxts:p(e,{includeFiles:["**/*"],excludeFiles:[]})}]}}async function y(e,t){const n=await t.getConfig();if(e?.details?.path&&n.configPath)try{const o=t.fs.getFileInfo(n.configPath);if(!o)throw new Error(`Config file ${n.configPath} not found`);const s=x(t.fs.cwd,$(o.relativePath),e.details.path);return await E(s,P.R_OK),F(s,"utf-8")}catch{throw new Error(`${e.details.path} is not accessible`)}if(e?.details?.content)return e.details.content}function p(e,t){const{excludeFiles:n,includeFiles:o}=t,s=n?.map(i=>a(i)),r=o?.map(i=>a(i));return e.filter(i=>s?.some(d=>d(i.fsPath))?!1:r?.some(d=>d(i.fsPath)))}async function S(e,t,n={title:l,description:void 0},o){const s=await g(e,t,n,o),r=[`# ${s.title}
1
+ import a from"picomatch";import{dirname as $,resolve as x}from"node:path";import{access as P,readFile as E,constants as F}from"fs/promises";import{removeTrailingSlash as w}from"../../../../utils/url/remove-trailing-slash.js";import{logger as I}from"../../../tools/notifiers/logger.js";import{withPathPrefix as g}from"@redocly/theme/core/utils";const l="llms.txt",u="Table of contents";async function y(t,e,n={title:l,description:void 0},o){if(!e)return{title:n.title||l,description:n.description,details:void 0,sections:[{title:u,description:void 0,llmstxts:t}]};const s=e.title||n.title||l,r=e.description||n.description,i=await M(e,o),c=e.sections?.map(d=>{const{title:f,description:h,excludeFiles:L,includeFiles:m}=d,T=p(t,{excludeFiles:L,includeFiles:m});return{title:f,description:h,llmstxts:T}});return{title:s,description:r,details:i,sections:c||[{title:u,description:void 0,llmstxts:p(t,{includeFiles:["**/*"],excludeFiles:[]})}]}}async function M(t,e){const n=await e.getConfig();if(t?.details?.path&&n.configPath)try{const o=e.fs.getFileInfo(n.configPath);if(!o)throw new Error(`Config file ${n.configPath} not found`);const s=x(e.fs.cwd,$(o.relativePath),t.details.path);return await P(s,F.R_OK),E(s,"utf-8")}catch{throw new Error(`${t.details.path} is not accessible`)}if(t?.details?.content)return t.details.content}function p(t,e){const{excludeFiles:n,includeFiles:o}=e,s=n?.map(i=>a(i)),r=o?.map(i=>a(i));return t.filter(i=>s?.some(d=>d(i.fsPath))?!1:r?.some(d=>d(i.fsPath)))}async function N(t,e,n={title:l,description:void 0},o){const s=await y(t,e,n,o),r=[`# ${s.title}
2
2
 
3
3
  `];return s.description&&r.push(`> ${s.description}
4
4
 
@@ -8,6 +8,6 @@ import a from"picomatch";import{dirname as $,resolve as x}from"node:path";import
8
8
  `),i.description?r.push(`${i.description.replace(/\n+$/,"")}
9
9
 
10
10
  `):r.push(`
11
- `),i.llmstxts.forEach(c=>{r.push(` - ${M({title:c.title,description:c.description,slug:v(c.slug)})}`)}),r.push(`
12
- `)}),r.join("")}function M({title:e,description:t,slug:n}){return`[${e}](${w(process.env.REDOCLY_PUBLIC_URL||"")}${encodeURI(n)})${t?`: ${t}`:""}
13
- `}function A(e){if(e?.details?.path&&e?.details?.content)throw new Error('"details.path" and "details.content" are mutually exclusive. Please use only one of them.')}function v(e){return`${e}${e==="/"?"index.html.md":".md"}`}export{S as generateLLMsTxt,v as getLLMsTxtMdSlug,M as llmsTxtLink,A as validateLLMsTxtConfig};
11
+ `),i.llmstxts.forEach(c=>{r.push(` - ${v({title:c.title,description:c.description,slug:_(c.slug)})}`)}),r.push(`
12
+ `)}),r.join("")}function v({title:t,description:e,slug:n}){return`[${t}](${w(process.env.REDOCLY_PUBLIC_URL||"")}${encodeURI(g(n))})${e?`: ${e}`:""}
13
+ `}function H(t){if(t?.details?.path&&t?.details?.content)throw new Error('"details.path" and "details.content" are mutually exclusive. Please use only one of them.')}function _(t){return`${t}${t==="/"?"index.html.md":".md"}`}export{N as generateLLMsTxt,_ as getLLMsTxtMdSlug,v as llmsTxtLink,H as validateLLMsTxtConfig};
@@ -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 _(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.ORGANIZATION_SLUG }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORGANIZATION_SLUG }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{_ 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 _(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.ORGANIZATION_ID }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORGANIZATION_ID }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{_ as ssoPlugin};
@@ -1 +1 @@
1
- import b from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as C}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as T}from"../utils/object/map-object.js";import{getValueDeep as S}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as M}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as L}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as k}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{KvService as G}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as I}from"./ssr/render.js";import{readStaticData as N,writeStaticData as V}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as H}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as y}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as U}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as q}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",bt="markdown/partials-deps",v="PLAN_GATES",W=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORG_ID"],At="userDefinedApiFunctions";class E{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=y.instance(),e=await H(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>G.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await j(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=S(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=J(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!y.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&q(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??k(r);return this.#t[t]===a||(this.#t[t]=a,await B(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=M(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=A(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!L(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!K(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&V(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return N(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:C,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):I(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=F("PLAN_GATES"),e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=z(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=S(t,r);if(c||!O(o)&&!Array.isArray(o)){await w.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!W.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(e)}}function z(P){return T(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,bt as MARKDOC_PARTIALS_DEPS_KEY,E as Store,At as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import b from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as C}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as T}from"../utils/object/map-object.js";import{getValueDeep as S}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as M}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as L}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as k}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{KvService as G}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as I}from"./ssr/render.js";import{readStaticData as N,writeStaticData as V}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as H}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as y}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as U}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as q}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",bt="markdown/partials-deps",v="PLAN_GATES",W=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],At="userDefinedApiFunctions";class E{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=y.instance(),e=await H(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>G.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await j(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=S(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=J(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!y.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&q(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??k(r);return this.#t[t]===a||(this.#t[t]=a,await B(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=M(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=A(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!L(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!K(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&V(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return N(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:C,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):I(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=F("PLAN_GATES"),e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=z(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=S(t,r);if(c||!O(o)&&!Array.isArray(o)){await w.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!W.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(e)}}function z(P){return T(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,bt as MARKDOC_PARTIALS_DEPS_KEY,E as Store,At as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -1,2 +1,2 @@
1
1
  import{telemetry as a}from"../../telemetry/index.js";import{isProductionMode as c}from"../../utils/envs/is-production-mode.js";import l,{LogLevel as r,shouldLog as h,parseLogLevel as u}from"./formatter.js";import{isVirtualFile as f}from"../../fs/utils/isVirtualFile.js";import{TerminalManager as p}from"./terminal-manager.js";import{isDevelopMode as g}from"../../utils/envs/is-develop-mode.js";class d{#e;#l;#i;#n;#r=new Map;#o=new Map;constructor({context:t,forceNonInteractive:e,minLogLevel:i}={}){this.#e=t,this.#l=c(),this.#i=new p(e),this.#n=i??u(process.env.REDOCLY_LOG_LEVEL)??(g()?r.INFO:r.HTTP)}shouldLog(t){return h(t,this.#n)}info(t,...e){this.#t({level:r.INFO,message:t,args:e})}infoTime(t,e,...i){return this.#s(r.INFO,e,t,...i)}success(t,...e){this.#t({level:r.SUCCESS,message:t,args:e})}logInFooter(t,e,...i){const o=l.interpolate(e,...i)+`
2
- `;this.isInteractive()||this.#i.isFooterChanged(t,o)&&this.#t({level:r.INFO,message:e,args:i}),this.#i.updateFooter(t,o)}successTime(t,e,...i){return this.#s(r.SUCCESS,e,t,...i)}warn(t,...e){this.#t({level:r.WARN,message:t,args:e})}warnProd(t,...e){this.#l?this.warn(t,...e):this.verbose(t,...e)}error(t,...e){this.#t({level:r.ERROR,message:t,args:e})}contentError(t,...e){this.#t({level:r.ERROR,message:t,scope:"content",args:e})}verbose(t,...e){this.#t({level:r.VERBOSE,message:t,args:e})}verboseTime(t,e,...i){return this.#s(r.VERBOSE,e,t,...i)}httpTime(t){return this.#s(r.HTTP,"",t)}startTiming(t){const e=t||Symbol();this.#r.set(e,performance.now());const i=setTimeout(()=>{this.#r.delete(e),this.#o.delete(e)},500*1e3);return this.#o.set(e,i),e}updateContext(t){this.#e={...this.#e,...t}}clearAllTimeouts(){for(const t of this.#o.values())clearTimeout(t);this.#o.clear()}isInteractive(){return this.#i.isInteractive()}warnForRealFile(t,e,i,...o){f(e,i)||this.warn(t,e,...o)}#s(t,e,i,...o){const n=this.#r.get(i);if(!n)return;const s=Math.round(performance.now()-n);return this.#r.delete(i),this.#t({level:t,message:e,duration:s,args:o}),{message:e,timeMs:s}}#t({level:t,message:e,duration:i,scope:o,args:n}){if(!h(t,this.#n))return;let s=e&&l.interpolate(e,...n);s&&i!=null&&t!==r.VERBOSE&&a.sendTimingPerformedMessage({timeMs:i,message:s});const m={level:t,message:s,duration:i,scope:o,context:this.#e};process.stderr.write(l.format(m))}}const O=new d;export{d as Logger,O as logger};
2
+ `;this.isInteractive()||this.#i.isFooterChanged(t,o)&&this.#t({level:r.INFO,message:e,args:i}),this.#i.updateFooter(t,o)}successTime(t,e,...i){return this.#s(r.SUCCESS,e,t,...i)}warn(t,...e){this.#t({level:r.WARN,message:t,args:e})}warnProd(t,...e){this.#l?this.warn(t,...e):this.verbose(t,...e)}error(t,...e){this.#t({level:r.ERROR,message:t,args:e})}contentError(t,...e){this.#t({level:r.ERROR,message:t,scope:"content",args:e})}verbose(t,...e){this.#t({level:r.VERBOSE,message:t,args:e})}verboseTime(t,e,...i){return this.#s(r.VERBOSE,e,t,...i)}httpTime(t){return this.#s(r.HTTP,"",t)}startTiming(t){const e=t||Symbol();this.#r.set(e,performance.now());const i=setTimeout(()=>{this.#r.delete(e),this.#o.delete(e)},500*1e3);return this.#o.set(e,i),e}updateContext(t){this.#e={...this.#e,...t}}clearAllTimeouts(){for(const t of this.#o.values())clearTimeout(t);this.#o.clear()}isInteractive(){return this.#i.isInteractive()}warnForRealFile(t,e,i,...o){f(e,i)||this.warn(t,e,...o)}#s(t,e,i,...o){const n=this.#r.get(i);if(!n)return;const s=Math.round(performance.now()-n);return this.#r.delete(i),this.#t({level:t,message:e,duration:s,args:o}),{message:e,timeMs:s}}#t({level:t,message:e,duration:i,scope:o,args:n}){if(!h(t,this.#n))return;let s=e&&l.interpolate(e,...n);s&&i!=null&&t!==r.VERBOSE&&a.sendTimingPerformedMessage([{object:"timing",timeMs:i,message:s}]);const m={level:t,message:s,duration:i,scope:o,context:this.#e};process.stderr.write(l.format(m))}}const O=new d;export{d as Logger,O as logger};
@@ -1,12 +1,12 @@
1
- import{isBuildMode as h}from"../../utils/envs/is-build-mode.js";import{logger as e}from"../../tools/notifiers/logger.js";import P from"./formatter.js";import{blue as g,gray as p,red as a}from"./helpers/colors.js";import{isVirtualFile as b}from"../../fs/utils/isVirtualFile.js";import{telemetry as u}from"../../telemetry/index.js";import{shutdowner as f}from"../shutdowner.js";const c=30;class C{#r=[];#o=[];#e=new Map;#t=[];pushError(r,t,...o){const n=P.interpolate(r,...o);this.#r.push({severity:t,message:n,type:"ERROR"})}reportBrokenLink(r){this.#r.push(r)}reportCompilationError(r){const t=`${r.message}::${r.sourceFileRelativePath}::${r?.sourceFileLocation?.line}`;this.#e.has(t)||this.#e.set(t,r)}reportPageRenderError(r){this.#t.push(r)}async panicOnBuild(r,...t){r instanceof Error&&(r=r.message+`
2
- `+r.stack),h()?await this.panic(r,...t):this.pushError(r,"PANIC",...t)}async panicOnBuildContentErrorForRealFile(r,t,o,...n){b(t,o)||await this.panicOnBuildContentError(r,...n)}async panicOnBuildContentError(r,...t){r instanceof Error&&(r=r.message+`
1
+ import{isBuildMode as h}from"../../utils/envs/is-build-mode.js";import{logger as e}from"../../tools/notifiers/logger.js";import P from"./formatter.js";import{blue as b,gray as p,red as c}from"./helpers/colors.js";import{isVirtualFile as g}from"../../fs/utils/isVirtualFile.js";import{telemetry as u}from"../../telemetry/index.js";import{shutdowner as f}from"../shutdowner.js";const a=30;class C{#r=[];#o=[];#e=new Map;#t=[];pushError(r,t,...o){const i=P.interpolate(r,...o);this.#r.push({severity:t,message:i,type:"ERROR"})}reportBrokenLink(r){this.#r.push(r)}reportCompilationError(r){const t=`${r.message}::${r.sourceFileRelativePath}::${r?.sourceFileLocation?.line}`;this.#e.has(t)||this.#e.set(t,r)}reportPageRenderError(r){this.#t.push(r)}async panicOnBuild(r,...t){r instanceof Error&&(r=r.message+`
2
+ `+r.stack),h()?await this.panic(r,...t):this.pushError(r,"PANIC",...t)}async panicOnBuildContentErrorForRealFile(r,t,o,...i){g(t,o)||await this.panicOnBuildContentError(r,...i)}async panicOnBuildContentError(r,...t){r instanceof Error&&(r=r.message+`
3
3
  `+r.stack),h()?await this.panicOnContentError(r,...t):this.pushError(r,"PANIC",...t)}async panic(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
4
- `+r.stack):o=new Error(r),e.error(r,...t),u.sendCliErrorCaughtMessage({message:r}),await f.exitWithCode(1,o)}async panicOnContentError(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
5
- `+r.stack):o=new Error(r),e.contentError(r,...t),u.sendCliErrorCaughtMessage({message:r,scope:"content"}),await f.exitWithCode(1,o)}reportMarkdocProblem(r){this.#o.push(r)}clearErrors(){this.#r=[]}clearMarkdocProblems(){this.#o=[]}clearEsbuildProblems(){this.#e.clear()}clearPageRenderProblems(){this.#t=[]}getCompilationProblem(r){return this.#e.get(r)}getCompilationProblems(){return[...this.#e.values()]}getPageRenderProblems(){return this.#t}getPageRenderProblem(r){return this.#t.find(t=>t.sourceFileRelativePath===r)}getProblems(){return[...this.#r,...this.getCompilationProblems(),...this.#o,...this.#t]}summary(r,t=0){const o=this.getProblems(),n=this.#o.filter(l=>l.type==="BROKEN_LINK").length,s=this.#r.filter(l=>l.type==="BROKEN_LINK").length,m=this.#o.length-n,E=this.#r.length-s+this.getCompilationProblems().length+this.#t.length;return e.logInFooter("validate",o.length?a(" \u274C Status: %s markdoc errors, %s broken links, %s other errors"):" \u2705 Status: No errors found",m,n+s,E),t!==0&&e.logInFooter("pages",` \u{1F4C4} Total pages: ${t}`),e.logInFooter("timing",r),e.logInFooter("validate-sep",""),e.isInteractive()&&(o.length?e.logInFooter("actions","Press (e) to print all errors, (q) to quit"):e.logInFooter("actions",p("Press (q) to quit"))),o}printErrors(r=[]){const t=this.#r.length,o=r.length?r:this.getProblems();let n=0;for(const s of o.slice(0,c))n>=t?e.contentError(a(`[${++n}] `)+d(s)):e.error(a(`[${++n}] `)+d(s));o.length>c&&e.error(`... and ${o.length-c} more errors`)}listenStdin(){if(!e.isInteractive())return;process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8");const r=this.printErrors.bind(this);process.stdin.on("data",function(t){if(t===""&&process.exit(),t==="\x7F"){process.stdout.write("\b \b");return}if(t==="\r"){process.stdout.write(`
6
- `);return}if(t==="e"){r();return}t==="q"&&process.exit(0)})}}const B=new C;function d(i){const r=i.sourceFileLocation,t=r?`:${r.line}:${r.character??1}`:"";return i.message+(i.codeframe?`
4
+ `+r.stack):o=new Error(r),e.error(r,...t),u.sendCliErrorCaughtMessage([{object:"cli",message:r}]),await f.exitWithCode(1,o)}async panicOnContentError(r,...t){let o;r instanceof Error?(o=r,r=r.message+`
5
+ `+r.stack):o=new Error(r),e.contentError(r,...t),u.sendCliErrorCaughtMessage([{object:"cli",message:r,scope:"content"}]),await f.exitWithCode(1,o)}reportMarkdocProblem(r){this.#o.push(r)}clearErrors(){this.#r=[]}clearMarkdocProblems(){this.#o=[]}clearEsbuildProblems(){this.#e.clear()}clearPageRenderProblems(){this.#t=[]}getCompilationProblem(r){return this.#e.get(r)}getCompilationProblems(){return[...this.#e.values()]}getPageRenderProblems(){return this.#t}getPageRenderProblem(r){return this.#t.find(t=>t.sourceFileRelativePath===r)}getProblems(){return[...this.#r,...this.getCompilationProblems(),...this.#o,...this.#t]}summary(r,t=0){const o=this.getProblems(),i=this.#o.filter(l=>l.type==="BROKEN_LINK").length,s=this.#r.filter(l=>l.type==="BROKEN_LINK").length,m=this.#o.length-i,E=this.#r.length-s+this.getCompilationProblems().length+this.#t.length;return e.logInFooter("validate",o.length?c(" \u274C Status: %s markdoc errors, %s broken links, %s other errors"):" \u2705 Status: No errors found",m,i+s,E),t!==0&&e.logInFooter("pages",` \u{1F4C4} Total pages: ${t}`),e.logInFooter("timing",r),e.logInFooter("validate-sep",""),e.isInteractive()&&(o.length?e.logInFooter("actions","Press (e) to print all errors, (q) to quit"):e.logInFooter("actions",p("Press (q) to quit"))),o}printErrors(r=[]){const t=this.#r.length,o=r.length?r:this.getProblems();let i=0;for(const s of o.slice(0,a))i>=t?e.contentError(c(`[${++i}] `)+d(s)):e.error(c(`[${++i}] `)+d(s));o.length>a&&e.error(`... and ${o.length-a} more errors`)}listenStdin(){if(!e.isInteractive())return;process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8");const r=this.printErrors.bind(this);process.stdin.on("data",function(t){if(t===""&&process.exit(),t==="\x7F"){process.stdout.write("\b \b");return}if(t==="\r"){process.stdout.write(`
6
+ `);return}if(t==="e"){r();return}t==="q"&&process.exit(0)})}}const B=new C;function d(n){const r=n.sourceFileLocation,t=r?`:${r.line}:${r.character??1}`:"";return n.message+(n.codeframe?`
7
7
 
8
- `+i.codeframe+`
8
+ `+n.codeframe+`
9
9
 
10
10
  `:`
11
- `)+(i.sourceFileRelativePath?p(`at ${g("./"+i.sourceFileRelativePath)}${t}`)+`
11
+ `)+(n.sourceFileRelativePath?p(`at ${b("./"+n.sourceFileRelativePath)}${t}`)+`
12
12
  `:"")}export{C as Reporter,B as reporter};