@redocly/redoc 0.131.0-next.9 → 0.131.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 (58) hide show
  1. package/CHANGELOG.md +165 -1
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/stats/collectors/{openapi.d.ts → openapi/index.d.ts} +2 -2
  4. package/dist/cli/stats/collectors/openapi/index.js +1 -0
  5. package/dist/cli/stats/collectors/openapi/oas32.d.ts +15 -0
  6. package/dist/cli/stats/collectors/openapi/oas32.js +1 -0
  7. package/dist/cli/stats/index.js +1 -1
  8. package/dist/client/app/hooks/useAnchorPositioning.js +1 -1
  9. package/dist/client/app/l10n/index.js +1 -1
  10. package/dist/client/app/search/useAiSearch.js +1 -1
  11. package/dist/client/app/seo/SeoTags.js +1 -1
  12. package/dist/client/templates/asyncapi-docs/template.js +1 -3
  13. package/dist/client/templates/openapi-docs/template.js +2 -6
  14. package/dist/client/types/ai-search.d.ts +1 -0
  15. package/dist/constants/l10n/langs/ar.js +1 -1
  16. package/dist/constants/l10n/langs/de.js +1 -1
  17. package/dist/constants/l10n/langs/en.js +1 -1
  18. package/dist/constants/l10n/langs/es.js +1 -1
  19. package/dist/constants/l10n/langs/fr.js +1 -1
  20. package/dist/constants/l10n/langs/hi.js +1 -1
  21. package/dist/constants/l10n/langs/it.js +1 -1
  22. package/dist/constants/l10n/langs/ja.js +1 -1
  23. package/dist/constants/l10n/langs/ko.js +1 -1
  24. package/dist/constants/l10n/langs/pl.js +1 -1
  25. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  26. package/dist/constants/l10n/langs/pt.js +1 -1
  27. package/dist/constants/l10n/langs/ru.js +1 -1
  28. package/dist/constants/l10n/langs/uk.js +1 -1
  29. package/dist/constants/l10n/langs/zh.js +1 -1
  30. package/dist/server/api-routes/execute-api-route.js +1 -1
  31. package/dist/server/node-bundle-entry.js +1 -1
  32. package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.js +37 -37
  33. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +7 -0
  34. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  35. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +22 -0
  36. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +29 -15
  37. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +6 -0
  38. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  39. package/dist/server/plugins/entitlements/index.js +1 -1
  40. package/dist/server/plugins/entitlements/utils/get-billed-catalog-build-pages-count.d.ts +6 -0
  41. package/dist/server/plugins/entitlements/utils/get-billed-catalog-build-pages-count.js +1 -0
  42. package/dist/server/plugins/graphql-docs/index.js +1 -1
  43. package/dist/server/plugins/markdown/search/nodes/heading-node.js +1 -1
  44. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +25 -25
  45. package/dist/server/plugins/pages/validators/validate-react-pages.js +1 -1
  46. package/dist/server/plugins/sidebars/index.d.ts +0 -1
  47. package/dist/server/plugins/sidebars/index.js +2 -2
  48. package/dist/server/ssr/template.js +3 -3
  49. package/dist/server/tools/notifiers/logger.d.ts +2 -2
  50. package/dist/server/tools/notifiers/logger.js +2 -2
  51. package/dist/server/tools/notifiers/terminal-manager.d.ts +1 -1
  52. package/dist/server/tools/notifiers/terminal-manager.js +4 -4
  53. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  54. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.d.ts +12 -0
  55. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.js +1 -0
  56. package/dist/server/web-server/routes/cors-proxy.js +2 -2
  57. package/package.json +12 -12
  58. package/dist/cli/stats/collectors/openapi.js +0 -1
@@ -1 +1 @@
1
- import{promiseMapLimit as l}from"../../../../../utils/async/promise-map-limit.js";import{logger as R}from"../../../../../tools/notifiers/logger.js";import{DatabaseConnectionFactory as p}from"../../../../../providers/database/database-connection-factory.js";import{BaseRepository as f}from"../../../../../providers/database/base-repository.js";import{CatalogEntitiesLocalReadRepository as m}from"./catalog-entities-local-read-repository.js";import{CatalogEntitiesLocalWriteRepository as w}from"./catalog-entities-local-write-repository.js";import{createEntityRelationDbRecordFromDto as g}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{hasOptionsChanged as I}from"../../../utils/has-options-changed.js";const c=50;class r extends f{static#i;static#n;#t;#e;#s={};constructor(t){super(t),this.#t=new m(this.databaseClient),this.#e=new w(this.databaseClient,this.organizationId,this.projectId)}get transactionsManager(){return this.databaseClient.transactionsManager}getEntitySources(){return this.#s}static async getInstance(t){const e=I(r.#n,t);if(!r.#i||e){const i=await p.create("catalog-local",t);if(!i)throw new Error("Failed to create db connection for catalog entities local repository");r.#i=new r(i),r.#n=t}return r.#i}async attachDatabase(t){await this.#t.attachDatabase(t)}getEntities({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s}){return this.#t.getEntities({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s})}getEntityById(t,e){return this.#t.getEntityById(t,e)}getEntityKeysAndVersionsBySourceFile(t){return this.#t.getEntityKeysAndVersionsBySourceFile(t)}getEntitiesCountByTypes(){return this.#t.getEntitiesCountByTypes()}getEntitiesRelations(t={}){return this.#t.getEntitiesRelations(t)}getEntityRelationById(t){return this.#t.getEntityRelationById(t)}getEntitiesWithRelations({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s}){return this.#t.getEntitiesWithRelations({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s})}getEntityWithRelationsByKey({entityKey:t,filter:e,rbacTeams:i,excludedTypes:s,excludedEntities:n}){return this.#t.getEntityWithRelationsByKey({entityKey:t,filter:e,rbacTeams:i,excludedTypes:s,excludedEntities:n})}getRelatedEntities({key:t,paginationParams:e,rbacTeams:i,excludedTypes:s,excludedEntities:n}){return this.#t.getRelatedEntities({key:t,paginationParams:e,rbacTeams:i,excludedTypes:s,excludedEntities:n})}createEntity(t){return t.isRootEntity&&(this.#s[t.sourceFile]={key:t.entity.key,version:t.entity.version??void 0}),this.#e.createEntity(t)}async createEntities(t){await l(t,c,async e=>this.createEntity(e))}createEntityRelation(t){const e=g(t,this.organizationId,this.projectId);return this.#e.upsertEntityRelation(e)}async createEntityRelations(t){await l(t,c,async e=>this.createEntityRelation(e))}deleteEntity(t){return this.#e.deleteEntity(t)}async softDeleteEntities({filter:t,revision:e,fileHash:i}){const s=await this.getEntities({paginationParams:{filter:t}}),n=await this.#e.softDeleteEntities(s.items,e,i);await this.softDeleteEntitiesRelations(n,e)}async softDeleteEntitiesRelations(t,e){try{const i=t.filter(n=>n.result==="created");if(i.length===0)return!0;const s=await l(i,c,async n=>(await this.#t.getRelationsForEntity(n.entityKey,n.entityVersion,e)).map(a=>{if(!a)return null;const y=a.direction,o=a.sourceToTargetRelation,u=a.targetKey,d=y==="outgoing"?n.entityKey:u,h=y==="outgoing"?u:n.entityKey,E=y==="outgoing"?o:o.startsWith("reverse:")?o.slice(8):o;return!E||!d||!h?null:g({type:E,sourceKey:d,targetKey:h,sourceVersion:n.entityVersion,targetVersion:n.entityVersion,sourceRevision:e,targetRevision:e,isDeleted:!0},this.organizationId,this.projectId)}).filter(a=>a!==null));return await l(s.flat(),c,async n=>this.#e.upsertEntityRelation(n)),!0}catch(i){return R.error("Error soft deleting entity relations",i),!1}}deleteEntities(t){return this.#e.deleteEntities(t)}deleteEntityRelation(t){return this.#e.deleteEntityRelation(t)}deleteEntityRelations(t){return this.#e.deleteEntityRelations(t)}getCatalogFilters(t){return this.#t.getCatalogFilters(t)}listEntityRevisions(t,e){return this.#t.listEntityRevisions(t,e)}updateEntityScorecardsStatus(t,e){return this.#e.updateEntityScorecardsStatus(t,e)}updateEntityScorecardsStatusIfCalculating(t,e){return this.#e.updateEntityScorecardsStatusIfCalculating(t,e)}getOutdatedEntities(t){return this.#t.getOutdatedEntities(t)}async setEntitiesAsOutdated(t){await this.#e.setEntitiesAsOutdated(t)}}export{r as CatalogEntitiesLocalRepository};
1
+ import{promiseMapLimit as l}from"../../../../../utils/async/promise-map-limit.js";import{logger as R}from"../../../../../tools/notifiers/logger.js";import{DatabaseConnectionFactory as p}from"../../../../../providers/database/database-connection-factory.js";import{BaseRepository as f}from"../../../../../providers/database/base-repository.js";import{CatalogEntitiesLocalReadRepository as m}from"./catalog-entities-local-read-repository.js";import{CatalogEntitiesLocalWriteRepository as w}from"./catalog-entities-local-write-repository.js";import{createEntityRelationDbRecordFromDto as h}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{hasOptionsChanged as C}from"../../../utils/has-options-changed.js";const c=50;class r extends f{static#i;static#n;#t;#e;#s={};constructor(t){super(t),this.#t=new m(this.databaseClient),this.#e=new w(this.databaseClient,this.organizationId,this.projectId)}get transactionsManager(){return this.databaseClient.transactionsManager}getEntitySources(){return this.#s}static async getInstance(t){const e=C(r.#n,t);if(!r.#i||e){const i=await p.create("catalog-local",t);if(!i)throw new Error("Failed to create db connection for catalog entities local repository");r.#i=new r(i),r.#n=t}return r.#i}async attachDatabase(t){await this.#t.attachDatabase(t)}getEntities({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s}){return this.#t.getEntities({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s})}getEntityById(t,e){return this.#t.getEntityById(t,e)}getEntityKeysAndVersionsBySourceFile(t){return this.#t.getEntityKeysAndVersionsBySourceFile(t)}getEntitiesCountByTypes(){return this.#t.getEntitiesCountByTypes()}getEntitiesRelations(t={}){return this.#t.getEntitiesRelations(t)}getEntityRelationById(t){return this.#t.getEntityRelationById(t)}getEntitiesWithRelations({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s}){return this.#t.getEntitiesWithRelations({paginationParams:t,rbacTeams:e,excludedTypes:i,excludedEntities:s})}getEntityWithRelationsByKey({entityKey:t,filter:e,rbacTeams:i,excludedTypes:s,excludedEntities:n}){return this.#t.getEntityWithRelationsByKey({entityKey:t,filter:e,rbacTeams:i,excludedTypes:s,excludedEntities:n})}getRelatedEntities({key:t,paginationParams:e,rbacTeams:i,excludedTypes:s,excludedEntities:n}){return this.#t.getRelatedEntities({key:t,paginationParams:e,rbacTeams:i,excludedTypes:s,excludedEntities:n})}createEntity(t){return t.isRootEntity&&(this.#s[t.sourceFile]={key:t.entity.key,version:t.entity.version??void 0}),this.#e.createEntity(t)}async createEntities(t){await l(t,c,async e=>this.createEntity(e))}createEntityRelation(t){const e=h(t,this.organizationId,this.projectId);return this.#e.upsertEntityRelation(e)}async createEntityRelations(t){await l(t,c,async e=>this.createEntityRelation(e))}deleteEntity(t){return this.#e.deleteEntity(t)}async softDeleteEntities({filter:t,revision:e,fileHash:i}){const s=await this.getEntities({paginationParams:{filter:t}}),n=await this.#e.softDeleteEntities(s.items,e,i);await this.softDeleteEntitiesRelations(n,e)}async softDeleteEntitiesRelations(t,e){try{const i=t.filter(n=>n.result==="created");if(i.length===0)return!0;const s=await l(i,c,async n=>(await this.#t.getRelationsForEntity(n.entityKey,n.entityVersion,e)).map(a=>{if(!a)return null;const u=a.direction,o=a.sourceToTargetRelation,y=a.targetKey,d=u==="outgoing"?n.entityKey:y,E=u==="outgoing"?y:n.entityKey,g=u==="outgoing"?o:o.startsWith("reverse:")?o.slice(8):o;return!g||!d||!E?null:h({type:g,sourceKey:d,targetKey:E,sourceVersion:n.entityVersion,targetVersion:n.entityVersion,sourceRevision:e,targetRevision:e,isDeleted:!0},this.organizationId,this.projectId)}).filter(a=>a!==null));return await l(s.flat(),c,async n=>this.#e.upsertEntityRelation(n)),!0}catch(i){return R.error("Error soft deleting entity relations",i),!1}}deleteEntities(t){return this.#e.deleteEntities(t)}deleteEntityRelation(t){return this.#e.deleteEntityRelation(t)}deleteEntityRelations(t){return this.#e.deleteEntityRelations(t)}getCatalogFilters(t){return this.#t.getCatalogFilters(t)}listEntityRevisions(t,e){return this.#t.listEntityRevisions(t,e)}updateEntityScorecardsStatus(t,e){return this.#e.updateEntityScorecardsStatus(t,e)}updateEntityScorecardsStatusIfCalculating(t,e){return this.#e.updateEntityScorecardsStatusIfCalculating(t,e)}getOutdatedEntities(t){return this.#t.getOutdatedEntities(t)}async setEntitiesAsOutdated(t){await this.#e.setEntitiesAsOutdated(t)}getEntitiesCount(t,e,i){return this.#t.getEntitiesCount(t,e,i)}getDuplicatedEntitiesCount(t,e){return this.#t.getDuplicatedEntitiesCount(t,e)}}export{r as CatalogEntitiesLocalRepository};
@@ -1 +1 @@
1
- import{writeFileSync as P}from"node:fs";import T from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as y}from"../../constants/common.js";import{envConfig as F}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as S}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as b}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as O,isPathIgnored as R}from"../../utils/index.js";import{isGraphqlDoc as $}from"../graphql-docs/is-graphql-doc.js";import{isMarkdownPage as M}from"../markdown/is-markdown-page.js";import{isOpenapiDoc as k}from"../openapi-docs/is-openapi-doc.js";import{PRODUCT_NAME as l}from"../../../config/product-gates.js";import{isAsyncapiDoc as E}from"../asyncapi-docs/is-asyncapi-doc.js";import{telemetryTraceStep as _}from"../../../cli/telemetry/helpers/trace-step.js";async function z(){return{id:"entitlements",async afterRoutesCreated(w,u){await _("build.plugin.entitlements",async t=>{const i=b.instance(),n=[],r=[],s=[],a=[],p=[];for(const{relativePath:e}of u.fs.scan())R(e)||(M(e)?n.push(e):$(e)?s.push(e):S(e)?a.push(e):await k(e,u)?r.push(e):await E(e,u)&&p.push(e));const g=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",n.length.toString()),t?.setAttribute("isMarkdownSupported",(!!g).toString()),n.length>0&&!g&&o.warn(`The product you are using ("${l}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const c=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",r.length.toString()),t?.setAttribute("isOpenApiSupported",(!!c).toString()),r.length>0&&!c&&o.warn(`The product you are using ("${l}") does not support OpenAPI documents. The following files are ignored: ${r.map(()=>"%rp").join(", ")}`,...r);const d=i.canAccessFeature("asyncapi");t?.setAttribute("totalAsyncApiFiles",p.length.toString()),t?.setAttribute("isAsyncApiSupported",(!!d).toString()),p.length>0&&!d&&o.warn(`The product you are using ("${l}") does not support AsyncAPI documents. The following files are ignored: ${p.map(()=>"%rp").join(", ")}`,...p);const m=i.canAccessFeature("graphql");t?.setAttribute("totalGraphqlFiles",s.length.toString()),t?.setAttribute("isGraphqlSupported",(!!m).toString()),s.length>0&&!m&&o.warn(`The product you are using ("${l}") does not support GraphQL documents. The following files are ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const f=i.canAccessFeature("reactPages");t?.setAttribute("totalReactFiles",a.length.toString()),t?.setAttribute("isReactPagesSupported",(!!f).toString()),a.length>0&&!f&&o.warn(`The product you are using ("${l}") does not support React pages. The following files are ignored: ${a.map(()=>"%rp").join(", ")}`,...a);const A=O(w.getAllRoutes());t?.setAttribute("totalBilledPages",A.toString());const h=F.REDOCLY_METADATA_OUTPUT_FOLDER;h&&(o.info("Save total pages..."),P(T.join(h,y),JSON.stringify({totalPages:A},null)))})}}}export{z as entitlementsPlugin};
1
+ import{writeFileSync as S}from"node:fs";import b from"path";import{PAGE_COUNT_OUTPUT_FILE_NAME as O}from"../../constants/common.js";import{envConfig as C}from"../../config/env-config.js";import{logger as o}from"../../tools/notifiers/logger.js";import{isReactPage as R}from"../../utils/content/is-react-page.js";import{EntitlementsProvider as $}from"../../entitlements/entitlements-provider.js";import{getBilledPagesCount as E,isPathIgnored as M}from"../../utils/index.js";import{isGraphqlDoc as k}from"../graphql-docs/is-graphql-doc.js";import{isMarkdownPage as D}from"../markdown/is-markdown-page.js";import{isOpenapiDoc as _}from"../openapi-docs/is-openapi-doc.js";import{PRODUCT_NAME as p}from"../../../config/product-gates.js";import{isAsyncapiDoc as I}from"../asyncapi-docs/is-asyncapi-doc.js";import{telemetryTraceStep as j}from"../../../cli/telemetry/helpers/trace-step.js";import{getBilledCatalogBuildPagesCount as q}from"./utils/get-billed-catalog-build-pages-count.js";async function Z(){return{id:"entitlements",async afterRoutesCreated(g,u){await j("build.plugin.entitlements",async t=>{const i=$.instance(),s=[],n=[],r=[],a=[],l=[];for(const{relativePath:e}of u.fs.scan())M(e)||(D(e)?s.push(e):k(e)?r.push(e):R(e)?a.push(e):await _(e,u)?n.push(e):await I(e,u)&&l.push(e));const c=i.canAccessFeature("markdown");t?.setAttribute("totalMarkdownFiles",s.length.toString()),t?.setAttribute("isMarkdownSupported",(!!c).toString()),s.length>0&&!c&&o.warn(`The product you are using ("${p}") does not support Markdown pages. The following Markdown files were detected but will be ignored: ${s.map(()=>"%rp").join(", ")}`,...s);const d=i.canAccessFeature("openapi");t?.setAttribute("totalOpenApiFiles",n.length.toString()),t?.setAttribute("isOpenApiSupported",(!!d).toString()),n.length>0&&!d&&o.warn(`The product you are using ("${p}") does not support OpenAPI documents. The following files are ignored: ${n.map(()=>"%rp").join(", ")}`,...n);const f=i.canAccessFeature("asyncapi");t?.setAttribute("totalAsyncApiFiles",l.length.toString()),t?.setAttribute("isAsyncApiSupported",(!!f).toString()),l.length>0&&!f&&o.warn(`The product you are using ("${p}") does not support AsyncAPI documents. The following files are ignored: ${l.map(()=>"%rp").join(", ")}`,...l);const m=i.canAccessFeature("graphql");t?.setAttribute("totalGraphqlFiles",r.length.toString()),t?.setAttribute("isGraphqlSupported",(!!m).toString()),r.length>0&&!m&&o.warn(`The product you are using ("${p}") does not support GraphQL documents. The following files are ignored: ${r.map(()=>"%rp").join(", ")}`,...r);const A=i.canAccessFeature("reactPages");t?.setAttribute("totalReactFiles",a.length.toString()),t?.setAttribute("isReactPagesSupported",(!!A).toString()),a.length>0&&!A&&o.warn(`The product you are using ("${p}") does not support React pages. The following files are ignored: ${a.map(()=>"%rp").join(", ")}`,...a);const w=(await u.getConfig()).entitiesCatalog,T=E(g.getAllRoutes()),{total:y,duplicatedEntitiesPages:F}=await q(g.serverOutDir,w),h=T+y;t?.setAttribute("totalBilledPages",h.toString());const P=C.REDOCLY_METADATA_OUTPUT_FOLDER;P&&(o.info("Save total pages..."),S(b.join(P,O),JSON.stringify({totalPages:h,duplicatedEntitiesPages:F},null)))})}}}export{Z as entitlementsPlugin};
@@ -0,0 +1,6 @@
1
+ import type { RedoclyConfig } from '@redocly/config';
2
+ export declare function getBilledCatalogBuildPagesCount(serverOutDir: string, catalogConfig: RedoclyConfig['entitiesCatalog']): Promise<{
3
+ total: number;
4
+ duplicatedEntitiesPages: number;
5
+ }>;
6
+ //# sourceMappingURL=get-billed-catalog-build-pages-count.d.ts.map
@@ -0,0 +1 @@
1
+ import{envConfig as c}from"../../../config/env-config.js";import{PRODUCT_NAME as s}from"../../../../config/product-gates.js";import{CatalogEntitiesService as g}from"../../catalog-entities/database/catalog-entities-service.js";async function E(t,a){const i=s.toLowerCase().includes("realm")||s.toLowerCase().includes("reef"),e=c.NEW_CATALOG_ENABLED==="true";if(!i||!e)return{total:0,duplicatedEntitiesPages:0};const o=await g.getInstance({baseDbDir:t}),{total:n}=await o.getEntitiesCount("file"),{total:l}=await o.getDuplicatedEntitiesCount(),r=u(a);return{total:n+r,duplicatedEntitiesPages:l}}function u(t){return t?.show?Object.entries(t.catalogs??{}).filter(([i,e])=>!e?.hide).length:0}export{E as getBilledCatalogBuildPagesCount};
@@ -1 +1 @@
1
- import{writeFileSync as C}from"node:fs";import $ from"node:path";import{REDOCLY_TEAMS_RBAC as v}from"@redocly/config";import{combineUrls as I}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as w}from"../../constants/common.js";import{GRAPHQL_TEMPLATE_ID as H,GRAPHQL_SPEC_SLUG as N,PUBLIC_RBAC_SCOPE_ITEM as O}from"../../../constants/common.js";import{removeTrailingSlash as _}from"../../../utils/url/remove-trailing-slash.js";import{getTemplatePath as Q}from"./get-template-path.js";import{searchResolver as F}from"./search/search-resolver.js";import{graphqlDocLoader as M}from"./graphql-doc-loader.js";import{getAiDocumentsStore as A}from"./search/ai/get-ai-search-document.js";import{fromCurrentDir as U}from"../../utils/paths.js";import{ensureDir as k}from"../../utils/fs.js";import{telemetryTraceStep as x}from"../../../cli/telemetry/helpers/trace-step.js";const B="graphql-docs-",R="graphql-spec-download";async function nt(){return{id:"graphql",requiredEntitlements:["graphql"],loaders:{"graphql-doc":M},processContent:async(t,{fs:n,cache:l,isPathIgnored:u,withPathPrefix:p})=>{await x("build.plugin.graphql_docs",async()=>{t.createRequestHandler(R,U(import.meta.url,"./spec-download.api.js")),t.addApiRoute({slug:N+"/*",requestHandlerId:R,httpMethod:"all",[v]:O,getStaticData:async()=>({props:{}})});const m=t.createTemplate(H,Q("./template/GraphQLDocs.js"));for(const{relativePath:o}of n.scan(/(\.gql|\.graphql)$/)){if(await u(o))continue;const h=await l.load(o,"graphql-doc");if(!h.data)continue;j(h.data.content,t.outdir,o);const{menu:q,content:T,settings:i,metadata:y,store:c}=h.data,b=`${B}${o}`;await t.createSharedData(b,T);const d=[{key:"graphQlSettings",id:b}],E=q.getGroups(),G=q.getSidebarItems(),g={type:"graphql",title:E[0].name,...y},s=[{slugSuffix:"",fsPath:o,templateId:m,getStaticData:S(void 0,i,p),sharedData:d,getAiDocumentsStore:A({label:i.info?.title??"GraphQL Overview",groupName:"overview",metadata:g,actions:t,store:c,includeInLLMsTxt:!0})}];for(const r of E){const f=`${r.id}`;s.push({slugSuffix:f,fsPath:o,templateId:m,getStaticData:S(r,i,p),sharedData:d});for(const e of r.typeGroups){const a=`${e.id}`;s.push({slugSuffix:a,fsPath:o,templateId:m,getStaticData:S(e,i,p),sharedData:d,getAiDocumentsStore:A({label:e.name,groupName:e.name,metadata:g,actions:t,store:c,isTypeGroup:!0,items:new Set(e.items)})});for(const L of e.items){const P=`${e.id}/${L}`;s.push({slugSuffix:P,fsPath:o,templateId:m,getStaticData:S(e,i,p),sharedData:d,getAiDocumentsStore:A({label:L,groupName:e.name,metadata:g,actions:t,store:c})})}}}if(!s.length)return;const D=s[s.length-1];D.metadata=g,D.getSidebar=r=>{function f(e){return e.map(a=>({...a,slug:a.slug&&_(I(r.baseSlug,a.slug)),routeSlug:a.routeSlug&&_(I(r.baseSlug,a.routeSlug)),link:a.link&&_(I(r.baseSlug,a.link)),items:a.items&&f(a.items)}))}return f(G)},D.getSearchDocuments=F(t,c);for(const r of s)t.addRoute(r)}})}}}function S(t,n,l){return async function(u){return{props:{seo:{title:t?.name},settings:{...n,location:{section:t?.id},sidebar:{hide:!0},baseUrlPath:l(u.baseSlug)},disableAutoScroll:!0}}}}function j(t,n,l){const u=w.slice(1);C(k($.resolve(n,`${u}/${l}`)),t,"utf8")}export{nt as graphqlDocsPlugin,j as storeGqlSchema};
1
+ import{writeFileSync as v}from"node:fs";import C from"node:path";import{REDOCLY_TEAMS_RBAC as $}from"@redocly/config";import{combineUrls as I}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as w}from"../../constants/common.js";import{GRAPHQL_TEMPLATE_ID as O,GRAPHQL_SPEC_SLUG as Q,PUBLIC_RBAC_SCOPE_ITEM as H}from"../../../constants/common.js";import{removeTrailingSlash as _}from"../../../utils/url/remove-trailing-slash.js";import{getTemplatePath as N}from"./get-template-path.js";import{searchResolver as F}from"./search/search-resolver.js";import{graphqlDocLoader as M}from"./graphql-doc-loader.js";import{getAiDocumentsStore as A}from"./search/ai/get-ai-search-document.js";import{fromCurrentDir as U}from"../../utils/paths.js";import{ensureDir as k}from"../../utils/fs.js";import{telemetryTraceStep as x}from"../../../cli/telemetry/helpers/trace-step.js";const B="graphql-docs-",R="graphql-spec-download";async function nt(){return{id:"graphql",requiredEntitlements:["graphql"],loaders:{"graphql-doc":M},processContent:async(t,{fs:n,cache:l,isPathIgnored:i,withPathPrefix:p})=>{await x("build.plugin.graphql_docs",async()=>{t.createRequestHandler(R,U(import.meta.url,"./spec-download.api.js")),t.addApiRoute({slug:Q+"/*",requestHandlerId:R,httpMethod:"all",[$]:H,getStaticData:async()=>({props:{}})});const m=t.createTemplate(O,N("./template/GraphQLDocs.js"));for(const{relativePath:o}of n.scan(/(\.gql|\.graphql)$/)){if(await i(o))continue;const h=await l.load(o,"graphql-doc");if(!h.data)continue;j(h.data.content,t.outdir,o);const{menu:q,content:G,settings:u,metadata:T,store:c}=h.data,L=`${B}${o}`;await t.createSharedData(L,G);const d=[{key:"graphQlSettings",id:L}],b=q.getGroups(),y=q.getSidebarItems(),g={type:"graphql",title:b[0].name,...T},s=[{slugSuffix:"",fsPath:o,templateId:m,getStaticData:S(void 0,u,p),sharedData:d,getAiDocumentsStore:A({label:u.info?.title??"GraphQL Overview",groupName:"overview",metadata:g,actions:t,store:c,includeInLLMsTxt:!0})}];for(const r of b){const f=`${r.id}`;s.push({slugSuffix:f,fsPath:o,templateId:m,getStaticData:S(r,u,p),sharedData:d});for(const e of r.typeGroups){const a=`${e.id}`;s.push({slugSuffix:a,fsPath:o,templateId:m,getStaticData:S(e,u,p),sharedData:d,getAiDocumentsStore:A({label:e.name,groupName:e.name,metadata:g,actions:t,store:c,isTypeGroup:!0,items:new Set(e.items)})});for(const E of e.items){const P=`${e.id}/${E}`;s.push({slugSuffix:P,fsPath:o,templateId:m,getStaticData:S(e,u,p),sharedData:d,getAiDocumentsStore:A({label:E,groupName:e.name,metadata:g,actions:t,store:c})})}}}if(!s.length)return;const D=s[s.length-1];D.metadata=g,D.getSidebar=r=>{function f(e){return e.map(a=>({...a,slug:a.slug&&_(I(r.baseSlug,a.slug)),routeSlug:a.routeSlug&&_(I(r.baseSlug,a.routeSlug)),link:a.link&&_(I(r.baseSlug,a.link)),items:a.items&&f(a.items)}))}return f(y)},D.getSearchDocuments=F(t,c);for(const r of s)t.addRoute(r)}})}}}function S(t,n,l){return async function(i){return{props:{seo:{title:t?.name??n.info?.title??"GraphQL Overview"},settings:{...n,location:{section:t?.id},sidebar:{hide:!0},baseUrlPath:l(i.baseSlug)},disableAutoScroll:!0}}}}function j(t,n,l){const i=w.slice(1);v(k(C.resolve(n,`${i}/${l}`)),t,"utf8")}export{nt as graphqlDocsPlugin,j as storeGqlSchema};
@@ -1 +1 @@
1
- import{SectionNode as t,WithSlugId as r}from"./section-node.js";class i extends r(t){constructor(e){super({...e,parentNode:null})}getUrl(e){return`${e}#${this.id}`}getPath(e){return[...e.values()].slice(0,this.node.attributes.level+1).filter(Boolean)}}export{i as HeadingNode};
1
+ import{SectionNode as o,WithSlugId as r}from"./section-node.js";class s extends r(o){constructor(e){super({...e,parentNode:null})}getUrl(e){const t=this.node.attributes.id??this.id;return`${e}#${t}`}getPath(e){return[...e.values()].slice(0,this.node.attributes.level+1).filter(Boolean)}}export{s as HeadingNode};
@@ -1,5 +1,5 @@
1
- import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as R,join as _}from"node:path";import{toMarkdown as L}from"../../../plugins/markdown/search/to-markdown.js";import{canDownloadApiDefinition as G,isResourcePubliclyAccessible as E}from"../../../utils/rbac.js";import{PUBLIC_API_DEFINITIONS_FOLDER as J}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as z}from"../../../../constants/common.js";import{SearchIndexer as V}from"../search-indexer.js";import{getLocaleFromRelativePath as q}from"../../../fs/utils/get-locale-from-relative-path.js";import{extractDocumentSearchFacets as B}from"./search-facets.js";import{formatDocumentMetadata as C}from"../../search/utils.js";import{getLLMsTxtMdSlug as Y,llmsTxtLink as M}from"../../search/llmstxt/index.js";import{replaceFileExtension as H}from"../store-definition-bundles.js";const x=new Map,me=({parser:i,options:c,info:t,tagOperations:s,relativePath:n,openapiContentItem:e,metadata:r,getSearchFacets:o,includeInLLMsTxt:a,excludeFromSearch:m})=>async(u,f,l)=>{if(m)return;const D=await u.getNavText?.()||R(u.fsPath),A=new V(i,c,u.baseSlug||u.slug),p=A.addItem(e);if(!p)return;const O=await l.getConfig(),S=Array.isArray(p.title)?p.title.join(" "):p.title;let g,d,$=x.get(n);if((e.type==="tag"||e.type==="section"&&e.infoDefinition)&&!$){const{all:b,publiclyAccessible:y}=ee(s.tagged,A,O),{all:T,publiclyAccessible:w}=ne(s.untagged,A,O);x.set(n,{taggedSearchDocuments:new Map(b),untaggedSearchDocuments:T,publiclyAccessibleTaggedSearchDocuments:new Map(y),publiclyAccessibleUntaggedSearchDocuments:w})}$=x.get(n);const h="#";switch(e.type){case"operation":const b=A.getOperation(e);g=d=X({title:S,security:i.definition.security,document:p,version:p.version||t.version,headingLevel:h,operation:b});break;case"section":if(e.infoDefinition){$=x.get(n),d=await P({parser:i,info:t,staticData:f,relativePath:n,headingLevel:h,pageName:D,config:O}),d+=`
2
- `;for(const[T,w]of $?.publiclyAccessibleTaggedSearchDocuments?.entries()||[]){if(!w.length)return;const U=i.definition.tags?.find(F=>F.name===T);d+=j({title:U?.["x-displayName"]||T,description:U?.description,operationSearchDocuments:w,headingLevel:`${h}#`})}const y=$?.publiclyAccessibleUntaggedSearchDocuments||[];y.length&&(d+=j({title:"Other",description:void 0,operationSearchDocuments:y,headingLevel:`${h}#`})),g=await P({parser:i,info:t,staticData:f,relativePath:n,headingLevel:h,pageName:D,config:O})}else e.ast&&(d=g=L(e.ast));break;case"tag":d=j({title:S,description:e.description,operationSearchDocuments:$?.publiclyAccessibleTaggedSearchDocuments.get(e.name)||[],headingLevel:h}),g=j({title:S,description:e.description,operationSearchDocuments:[],headingLevel:h});break;case"rsrc":case"prompt":case"tool":d=Z({title:S,description:e.description,name:e.name,xMcpConfig:i.definition["x-mcp"],headingLevel:h}),g=d;break}return{async getLLMsTxts(){return[{title:e.name,description:e.type==="tag"?e.description:void 0,content:d||"",slug:u.slug,fsPath:u.fsPath,includeInLLMsTxt:a}]},async getSearchDocuments(){if(e.type==="operation"||e.type==="section"&&(e.infoDefinition||e.ast)||e.type==="tag"){const b=q(u.fsPath),y=B({...p,...r},t,o);return[{title:S,description:Array.isArray(p.text)?p.text.join(" "):p.text,content:g||"",url:p.url??u.slug,fsPath:u.fsPath,locale:b,product:u.product?.name,rbacTeams:p.rbacTeams,facets:y}]}return[]}}};async function P({parser:i,info:c,staticData:t,relativePath:s,pageName:n,headingLevel:e,config:r}){const o=C(c["x-metadata"]);let a=c.title?`${e} ${c.title}
1
+ import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as F,join as L}from"node:path";import{toMarkdown as _}from"../../../plugins/markdown/search/to-markdown.js";import{canDownloadApiDefinition as G,isResourcePubliclyAccessible as J}from"../../../utils/rbac.js";import{PUBLIC_API_DEFINITIONS_FOLDER as q}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as z}from"../../../../constants/common.js";import{SearchIndexer as V}from"../search-indexer.js";import{getLocaleFromRelativePath as B}from"../../../fs/utils/get-locale-from-relative-path.js";import{extractDocumentSearchFacets as C}from"./search-facets.js";import{formatDocumentMetadata as Y}from"../../search/utils.js";import{getLLMsTxtMdSlug as H,llmsTxtLink as E}from"../../search/llmstxt/index.js";import{replaceFileExtension as K}from"../store-definition-bundles.js";const x=new Map,he=({parser:s,options:c,info:t,tagOperations:i,relativePath:n,openapiContentItem:e,metadata:r,getSearchFacets:o,includeInLLMsTxt:a,excludeFromSearch:m})=>async(u,f,l)=>{if(m)return;const D=await u.getNavText?.()||F(u.fsPath),A=new V(s,c,u.baseSlug||u.slug),p=A.addItem(e);if(!p)return;const O=await l.getConfig(),S=Array.isArray(p.title)?p.title.join(" "):p.title;let g,d,$=x.get(n);if((e.type==="tag"||e.type==="section"&&e.infoDefinition)&&!$){const{all:b,publiclyAccessible:y}=ne(i.tagged,A,O),{all:T,publiclyAccessible:w}=te(i.untagged,A,O);x.set(n,{taggedSearchDocuments:new Map(b),untaggedSearchDocuments:T,publiclyAccessibleTaggedSearchDocuments:new Map(y),publiclyAccessibleUntaggedSearchDocuments:w})}$=x.get(n);const h="#";switch(e.type){case"operation":const b=A.getOperation(e);g=d=Z({title:S,security:s.definition.security,document:p,version:p.version||t.version,headingLevel:h,operation:b});break;case"section":if(e.infoDefinition){$=x.get(n),d=await M({parser:s,info:t,staticData:f,relativePath:n,headingLevel:h,pageName:D,config:O}),d+=`
2
+ `;for(const[T,w]of $?.publiclyAccessibleTaggedSearchDocuments?.entries()||[]){if(!w.length)return;const U=s.definition.tags?.find(N=>N.name===T);d+=j({title:U?.["x-displayName"]||T,description:U?.description,operationSearchDocuments:w,headingLevel:`${h}#`})}const y=$?.publiclyAccessibleUntaggedSearchDocuments||[];y.length&&(d+=j({title:"Other",description:void 0,operationSearchDocuments:y,headingLevel:`${h}#`})),g=await M({parser:s,info:t,staticData:f,relativePath:n,headingLevel:h,pageName:D,config:O})}else e.ast&&(d=g=_(e.ast));break;case"tag":d=j({title:S,description:e.description,operationSearchDocuments:$?.publiclyAccessibleTaggedSearchDocuments.get(e.name)||[],headingLevel:h}),g=j({title:S,description:e.description,operationSearchDocuments:[],headingLevel:h});break;case"rsrc":case"prompt":case"tool":d=I({title:S,description:e.description,name:e.name,xMcpConfig:s.definition["x-mcp"],headingLevel:h}),g=d;break}return{async getLLMsTxts(){return[{title:e.name,description:e.type==="tag"?e.description:void 0,content:d||"",slug:u.slug,fsPath:u.fsPath,includeInLLMsTxt:a}]},async getSearchDocuments(){if(e.type==="operation"||e.type==="section"&&(e.infoDefinition||e.ast)||e.type==="tag"){const b=B(u.fsPath),y=C({...p,...r},t,o);return[{title:S,description:Array.isArray(p.text)?p.text.join(" "):p.text,content:g||"",url:p.url??u.slug,fsPath:u.fsPath,locale:b,product:u.product?.name,rbacTeams:p.rbacTeams,facets:y}]}return[]}}};async function M({parser:s,info:c,staticData:t,relativePath:i,pageName:n,headingLevel:e,config:r}){const o=Y(c["x-metadata"]);let a=c.title?`${e} ${c.title}
3
3
 
4
4
  `:`${e} ${n}
5
5
 
@@ -12,30 +12,30 @@ import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as R,join a
12
12
  `:"",e=`${e}#`,a+=o.length?`Metadata:
13
13
  ${o}
14
14
  `:"",a+=`
15
- `,a+=K({parser:i,headingLevel:e}),a+=W({parser:i,headingLevel:e}),a+=await Q({info:c,staticData:t,relativePath:s,pageName:n,headingLevel:e,config:r}),a}function j({title:i="",description:c,operationSearchDocuments:t,headingLevel:s}){let n=`${s} ${i}
15
+ `,a+=Q({parser:s,headingLevel:e}),a+=X({parser:s,headingLevel:e}),a+=await W({info:c,staticData:t,relativePath:i,pageName:n,headingLevel:e,config:r}),a}function j({title:s="",description:c,operationSearchDocuments:t,headingLevel:i}){let n=`${i} ${s}
16
16
 
17
17
  `;return c&&(n+=`${c}
18
18
 
19
- `),t.length&&t.forEach(e=>{const r=Array.isArray(e.title)?e.title.join(" "):e.title;n+=`${s}# ${r}${e.deprecated?" (deprecated)":""}
19
+ `),t.length&&t.forEach(e=>{const r=Array.isArray(e.title)?e.title.join(" "):e.title;n+=`${i}# ${r}${e.deprecated?" (deprecated)":""}
20
20
 
21
- `,n+=` - ${M({title:`${e.httpMethod?.toUpperCase()} ${e.httpPath}`,description:Array.isArray(e.text)?e.text.join(" "):e.text,slug:Y(e.url)})}`,n+=`
22
- `}),n}function K({parser:i,headingLevel:c}){const{servers:t}=i.definition;if(t&&t.length){let s=`${c} Servers
21
+ `,n+=` - ${E({title:`${e.httpMethod?.toUpperCase()} ${e.httpPath}`,description:Array.isArray(e.text)?e.text.join(" "):e.text,slug:H(e.url)})}`,n+=`
22
+ `}),n}function Q({parser:s,headingLevel:c}){const{servers:t}=s.definition;if(t&&t.length){let i=`${c} Servers
23
23
 
24
- `;return t.forEach(n=>{s+=n.description?`${n.description}
25
- `:"",s+=`\`\`\`
24
+ `;return t.forEach(n=>{i+=n.description?`${n.description}
25
+ `:"",i+=`\`\`\`
26
26
  ${n.url}
27
27
  \`\`\`
28
28
 
29
- `,n.variables&&(s+=`Variables:
30
- `,Object.entries(n.variables).forEach(([e,r])=>{s+=`- \`${e}\`${r.description?`: ${r.description}`:""}
31
- `,s+=r.default?`Default: ${JSON.stringify(r.default)}
32
- `:"",s+=r.enum?`Enum: ${r.enum.map(o=>JSON.stringify(o)).join(", ")}
33
- `:""}),s+=`
34
- `)}),s}return""}async function Q({info:i,staticData:c,relativePath:t,pageName:s,headingLevel:n,config:e}){const r=_(c.props?.outdir||"",J,H(t,".yaml"));if(G(r,e.rbac||{},e.requiresLogin||!1,{isAuthenticated:!1,teams:[z]})){let o=`${n} Download OpenAPI description
29
+ `,n.variables&&(i+=`Variables:
30
+ `,Object.entries(n.variables).forEach(([e,r])=>{i+=`- \`${e}\`${r.description?`: ${r.description}`:""}
31
+ `,i+=r.default?`Default: ${JSON.stringify(r.default)}
32
+ `:"",i+=r.enum?`Enum: ${r.enum.map(o=>JSON.stringify(o)).join(", ")}
33
+ `:""}),i+=`
34
+ `)}),i}return""}async function W({info:s,staticData:c,relativePath:t,pageName:i,headingLevel:n,config:e}){const r=L(c.props?.outdir||"",q,K(t,".yaml"));if(G(r,e.rbac||{},e.requiresLogin||!1,{isAuthenticated:!1,teams:[z]})){let o=`${n} Download OpenAPI description
35
35
 
36
- `;return o+=M({title:i.title||s||"OpenAPI definition",description:void 0,slug:r}),o}return""}function W({parser:i,headingLevel:c}){if(!i.definition.components?.securitySchemes)return"";let t=`${c} Security
36
+ `;return o+=E({title:s.title||i||"OpenAPI definition",description:void 0,slug:r}),o}return""}function X({parser:s,headingLevel:c}){if(!s.definition.components?.securitySchemes)return"";let t=`${c} Security
37
37
 
38
- `;const{securitySchemes:s}=i.definition.components;return Object.keys(s).forEach(n=>{const e=s[n];e&&(t+=`${c}# ${n}
38
+ `;const{securitySchemes:i}=s.definition.components;return Object.keys(i).forEach(n=>{const e=i[n];e&&(t+=`${c}# ${n}
39
39
 
40
40
  `,t+=e.description?`${e.description}
41
41
 
@@ -52,41 +52,41 @@ ${n.url}
52
52
  `),e.flows?.password?.scopes&&(t+=`Scopes:
53
53
  `,Object.entries(e.flows?.password?.scopes||{}).forEach(([r,o])=>{t+=`- \`${r}\`: ${o}
54
54
  `})),t+=`
55
- `)}),t}function X({title:i,security:c,document:t,version:s,headingLevel:n,operation:e}){const{text:r,httpMethod:o,httpPath:a,deprecated:m}=t,u=v(t.parameters||[],`${n}#`),f=I(`${n}#`,t.parameters,e);let l=i?`${n} ${i}${m?" (deprecated)":""}
55
+ `)}),t}function Z({title:s,security:c,document:t,version:i,headingLevel:n,operation:e}){const{text:r,httpMethod:o,httpPath:a,deprecated:m}=t,u=ee(t.parameters||[],`${n}#`),f=v(`${n}#`,t.parameters,e);let l=s?`${n} ${s}${m?" (deprecated)":""}
56
56
 
57
57
  `:"";return l+=r?`${r}
58
58
 
59
59
  `:"",l+=`Endpoint: ${o?.toUpperCase()} ${a}
60
- `,l+=s?`Version: ${s}
60
+ `,l+=i?`Version: ${i}
61
61
  `:"",l+=t.security?.length?`Security: ${t.security.join(", ")}
62
62
  `:c?.length?`Security: ${c.map(D=>D.id).join(", ")}
63
63
  `:"",l+=`
64
64
  `,l+=u?`${u}
65
65
  `:"",l+=`
66
66
  `,l+=`${f.join(`
67
- `)}`,l}function Z({title:i,name:c,xMcpConfig:t,headingLevel:s}){const n=t?.tools.find(r=>r.name===c);if(!n)return"";let e=`${s} ${i}
67
+ `)}`,l}function I({title:s,name:c,xMcpConfig:t,headingLevel:i}){const n=t?.tools.find(r=>r.name===c);if(!n)return"";let e=`${i} ${s}
68
68
 
69
69
  `;return e+=n.description?`${n.description}
70
70
 
71
- `:"",e+=`${s}# Input schema:
71
+ `:"",e+=`${i}# Input schema:
72
72
 
73
73
  `,e+=`\`\`\`json
74
74
  ${JSON.stringify(n.inputSchema,null,2)}
75
75
  \`\`\`
76
76
 
77
- `,n.outputSchema&&(e+=`${s}# Output schema:
77
+ `,n.outputSchema&&(e+=`${i}# Output schema:
78
78
 
79
79
  `,e+=`\`\`\`json
80
80
  ${JSON.stringify(n.outputSchema,null,2)}
81
81
  \`\`\`
82
82
 
83
- `),e}function I(i,c,t){return!c&&!t||!t?.responses?[]:t?.responses.filter(n=>!n.content?.mediaTypes[0]?.schema).map(n=>`${i} ${N(`response ${n.code} fields`)}
84
- `)}function v(i,c){const t={};for(const n of i){const e=`${n.place}${n.mediaType?` (${n.mediaType})`:""}`;t[e]=[...t[e]||[],n]}return Object.entries(t).map(([n,e])=>{const r=e.map(o=>{const a=" ",m=[...o.path||[],o.name],u=Array.isArray(o.description)?o.description.join(" "):o.description;let f=` - \`${m.join(".")}\` (${o.type}${o.required?", required":""})
83
+ `),e}function v(s,c,t){return!c&&!t||!t?.responses?[]:t?.responses.filter(n=>!n.content?.mediaTypes[0]?.schema).map(n=>`${s} ${P(`response ${n.code} fields`)}
84
+ `)}function ee(s,c){const t={};for(const n of s){const e=`${n.place}${n.mediaType?` (${n.mediaType})`:""}`;t[e]=[...t[e]||[],n]}return Object.entries(t).map(([n,e])=>{const r=e.map(o=>{const a=" ",m=[...o.path||[],o.name],u=Array.isArray(o.description)?o.description.join(" "):o.description;let f=` - \`${m.join(".")}\` (${o.type}${o.required?", required":""})
85
85
  `;return f+=u?`${a}${u.trim()}
86
86
  `:"",o.enum?f+=`${a}Enum: ${o.enum.map(l=>JSON.stringify(l)).join(", ")}
87
87
  `:o.example&&(f+=`${a}Example: ${o.example}
88
- `),f});return`${c} ${N(n)}:
88
+ `),f});return`${c} ${P(n)}:
89
89
 
90
90
  ${r.join(`
91
91
  `)}`}).join(`
92
- `)}function ee(i,c,t){const s=[],n=[];return i.forEach((e,r)=>{const o=[],a=[];e.forEach(m=>{const u=c.addItem(m);u&&(o.push(u),E({[k]:m[k],slug:u.url},t)&&a.push(u))}),s.push([r,o]),n.push([r,a])}),{all:s,publiclyAccessible:n}}function ne(i,c,t){const s=[],n=[];return i.forEach(e=>{const r=c.addItem(e);r&&(s.push(r),E({[k]:e[k],slug:r.url},t)&&n.push(r))}),{all:s,publiclyAccessible:n}}function N(i){return i.charAt(0).toUpperCase()+i.slice(1)}export{me as getAiDocumentsStore};
92
+ `)}function ne(s,c,t){const i=[],n=[];return s.forEach((e,r)=>{const o=[],a=[];e.forEach(m=>{const u=c.addItem(m);u&&(o.push(u),R({[k]:m[k],slug:u.url},t)&&a.push(u))}),i.push([r,o]),n.push([r,a])}),{all:i,publiclyAccessible:n}}function te(s,c,t){const i=[],n=[];return s.forEach(e=>{const r=c.addItem(e);r&&(i.push(r),R({[k]:e[k],slug:r.url},t)&&n.push(r))}),{all:i,publiclyAccessible:n}}function P(s){return s.charAt(0).toUpperCase()+s.slice(1)}function R(s,c){return c.requiresLogin?!0:J(s,c)}export{he as getAiDocumentsStore};
@@ -1 +1 @@
1
- import u from"node:path";import{logger as n}from"../../../tools/notifiers/logger.js";import{reporter as s}from"../../../tools/notifiers/reporter.js";import{getServerProps as d}from"../../../ssr/server-side-props/get-server-props.js";import{telemetry as f}from"../../../../cli/telemetry/index.js";async function b(e,o){s.clearPageRenderProblems();const r=e.getAllRoutes().filter(t=>t.fsPath.match(/\.page\.tsx?$/));if(!r.length)return;const l=n.startTiming();n.info("Validating react pages");const g=await p(e.serverOutDir);for(const t of r){const c=await e.resolveRouteStaticData(t,o),m=await d(t,null,c,e);let a;try{a=(await g(t,m,null,e,f,!0)).error}catch(i){a=i}a&&s.reportPageRenderError({message:a.name==="PageMissingDefaultExportError"?a.message:`Runtime error: ${a.message}`,sourceFileRelativePath:t.fsPath})}n.infoTime(l,`Validated ${r.length} React pages`)}async function p(e){const r=await import(u.join(e,"index.mjs"));if(!r.renderPage)throw new Error("renderPage function not found in bundle");return r.renderPage}export{b as validateReactPages};
1
+ import{pathToFileURL as u}from"node:url";import{slash as d}from"../../../../utils/path/slash.js";import{logger as o}from"../../../tools/notifiers/logger.js";import{reporter as n}from"../../../tools/notifiers/reporter.js";import{getServerProps as p}from"../../../ssr/server-side-props/get-server-props.js";import{telemetry as f}from"../../../../cli/telemetry/index.js";async function x(r,i){try{n.clearPageRenderProblems();const e=r.getAllRoutes().filter(t=>t.fsPath.match(/\.page\.tsx?$/));if(!e.length)return;const l=o.startTiming();o.info("Validating react pages");const g=await P(r.serverOutDir);for(const t of e){const c=await r.resolveRouteStaticData(t,i),m=await p(t,null,c,r);let a;try{a=(await g(t,m,null,r,f,!0)).error}catch(s){a=s}a&&n.reportPageRenderError({message:a.name==="PageMissingDefaultExportError"?a.message:`Runtime error: ${a.message}`,sourceFileRelativePath:t.fsPath})}o.infoTime(l,`Validated ${e.length} React pages`)}catch(e){await n.panicOnBuild(`Failed to validate react pages: ${e.message}`)}}async function P(r){const e=await import(u(`${d(r)}/index.mjs`)+"?only-exports=true");if(!e.renderPage)throw new Error("renderPage function not found in bundle");return e.renderPage}export{x as validateReactPages};
@@ -4,5 +4,4 @@ import type { ContentFs } from '../../fs/content-fs.js';
4
4
  export declare function sidebarsPlugin({ contentDir, }: PluginOptions): Promise<LifecyclePluginInstance>;
5
5
  export declare function removeMarkdownTags(items: ResolvedNavItem[]): ResolvedNavItem[];
6
6
  export declare function resolveSidebarId(relativePath: string, sidebarPath: string, fs: ContentFs): Promise<string | null>;
7
- export declare function isSidebarIgnored(ignore: string[], sidebarPath: string): boolean;
8
7
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,3 @@
1
- import{writeFileSync as tt}from"node:fs";import*as u from"path";import et from"@markdoc/markdoc";import{withoutHash as ot}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as v,SIDEBAR_PREFIX as at,CONFIG_FILE_NAME as V}from"../../../constants/common.js";import{CATALOG_OUTPUT_FILE_NAME as rt}from"../../constants/common.js";import{findDeepFirst as M}from"../../../utils/tree/find-deep-first.js";import{isDefined as X}from"../../../utils/guards/is-defined.js";import{partition as it}from"../../../utils/array/partition.js";import{collectPropValueDeep as N}from"../../../utils/tree/collect-prop-value-deep.js";import{envConfig as nt}from"../../config/env-config.js";import{isLocalLink as st}from"../../../utils/path/is-local-link.js";import{normalizeRouteSlug as Y}from"../../../utils/path/normalize-route-slug.js";import{slash as lt}from"../../../utils/path/slash.js";import{parsePathVersions as ct}from"../../../utils/path/parse-path-versions.js";import{reporter as A}from"../../tools/notifiers/reporter.js";import{logger as x}from"../../tools/notifiers/logger.js";import{sha1 as ft}from"../../utils/crypto/sha1.js";import{getInnerText as dt}from"../../../markdoc/helpers/get-inner-text.js";import{collectItemsLinkedToSidebars as ut,resolveItems as Z}from"../nav-utils.js";import{getExcludedFromLinkCheckerPatterns as mt,getSidebarReferences as gt,hasCircularDependency as pt}from"./utils.js";import{getLocaleFromRelativePath as ht}from"../../fs/utils/get-locale-from-relative-path.js";import{isSystemRouteSlug as St}from"../../utils/system-routes.js";import{ENTITIES_MAP_GLOBAL_DATA_KEY as yt}from"../../constants/plugins/catalog-entities.js";import{telemetryTraceStep as bt}from"../../../cli/telemetry/helpers/trace-step.js";const Ft=180,It=170,Ct=10;async function Jt({contentDir:l}){return{id:"sidebars",async afterRoutesCreated(o,i){await bt("build.plugin.sidebars",async()=>{const{cache:d,fs:c}=i,I=o.getConfig(),C=new Map,D=new Set,B=[v,...c.localeFolders],j=o.getGlobalData()[yt]||{},G=new Map;let L=c.scan(/sidebars.yaml$/).map(({relativePath:t})=>t).filter(t=>!wt(I.ignore??[],t)&&t);const $=await gt(i,l,L),q=it(L.filter(t=>!$.has(t)),t=>ct(t)?.versionFolderPath||t),_=mt(I),Q=await ut(I?.navbar,o,i,{navFile:V,excludedFromLinkCheckerPatterns:_});let P;const T=pt($);T&&Array.isArray(T)&&await A.panicOnBuildContentError(`Sidebar references have circular dependency. Please check your sidebar files.
1
+ import{writeFileSync as tt}from"node:fs";import*as u from"path";import et from"@markdoc/markdoc";import{withoutHash as ot}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as v,SIDEBAR_PREFIX as at,CONFIG_FILE_NAME as V}from"../../../constants/common.js";import{CATALOG_OUTPUT_FILE_NAME as rt}from"../../constants/common.js";import{findDeepFirst as M}from"../../../utils/tree/find-deep-first.js";import{isDefined as X}from"../../../utils/guards/is-defined.js";import{partition as it}from"../../../utils/array/partition.js";import{collectPropValueDeep as N}from"../../../utils/tree/collect-prop-value-deep.js";import{envConfig as nt}from"../../config/env-config.js";import{isLocalLink as st}from"../../../utils/path/is-local-link.js";import{normalizeRouteSlug as Y}from"../../../utils/path/normalize-route-slug.js";import{slash as lt}from"../../../utils/path/slash.js";import{parsePathVersions as ct}from"../../../utils/path/parse-path-versions.js";import{reporter as k}from"../../tools/notifiers/reporter.js";import{logger as B}from"../../tools/notifiers/logger.js";import{sha1 as ft}from"../../utils/crypto/sha1.js";import{getInnerText as dt}from"../../../markdoc/helpers/get-inner-text.js";import{collectItemsLinkedToSidebars as ut,resolveItems as J}from"../nav-utils.js";import{getExcludedFromLinkCheckerPatterns as mt,getSidebarReferences as gt,hasCircularDependency as pt}from"./utils.js";import{getLocaleFromRelativePath as ht}from"../../fs/utils/get-locale-from-relative-path.js";import{isSystemRouteSlug as St}from"../../utils/system-routes.js";import{ENTITIES_MAP_GLOBAL_DATA_KEY as yt}from"../../constants/plugins/catalog-entities.js";import{telemetryTraceStep as Ft}from"../../../cli/telemetry/helpers/trace-step.js";import{isPathIgnored as It}from"../../utils/paths.js";const bt=180,Ct=170,Dt=10;async function Qt({contentDir:c}){return{id:"sidebars",async afterRoutesCreated(o,s){await Ft("build.plugin.sidebars",async()=>{const{cache:f,fs:d}=s,b=o.getConfig(),C=new Map,D=new Set,x=[v,...d.localeFolders],j=o.getGlobalData()[yt]||{},G=new Map;let R=d.scan(/sidebars.yaml$/).map(({relativePath:t})=>t).filter(t=>!It(t,b.ignore??[])&&t);const $=await gt(s,c,R),Q=it(R.filter(t=>!$.has(t)),t=>ct(t)?.versionFolderPath||t),_=mt(b),Z=await ut(b?.navbar,o,s,{navFile:V,excludedFromLinkCheckerPatterns:_});let P;const T=pt($);T&&Array.isArray(T)&&await k.panicOnBuildContentError(`Sidebar references have circular dependency. Please check your sidebar files.
2
2
  Circular dependency chain: ${T.reverse().join(" -> ")}
3
- `);for(const t of q){const m=(await Promise.all(t.map(async n=>{const e=(await d.load(n,"yaml")).data;if(!Array.isArray(e)){await A.panicOnBuildContentErrorForRealFile('Invalid sidebar contents at %rp, items should be an array, got "%s"',n,c,n,typeof e);return}return{items:e,sidebarRelativePath:n,locale:ht(n)}}))).filter(X),r=(await k(m))?.firstLink;P||(P=r)}const z=Object.entries(I?.catalogClassic??{});for(const t of B){for(const[e,s]of z)await W(e,s,t);const m={},r=new Set,n=o.getAllRoutesForLocale(t);for(const e of n)if(U(e)&&e.fsPath&&!r.has(e.fsPath)){r.add(e.fsPath);let f=u.posix.dirname(e.fsPath);const h=u.parse(f).root;do m[f]=(m[f]||0)+1,f=u.dirname(f);while(f&&f!="."&&h!=f)}for(const e of n){if(C.has(e.slug))continue;const s=U(e),f=u.dirname(e.fsPath),h=m[f]===1,g=vt(e.baseSlug||e.slug);s&&h?await k([{items:[{directory:f}],sidebarRelativePath:"sidebar.yaml_"+g,locale:t}]):e.getSidebar!==void 0&&await k([{items:[{page:e.fsPath}],sidebarRelativePath:"sidebar.yaml_"+g,locale:t}])}for(const[e,s]of z)await W(e,s,t,!0)}if(L.length===0)for(const t of B){x.verbose("Creating default sidebar");const m=t===v,r=`sidebars.yaml${m?"":"_"+t}`,n=m?"":`${c.localizationFolder}/${t}`,e=(await k([{items:[{directory:`./${n}`}],sidebarRelativePath:r,locale:t,ignoredRoutes:D}]))?.firstLink;P||(P=e)}if(!o.getRouteBySlug("/")&&!o.getConfig().redirects?.["/"]){const m=o.getAllRoutes().find(n=>!St(n.slug)),r=P?P.link:m?.baseSlug??null;if(r){const n=ot(r);o.addRedirect("/",{to:n,type:302}),x.info("Creating default redirect for index page => %s",n)}}const H=nt.REDOCLY_METADATA_OUTPUT_FOLDER;H&&(x.info("Writing catalog data..."),tt(u.join(H,rt),JSON.stringify(Object.fromEntries(G.entries()))));function U(t){return D.has(t.slug)||j[t.fsPath]}async function k(t){if(t.length===0)return;const r=(await Promise.all(t.map(async({items:g,locale:F,sidebarRelativePath:p,ignoredRoutes:R})=>{const a=await Z(g,u.dirname(u.join(l,p)),o,i,{locale:F,ignoredRoutes:R,navFile:p,excludedFromLinkCheckerPatterns:_});if(!a){await A.panicOnBuild("Failed to resolve sidebar configuration. Make sure %rp is valid",p);return}return a}))).flat().filter(X),n=N(r,"routeSlug"),e=t[0].sidebarRelativePath,s=J(e),f=new Set;for(const g of n){const F=o.getRouteBySlug(g)?.fsPath??"",p=j[F];p&&(Array.from(f).find(a=>a.key===p.key&&a.version===p.version)||f.add(p)),o.addRouteSharedData(g,"sidebar",s),C.set(Y(g),r)}const h=f.size===1?Array.from(f)[0]:void 0;return await o.createSharedData(s,{relatedNavbarItem:Q?.get(e),items:r,catalogEntity:h?{key:h.key,version:h.version}:void 0}),{firstLink:M(r,g=>!!g.link),resolved:r}}async function W(t,m,r,n=!1){const e=structuredClone(m);r&&r!==v&&e.items.forEach(a=>{a.directory=u.posix.join(c.localizationFolder||"",r,a.directory||"")});let s=await Z(e.items,l,o,i,{groupCustomSidebars:!0,locale:r,navFile:V,excludedFromLinkCheckerPatterns:_});if(s&&(s=Pt(s)),!s){await A.panicOnBuild(`Failed to resolve catalog configuration. Make sure catalog ${t} has valid config`);return}const f=r===v?"":"/"+r.toLowerCase(),h=r===v?"":`-${r}`,g=Y(u.posix.join(f,e.slug));if(n)for(const a of s){const S=M(a.items||[],b=>!!b.routeSlug);if(!S?.routeSlug)continue;const y=C.get(S.routeSlug);if(!y)continue;const O=N(y,"routeSlug"),E="current-catalog-info-"+a.routeSlug+h,w={catalog:{label:e.title,titleTranslationKey:e.titleTranslationKey,link:g,icon:e?.icon},item:{label:a.metadata?.title,link:a.link,icon:a.icon}};await o.createSharedData(E,w);for(const b of O)o.addRouteSharedData(b,"current-catalog-info",E),D.add(b);const K=M(y,b=>!!b.link&&!b.external&&st(b.link)&&(!a.version||b.version===a.version));K&&(a.sidebar=[{...K,items:void 0}])}const F={},p=new Set;for(const a of s){if(!(a.routeSlug||a.sidebar?.[0]?.routeSlug)||!a.fsPath||p.has(a.fsPath))continue;p.add(a.fsPath);const y=u.dirname(a.fsPath);F[y]=(F[y]||0)+1}if(n){const a=await o.createSharedData("catalog-"+t+h,s.flatMap(S=>{const y=u.dirname(S.fsPath??""),O=F[y]===1,E=w=>({...w,fsPath:O?y:w.fsPath??""});return S.type==="group"&&S.items?.every(w=>w.type==="group")?(S.items||[]).map(E):E(S)}));o.addRouteSharedData(g,"catalog",a),Dt(r,s,G,F)}const R=N(s,"routeSlug");for(const a of R)D.add(a)}})}}}function Dt(l,o,i,d){if(l===v)for(const c of o){const I=c.routeSlug||c.sidebar?.[0]?.routeSlug;if(!I||!c.fsPath)continue;const C=u.dirname(c.fsPath),D=d[C]===1;i.set(I,{rootFileFsPath:c.fsPath,fsPath:D?C:c.fsPath,metadata:c.metadata||{},title:c.metadata?.title||c.label||"Untitled",version:c.version||"latest"})}}function Pt(l){const o=i=>{if(!i)return i;const d=et.parse(i);return dt([d])};return l.map(i=>{const d={...i};return d.metadata?.description&&(d.metadata={...d.metadata,description:o(d.metadata.description)}),d})}function J(l){return at+lt(l)}async function qt(l,o,i){const d=u.posix.join(u.dirname(l),o);return await i.exists(d)?J(d):(await A.panicOnBuildContentErrorForRealFile("File %rp: Failed to create relative path for sidebars.yaml using %s",l,i,l,o),null)}function wt(l,o){const i=/\/?([a-zA-Z0-9-_]+\/)*sidebars?(-[a-zA-Z0-9-_]+)?\.yaml/;return l.filter(c=>i.test(c)).includes(o)}function vt(l){const o=l.replaceAll("/","_");if(o.length>Ft){const i=o.slice(0,It),d=ft(l).slice(0,Ct).replaceAll("/","_");return i+d}else return o}export{wt as isSidebarIgnored,Pt as removeMarkdownTags,qt as resolveSidebarId,Jt as sidebarsPlugin};
3
+ `);for(const t of Q){const m=(await Promise.all(t.map(async i=>{const e=(await f.load(i,"yaml")).data;if(!Array.isArray(e)){await k.panicOnBuildContentErrorForRealFile('Invalid sidebar contents at %rp, items should be an array, got "%s"',i,d,i,typeof e);return}return{items:e,sidebarRelativePath:i,locale:ht(i)}}))).filter(X),r=(await A(m))?.firstLink;P||(P=r)}const H=Object.entries(b?.catalogClassic??{});for(const t of x){for(const[e,n]of H)await z(e,n,t);const m={},r=new Set,i=o.getAllRoutesForLocale(t);for(const e of i)if(W(e)&&e.fsPath&&!r.has(e.fsPath)){r.add(e.fsPath);let l=u.posix.dirname(e.fsPath);const h=u.parse(l).root;do m[l]=(m[l]||0)+1,l=u.dirname(l);while(l&&l!="."&&h!=l)}for(const e of i){if(C.has(e.slug))continue;const n=W(e),l=u.dirname(e.fsPath),h=m[l]===1,g=vt(e.baseSlug||e.slug);n&&h?await A([{items:[{directory:l}],sidebarRelativePath:"sidebar.yaml_"+g,locale:t}]):e.getSidebar!==void 0&&await A([{items:[{page:e.fsPath}],sidebarRelativePath:"sidebar.yaml_"+g,locale:t}])}for(const[e,n]of H)await z(e,n,t,!0)}if(R.length===0)for(const t of x){B.verbose("Creating default sidebar");const m=t===v,r=`sidebars.yaml${m?"":"_"+t}`,i=m?"":`${d.localizationFolder}/${t}`,e=(await A([{items:[{directory:`./${i}`}],sidebarRelativePath:r,locale:t,ignoredRoutes:D}]))?.firstLink;P||(P=e)}if(!o.getRouteBySlug("/")&&!o.getConfig().redirects?.["/"]){const m=o.getAllRoutes().find(i=>!St(i.slug)),r=P?P.link:m?.baseSlug??null;if(r){const i=ot(r);o.addRedirect("/",{to:i,type:302}),B.info("Creating default redirect for index page => %s",i)}}const U=nt.REDOCLY_METADATA_OUTPUT_FOLDER;U&&(B.info("Writing catalog data..."),tt(u.join(U,rt),JSON.stringify(Object.fromEntries(G.entries()))));function W(t){return D.has(t.slug)||j[t.fsPath]}async function A(t){if(t.length===0)return;const r=(await Promise.all(t.map(async({items:g,locale:I,sidebarRelativePath:p,ignoredRoutes:L})=>{const a=await J(g,u.dirname(u.join(c,p)),o,s,{locale:I,ignoredRoutes:L,navFile:p,excludedFromLinkCheckerPatterns:_});if(!a){await k.panicOnBuild("Failed to resolve sidebar configuration. Make sure %rp is valid",p);return}return a}))).flat().filter(X),i=N(r,"routeSlug"),e=t[0].sidebarRelativePath,n=q(e),l=new Set;for(const g of i){const I=o.getRouteBySlug(g)?.fsPath??"",p=j[I];p&&(Array.from(l).find(a=>a.key===p.key&&a.version===p.version)||l.add(p)),o.addRouteSharedData(g,"sidebar",n),C.set(Y(g),r)}const h=l.size===1?Array.from(l)[0]:void 0;return await o.createSharedData(n,{relatedNavbarItem:Z?.get(e),items:r,catalogEntity:h?{key:h.key,version:h.version}:void 0}),{firstLink:M(r,g=>!!g.link),resolved:r}}async function z(t,m,r,i=!1){const e=structuredClone(m);r&&r!==v&&e.items.forEach(a=>{a.directory=u.posix.join(d.localizationFolder||"",r,a.directory||"")});let n=await J(e.items,c,o,s,{groupCustomSidebars:!0,locale:r,navFile:V,excludedFromLinkCheckerPatterns:_});if(n&&(n=wt(n)),!n){await k.panicOnBuild(`Failed to resolve catalog configuration. Make sure catalog ${t} has valid config`);return}const l=r===v?"":"/"+r.toLowerCase(),h=r===v?"":`-${r}`,g=Y(u.posix.join(l,e.slug));if(i)for(const a of n){const S=M(a.items||[],F=>!!F.routeSlug);if(!S?.routeSlug)continue;const y=C.get(S.routeSlug);if(!y)continue;const O=N(y,"routeSlug"),E="current-catalog-info-"+a.routeSlug+h,w={catalog:{label:e.title,titleTranslationKey:e.titleTranslationKey,link:g,icon:e?.icon},item:{label:a.metadata?.title,link:a.link,icon:a.icon}};await o.createSharedData(E,w);for(const F of O)o.addRouteSharedData(F,"current-catalog-info",E),D.add(F);const K=M(y,F=>!!F.link&&!F.external&&st(F.link)&&(!a.version||F.version===a.version));K&&(a.sidebar=[{...K,items:void 0}])}const I={},p=new Set;for(const a of n){if(!(a.routeSlug||a.sidebar?.[0]?.routeSlug)||!a.fsPath||p.has(a.fsPath))continue;p.add(a.fsPath);const y=u.dirname(a.fsPath);I[y]=(I[y]||0)+1}if(i){const a=await o.createSharedData("catalog-"+t+h,n.flatMap(S=>{const y=u.dirname(S.fsPath??""),O=I[y]===1,E=w=>({...w,fsPath:O?y:w.fsPath??""});return S.type==="group"&&S.items?.every(w=>w.type==="group")?(S.items||[]).map(E):E(S)}));o.addRouteSharedData(g,"catalog",a),Pt(r,n,G,I)}const L=N(n,"routeSlug");for(const a of L)D.add(a)}})}}}function Pt(c,o,s,f){if(c===v)for(const d of o){const b=d.routeSlug||d.sidebar?.[0]?.routeSlug;if(!b||!d.fsPath)continue;const C=u.dirname(d.fsPath),D=f[C]===1;s.set(b,{rootFileFsPath:d.fsPath,fsPath:D?C:d.fsPath,metadata:d.metadata||{},title:d.metadata?.title||d.label||"Untitled",version:d.version||"latest"})}}function wt(c){const o=s=>{if(!s)return s;const f=et.parse(s);return dt([f])};return c.map(s=>{const f={...s};return f.metadata?.description&&(f.metadata={...f.metadata,description:o(f.metadata.description)}),f})}function q(c){return at+lt(c)}async function Zt(c,o,s){const f=u.posix.join(u.dirname(c),o);return await s.exists(f)?q(f):(await k.panicOnBuildContentErrorForRealFile("File %rp: Failed to create relative path for sidebars.yaml using %s",c,s,c,o),null)}function vt(c){const o=c.replaceAll("/","_");if(o.length>bt){const s=o.slice(0,Ct),f=ft(c).slice(0,Dt).replaceAll("/","_");return s+f}else return o}export{wt as removeMarkdownTags,Zt as resolveSidebarId,Qt as sidebarsPlugin};
@@ -1,4 +1,4 @@
1
- import{withPathPrefix as p}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as y}from"../../constants/common.js";import{RUNTIME_RESOURCES_DIR as E}from"../constants/common.js";import{INIT_BROWSER_HOOKS_SCRIPT as R}from"./init-browser-hooks-script.js";const _="";function w({bodyHtml:r,linkTags:i,title:m,favicon:e,preload:n,headScriptTags:$,postBodyScriptTags:s,preBodyScriptTags:l,lang:t,productClass:o,fonts:a=_,runtimeCss:h}){const c=t&&t!=y?` lang="${t}"`:"",d=o?` class="${o}"`:"";return`<!doctype html>
1
+ import{withPathPrefix as p}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as y}from"../../constants/common.js";import{RUNTIME_RESOURCES_DIR as E}from"../constants/common.js";import{INIT_BROWSER_HOOKS_SCRIPT as R}from"./init-browser-hooks-script.js";const _="";function w({bodyHtml:r,linkTags:i,title:m,favicon:e,preload:n,headScriptTags:$,postBodyScriptTags:l,preBodyScriptTags:s,lang:t,productClass:o,fonts:a=_,runtimeCss:h}){const c=t&&t!=y?` lang="${t}"`:' lang="en"',d=o?` class="${o}"`:"";return`<!doctype html>
2
2
  <html${c}${d}>
3
3
  <head>
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1">
@@ -17,9 +17,9 @@ import{withPathPrefix as p}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE
17
17
  ${h||""}
18
18
  </head>
19
19
  <body>
20
- ${l||""}
20
+ ${s||""}
21
21
  <div id="app_root">${r}</div>
22
22
  <script async type="module" src="${p(E)}/browser-entry.js"></script>
23
- ${s||""}
23
+ ${l||""}
24
24
  </body>
25
25
  </html>`}export{w as htmlTemplate};
@@ -14,12 +14,12 @@ export type LoggerContext = {
14
14
  };
15
15
  type LoggerOptions = {
16
16
  context?: LoggerContext;
17
- forceNonInteractive?: boolean;
17
+ allowInteractive?: boolean;
18
18
  minLogLevel?: LogLevel;
19
19
  };
20
20
  export declare class Logger {
21
21
  #private;
22
- constructor({ context, forceNonInteractive, minLogLevel }?: LoggerOptions);
22
+ constructor({ context, allowInteractive, minLogLevel }?: LoggerOptions);
23
23
  shouldLog(level: LogLevel): boolean;
24
24
  info(message: string, ...args: unknown[]): void;
25
25
  infoTime(timingId: symbol | string, message: string, ...args: unknown[]): {
@@ -1,2 +1,2 @@
1
- import{telemetry as c}from"../../telemetry/index.js";import{envConfig as l}from"../../config/env-config.js";import h,{LogLevel as r,shouldLog as m,parseLogLevel as u}from"./formatter.js";import{isVirtualFile as f}from"../../fs/utils/isVirtualFile.js";import{TerminalManager as g}from"./terminal-manager.js";class p{#e;#l;#i;#n;#r=new Map;#o=new Map;constructor({context:t,forceNonInteractive:e,minLogLevel:i}={}){this.#e=t,this.#l=l.isProductionEnv,this.#i=new g(e),this.#n=i??u(l.REDOCLY_LOG_LEVEL)??(l.isDevelopMode?r.INFO:r.HTTP)}shouldLog(t){return m(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=h.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(!m(t,this.#n))return;let s=e&&h.interpolate(e,...n);s&&i!=null&&t!==r.VERBOSE&&c.sendTimingPerformedMessage([{object:"timing",timeMs:i,message:s}]);const a={level:t,message:s,duration:i,scope:o,context:this.#e};process.stderr.write(h.format(a))}}const R=new p;export{p as Logger,R as logger};
1
+ import{telemetry as c}from"../../telemetry/index.js";import{envConfig as l}from"../../config/env-config.js";import h,{LogLevel as r,shouldLog as m,parseLogLevel as u}from"./formatter.js";import{isVirtualFile as f}from"../../fs/utils/isVirtualFile.js";import{TerminalManager as g}from"./terminal-manager.js";class p{#e;#l;#i;#n;#r=new Map;#o=new Map;constructor({context:t,allowInteractive:e,minLogLevel:i}={}){this.#e=t,this.#l=l.isProductionEnv,this.#i=new g(e),this.#n=i??u(l.REDOCLY_LOG_LEVEL)??(l.isDevelopMode?r.INFO:r.HTTP)}shouldLog(t){return m(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=h.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(!m(t,this.#n))return;let s=e&&h.interpolate(e,...n);s&&i!=null&&t!==r.VERBOSE&&c.sendTimingPerformedMessage([{object:"timing",timeMs:i,message:s}]);const a={level:t,message:s,duration:i,scope:o,context:this.#e};process.stderr.write(h.format(a))}}const R=new p({allowInteractive:!0});export{p as Logger,R as logger};
@@ -1,6 +1,6 @@
1
1
  export declare class TerminalManager {
2
2
  #private;
3
- constructor(forceNonInteractive?: boolean);
3
+ constructor(allowInteractive?: boolean);
4
4
  isInteractive(): boolean;
5
5
  isFooterChanged(id: string, content: string): boolean;
6
6
  updateFooter(id: string, content: string): void;
@@ -1,6 +1,6 @@
1
- import{envConfig as p}from"../../config/env-config.js";import{gray as w}from"./helpers/colors.js";const t="\x1B[",f=`${t}6n`,i=`${t}s`,c=`${t}u`,l=`${t}J`,h=n=>`${t}1;${n}r`,d=`${t}r`,u=`${t}?25h`,R=`${t}?25l`,I=()=>`${w("\u2500".repeat(process.stderr.columns||80))}
1
+ import{envConfig as p}from"../../config/env-config.js";import{gray as w}from"./helpers/colors.js";const t="\x1B[",l=`${t}6n`,i=`${t}s`,c=`${t}u`,f=`${t}J`,h=n=>`${t}1;${n}r`,d=`${t}r`,u=`${t}?25h`,R=`${t}?25l`,I=()=>`${w("\u2500".repeat(process.stderr.columns||80))}
2
2
 
3
- `,g=3;class T{#s=new Map;#t=process.stderr.rows;#o=0;#i=!1;#c=!1;#r;constructor(s=!1){this.#c=s,this.#a(),this.isInteractive()&&process.stderr.write(f)}isInteractive(){return!!(!this.#c&&process.stderr&&process.stderr.isTTY&&p.TERM!=="dumb"&&!("CI"in process.env)&&p.isDevelopMode)}isFooterChanged(s,r){return this.#s.get(s)!==r}updateFooter(s,r){const e=!this.#s.has(s);this.#s.set(s,r),this.isInteractive()&&(e?this.#p():this.#n())}get#e(){if(this.#s.size===0)return 0;let s=g;for(const r of this.#s.values())s+=(r.match(/\n/g)||[]).length;return s}#n(){if(!this.isInteractive()||this.#s.size===0||!this.#r)return;this.#h();const s=this.#e,r=process.stderr.rows;if(!(s>r)){process.stderr.write(i),process.stderr.cursorTo(0,r-s-1),process.stderr.write(l),process.stderr.cursorTo(0,r-s+1),process.stderr.write(I());for(const e of this.#s.values())process.stderr.write(e);process.stderr.write(c)}}#p(s=0){if(!this.isInteractive())return;const r=process.stderr.rows;let e=this.#e;e>r&&(e=0);const o=e-this.#o;this.#o=e,o>0&&(process.stderr.write(i),process.stderr.write(`
3
+ `,g=3;class T{#s=new Map;#t=process.stderr.rows;#o=0;#i=!1;#c=!1;#r;constructor(s=!1){this.#c=s,this.isInteractive()&&(this.#a(),process.stderr.write(l))}isInteractive(){return!!(this.#c&&process.stderr&&process.stderr.isTTY&&p.TERM!=="dumb"&&!("CI"in process.env)&&p.isDevelopMode)}isFooterChanged(s,r){return this.#s.get(s)!==r}updateFooter(s,r){const e=!this.#s.has(s);this.#s.set(s,r),this.isInteractive()&&(e?this.#p():this.#n())}get#e(){if(this.#s.size===0)return 0;let s=g;for(const r of this.#s.values())s+=(r.match(/\n/g)||[]).length;return s}#n(){if(!this.isInteractive()||this.#s.size===0||!this.#r)return;this.#h();const s=this.#e,r=process.stderr.rows;if(!(s>r)){process.stderr.write(i),process.stderr.cursorTo(0,r-s-1),process.stderr.write(f),process.stderr.cursorTo(0,r-s+1),process.stderr.write(I());for(const e of this.#s.values())process.stderr.write(e);process.stderr.write(c)}}#p(s=0){if(!this.isInteractive())return;const r=process.stderr.rows;let e=this.#e;e>r&&(e=0);const o=e-this.#o;this.#o=e,o>0&&(process.stderr.write(i),process.stderr.write(`
4
4
  `.repeat(o)),process.stderr.write(c)),process.stderr.write(i),s<0&&process.stderr.write(`
5
- `.repeat(e)),process.stderr.write(h(r-e)),process.stderr.write(c),this.#n()}#h(){this.#i||!this.#r||(this.#i=!0,this.#d(),process.stderr.write(R),process.on("exit",this.#w),process.stderr.on("resize",this.#f))}#d(){if(!this.#r)return;const s=process.stderr.rows,{row:r}=this.#r,e=this.#e,o=s-e;r<o||(process.stderr.write(i),process.stderr.write(d),process.stderr.cursorTo(0,s-1),process.stderr.write(`
6
- `.repeat(Math.max(0,r-e))),process.stderr.write(h(o)),process.stderr.write(c),process.stderr.cursorTo(0,0))}#a(){if(!this.isInteractive())return;process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8");const s=/\[(\d+);(\d+)R/;process.stdin.once("data",r=>{if(s.test(r)){const e=s.exec(r);if(e){const o=parseInt(e[1],10),a=parseInt(e[2],10);this.#r={row:o,col:a}}}process.stdin.setRawMode(!1)})}#w=()=>{this.isInteractive()&&(process.stderr.write(d),process.stderr.write(`${t}${process.stderr.rows};1H`),process.stderr.write(u))};#f=()=>{const s=process.stderr.rows-this.#t;this.#t=process.stderr.rows,this.#p(s)}}export{T as TerminalManager};
5
+ `.repeat(e)),process.stderr.write(h(r-e)),process.stderr.write(c),this.#n()}#h(){this.#i||!this.#r||(this.#i=!0,this.#d(),process.stderr.write(R),process.on("exit",this.#w),process.stderr.on("resize",this.#l))}#d(){if(!this.#r)return;const s=process.stderr.rows,{row:r}=this.#r,e=this.#e,o=s-e;r<o||(process.stderr.write(i),process.stderr.write(d),process.stderr.cursorTo(0,s-1),process.stderr.write(`
6
+ `.repeat(Math.max(0,r-e))),process.stderr.write(h(o)),process.stderr.write(c),process.stderr.cursorTo(0,0))}#a(){if(!this.isInteractive())return;process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf8");const s=/\[(\d+);(\d+)R/;process.stdin.once("data",r=>{if(s.test(r)){const e=s.exec(r);if(e){const o=parseInt(e[1],10),a=parseInt(e[2],10);this.#r={row:o,col:a}}}process.stdin.setRawMode(!1)})}#w=()=>{this.isInteractive()&&(process.stderr.write(d),process.stderr.write(`${t}${process.stderr.rows};1H`),process.stderr.write(u))};#l=()=>{const s=process.stderr.rows-this.#t;this.#t=process.stderr.rows,this.#p(s)}}export{T as TerminalManager};
@@ -1 +1 @@
1
- import{getCompleteCatalogConfig as w}from"../../../plugins/catalog-entities/get-complete-catalog-config.js";import{telemetryTraceStep as m}from"../../../telemetry/helpers/trace-step.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as h,ALLOWED_CATALOG_QUERY_PARAMS as T}from"../../../constants/plugins/catalog-entities.js";import{CATALOG_ENTITY_ID as E}from"../../../../constants/common.js";import{allowlistObject as b}from"../../../../utils/object/allowlist-object.js";import{isValidIsoDate as j}from"../../../utils/is-valid-iso-date.js";import{CatalogEntitiesService as _}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";import{createPaginationParamsValidator as q}from"../../../providers/database/pagination/schemas.js";import{createEntityRelationDtoFromFileSchema as O}from"../../../plugins/catalog-entities/database/mappers/create-entity-relation-dto-from-file-schema.js";import{CacheService as R}from"../../../persistence/cache/services/cache-service.js";import{hasAccessToEntity as f}from"./helpers/has-access-to-entity.js";import{getRbacRestrictionsDataForCatalog as p}from"../helpers/get-rbac-restrictions-data-for-catalog.js";import{mapEntityReadModelSchemaToEntityReadDto as g}from"./mappers/map-entity-read-model-schema-to-entity-read-dto.js";import{parseEntity as v}from"./parsers/entities/parse-entity.js";import{parseEntityUpdateData as C}from"./parsers/entities/parse-entity-update-data.js";import{parseEntities as F}from"./parsers/entities/parse-entities.js";const D=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"],A=async n=>{await(await R.getInstance({baseDbDir:n})).deleteByNamespace(h)},I=async({catalogEntitiesService:n,ctx:e,store:y})=>m("catalog_entities.get_entities",async i=>{const a=e.get("logger");try{const t=e.req.query();i?.setAttribute("queryParams",JSON.stringify(b(t,T)));const{currentRbacTeamsForRead:o,excludedTypes:r,excludedEntities:s}=p({store:y,ctx:e}),c=q(D).parse(t),u=await n.getEntities({paginationParams:c,rbacTeams:o,excludedTypes:r,excludedEntities:s});return i?.setAttribute("entitiesCount",u.items.length),e.json({...u,items:u.items.map(g)})}catch(t){return a.error(t),i?.error(t),e.json({message:"Failed to get entities"},500)}}),P=async({catalogEntitiesService:n,ctx:e,store:y})=>m("catalog_entities.get_entity",async i=>{const a=e.req.param(E);if(!a)return i?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);i?.setAttribute("pathParams",JSON.stringify({entityId:a}));const{currentRbacTeamsForRead:t,excludedTypes:o,excludedEntities:r}=p({store:y,ctx:e}),s=await n.getEntityById(a,{rbacTeams:t,excludedTypes:o,excludedEntities:r});return s?(i?.setAttribute("entity",JSON.stringify(s)),e.json(g(s))):(i?.error(new Error("Entity not found")),e.json({message:"Entity not found"},404))}),N=async({catalogEntitiesService:n,ctx:e,catalogConfig:y,serverOutDir:i,store:a})=>m("catalog_entities.create_entity",async t=>{const o=e.get("logger");try{const r=await e.req.json();t?.setAttribute("requestBody",JSON.stringify(r));const s=v(r,y);if(!f({ctx:e,store:a,accessLevel:"WRITE",entityType:s.type,entityKey:s.key}))return t?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const u=await n.createEntity(s),d=s.relations?.map(l=>O(s.key,l));return await n.createEntitiesRelations(d??[]),u?(A(i),t?.setAttribute("entity",JSON.stringify(u)),e.json(g(u))):(t?.error(new Error("Failed to create entity")),e.json({message:"Failed to create entity"},500))}catch(r){return o.error(r),r instanceof Error&&r.message.includes("validation failed")?(t?.error(new Error(r.message)),e.json({message:r.message},400)):(t?.error(r),e.json({message:"Failed to create entity"},500))}}),W=async({catalogEntitiesService:n,ctx:e,catalogConfig:y,serverOutDir:i,store:a})=>m("catalog_entities.bulk_upsert_entities",async t=>{const o=e.get("logger");try{const r=await e.req.json();t?.setAttribute("requestBody",JSON.stringify(r));const s=F(r,y);for(const d of s)if(!f({ctx:e,store:a,accessLevel:"WRITE",entityType:d.type,entityKey:d.key}))return t?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const c=await n.createEntities(s);if(!c.length)return t?.error(new Error("Failed to create entities")),e.json({message:"Failed to create entities"},500);A(i);const u=c.filter(d=>d.status==="ok");return t?.setAttribute("totalSuccess",u.length),t?.setAttribute("totalFailed",c.length-u.length),e.json(u.map(d=>({...d,resource:g(d.resource)})),207)}catch(r){return o.error(r),r instanceof Error&&r.message.includes("validation failed")?(t?.error(new Error(r.message)),e.json({message:r.message},400)):(t?.error(r),e.json({message:"Failed to create entities"},500))}}),k=async({catalogEntitiesService:n,ctx:e,catalogConfig:y,serverOutDir:i,store:a})=>m("catalog_entities.update_entity",async t=>{const o=e.get("logger"),r=e.req.param(E);if(!r)return t?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);t?.setAttribute("pathParams",JSON.stringify({entityId:r}));try{const s=await e.req.json();t?.setAttribute("requestBody",JSON.stringify(s));const c=await n.getEntityById(r);if(!c)return t?.error(new Error(`Entity with id: ${r} not found`)),e.json({message:`Entity with id: ${r} not found`},404);if(!f({ctx:e,store:a,accessLevel:"WRITE",entityType:s.type??c.type,entityKey:s.key??c.key}))return t?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const d=C(s,y,s?.type??c.type);if(d.revision&&!j(d.revision))throw new Error("Entity validation failed: 'entity.revision' must be a valid ISO 8601 date-time string");const l=await n.updateEntity(d,c);return l?(A(i),t?.setAttribute("entity",JSON.stringify(l)),e.json(g(l))):(t?.error(new Error("Failed to update entity")),e.json({message:"Failed to update entity"},500))}catch(s){return o.error(s),s instanceof Error&&s.message.includes("validation failed")?(t?.error(new Error(s.message)),e.json({message:s.message},400)):(t?.error(s),e.json({message:s.message},500))}}),L=async({catalogEntitiesService:n,ctx:e,serverOutDir:y,store:i})=>m("catalog_entities.delete_entity",async a=>{const t=e.req.param(E);if(!t)return a?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);a?.setAttribute("pathParams",JSON.stringify({entityId:t}));const o=await n.getEntityById(t);return o?f({ctx:e,store:i,accessLevel:"WRITE",entityType:o.type,entityKey:o.key})?(await n.deleteEntity(o),A(y),new Response(null,{status:204})):(a?.error(new Error("Access denied")),e.json({message:"Access denied"},403)):new Response(null,{status:204})}),J={GET:I,POST:N,PUT:W},B={GET:P,DELETE:L,PATCH:k};function re(n){return async e=>m("catalog_entities",async y=>{const i=await _.getInstance({baseDbDir:n.serverOutDir}),a=e.req.method;y?.setAttribute("method",a);const t=e.req.param(E)?B:J,o=w(n.config.entitiesCatalog),r=t[a];return r?await r({catalogEntitiesService:i,ctx:e,catalogConfig:o,serverOutDir:n.serverOutDir,store:n}):(y?.error(new Error("Method not allowed")),e.json({message:"Method not allowed"},405))})}export{re as catalogHandler};
1
+ import{getCompleteCatalogConfig as j}from"../../../plugins/catalog-entities/get-complete-catalog-config.js";import{telemetryTraceStep as m}from"../../../telemetry/helpers/trace-step.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as b,ALLOWED_CATALOG_QUERY_PARAMS as F}from"../../../constants/plugins/catalog-entities.js";import{CATALOG_ENTITY_ID as f}from"../../../../constants/common.js";import{allowlistObject as _}from"../../../../utils/object/allowlist-object.js";import{isValidIsoDate as R}from"../../../utils/is-valid-iso-date.js";import{CatalogEntitiesService as q}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";import{createPaginationParamsValidator as I}from"../../../providers/database/pagination/schemas.js";import{createEntityRelationDtoFromFileSchema as O}from"../../../plugins/catalog-entities/database/mappers/create-entity-relation-dto-from-file-schema.js";import{CacheService as C}from"../../../persistence/cache/services/cache-service.js";import{hasAccessToEntity as w}from"./helpers/has-access-to-entity.js";import{getRbacRestrictionsDataForCatalog as T}from"../helpers/get-rbac-restrictions-data-for-catalog.js";import{mapEntityReadModelSchemaToEntityReadDto as g}from"./mappers/map-entity-read-model-schema-to-entity-read-dto.js";import{parseEntity as D}from"./parsers/entities/parse-entity.js";import{parseEntityUpdateData as P}from"./parsers/entities/parse-entity-update-data.js";import{parseEntities as v}from"./parsers/entities/parse-entities.js";import{upsertPagesStats as h}from"./helpers/upsert-pages-stats.js";const N=["type","key","title","summary","tags","metadata","metadata.*","git","contact","links","id","source","sourceFile","createdAt","updatedAt"],A=async n=>{await(await C.getInstance({baseDbDir:n})).deleteByNamespace(b)},W=async({catalogEntitiesService:n,ctx:e,store:u})=>m("catalog_entities.get_entities",async o=>{const i=e.get("logger");try{const r=e.req.query();o?.setAttribute("queryParams",JSON.stringify(_(r,F)));const{currentRbacTeamsForRead:d,excludedTypes:t,excludedEntities:s}=T({store:u,ctx:e}),c=I(N).parse(r),y=await n.getEntities({paginationParams:c,rbacTeams:d,excludedTypes:t,excludedEntities:s});return o?.setAttribute("entitiesCount",y.items.length),e.json({...y,items:y.items.map(g)})}catch(r){return i.error(r),o?.error(r),e.json({message:"Failed to get entities"},500)}}),k=async({catalogEntitiesService:n,ctx:e,store:u})=>m("catalog_entities.get_entity",async o=>{const i=e.req.param(f);if(!i)return o?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);o?.setAttribute("pathParams",JSON.stringify({entityId:i}));const{currentRbacTeamsForRead:r,excludedTypes:d,excludedEntities:t}=T({store:u,ctx:e}),s=await n.getEntityById(i,{rbacTeams:r,excludedTypes:d,excludedEntities:t});return s?(o?.setAttribute("entity",JSON.stringify(s)),e.json(g(s))):(o?.error(new Error("Entity not found")),e.json({message:"Entity not found"},404))}),L=async({catalogEntitiesService:n,ctx:e,catalogConfig:u,serverOutDir:o,store:i})=>m("catalog_entities.create_entity",async r=>{const d=e.get("logger");try{const t=await e.req.json();r?.setAttribute("requestBody",JSON.stringify(t));const s=D(t,u);if(!w({ctx:e,store:i,accessLevel:"WRITE",entityType:s.type,entityKey:s.key}))return r?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const y=await n.remoteTransaction(async()=>{const a=await n.createEntity(s),l=s.relations?.map(E=>O(s.key,E));return await n.createEntitiesRelations(l??[]),await h({ctx:e,catalogEntitiesService:n,addedEntities:a?[a]:void 0}),a});return y?(A(o),r?.setAttribute("entity",JSON.stringify(y)),e.json(g(y))):(r?.error(new Error("Failed to create entity")),e.json({message:"Failed to create entity"},500))}catch(t){return d.error(t),t instanceof Error&&t.message.includes("validation failed")?(r?.error(new Error(t.message)),e.json({message:t.message},400)):(r?.error(t),e.json({message:"Failed to create entity"},500))}}),J=async({catalogEntitiesService:n,ctx:e,catalogConfig:u,serverOutDir:o,store:i})=>m("catalog_entities.bulk_upsert_entities",async r=>{const d=e.get("logger");try{const t=await e.req.json();r?.setAttribute("requestBody",JSON.stringify(t));const s=v(t,u);for(const a of s)if(!w({ctx:e,store:i,accessLevel:"WRITE",entityType:a.type,entityKey:a.key}))return r?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const c=await n.remoteTransaction(async()=>{const a=await n.createEntities(s),l=a.reduce((E,p)=>(p.status==="ok"&&p.resource!=null&&E.push(p.resource),E),[]);return await h({ctx:e,catalogEntitiesService:n,addedEntities:l}),a});if(!c.length)return r?.error(new Error("Failed to create entities")),e.json({message:"Failed to create entities"},500);A(o);const y=c.filter(a=>a.status==="ok");return r?.setAttribute("totalSuccess",y.length),r?.setAttribute("totalFailed",c.length-y.length),e.json(y.map(a=>({...a,resource:g(a.resource)})),207)}catch(t){return d.error(t),t instanceof Error&&t.message.includes("validation failed")?(r?.error(new Error(t.message)),e.json({message:t.message},400)):(r?.error(t),e.json({message:"Failed to create entities"},500))}}),B=async({catalogEntitiesService:n,ctx:e,catalogConfig:u,serverOutDir:o,store:i})=>m("catalog_entities.update_entity",async r=>{const d=e.get("logger"),t=e.req.param(f);if(!t)return r?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);r?.setAttribute("pathParams",JSON.stringify({entityId:t}));try{const s=await e.req.json();r?.setAttribute("requestBody",JSON.stringify(s));const c=await n.getEntityById(t);if(!c)return r?.error(new Error(`Entity with id: ${t} not found`)),e.json({message:`Entity with id: ${t} not found`},404);if(!w({ctx:e,store:i,accessLevel:"WRITE",entityType:s.type??c.type,entityKey:s.key??c.key}))return r?.error(new Error("Access denied")),e.json({message:"Access denied"},403);const a=P(s,u,s?.type??c.type);if(a.revision&&!R(a.revision))throw new Error("Entity validation failed: 'entity.revision' must be a valid ISO 8601 date-time string");const l=await n.updateEntity(a,c);return l?(A(o),r?.setAttribute("entity",JSON.stringify(l)),e.json(g(l))):(r?.error(new Error("Failed to update entity")),e.json({message:"Failed to update entity"},500))}catch(s){return d.error(s),s instanceof Error&&s.message.includes("validation failed")?(r?.error(new Error(s.message)),e.json({message:s.message},400)):(r?.error(s),e.json({message:s.message},500))}}),U=async({catalogEntitiesService:n,ctx:e,serverOutDir:u,store:o})=>m("catalog_entities.delete_entity",async i=>{const r=e.get("logger"),d=e.req.param(f);if(!d)return i?.error(new Error("Entity id is required")),e.json({message:"Entity id is required"},400);i?.setAttribute("pathParams",JSON.stringify({entityId:d}));try{const t=await n.getEntityById(d);return t?w({ctx:e,store:o,accessLevel:"WRITE",entityType:t.type,entityKey:t.key})?await n.remoteTransaction(async()=>{const y=await n.deleteEntity(t);return y?(await h({ctx:e,catalogEntitiesService:n,removedEntities:t?[t]:void 0}),y):null})?(A(u),new Response(null,{status:204})):(i?.error(new Error("Failed to delete entity")),e.json({message:"Failed to delete entity"},500)):(i?.error(new Error("Access denied")),e.json({message:"Access denied"},403)):new Response(null,{status:204})}catch(t){return r.error(t),i?.error(t),e.json({message:"Failed to delete entity"},500)}}),G={GET:W,POST:L,PUT:J},H={GET:k,DELETE:U,PATCH:B};function oe(n){return async e=>m("catalog_entities",async u=>{const o=await q.getInstance({baseDbDir:n.serverOutDir}),i=e.req.method;u?.setAttribute("method",i);const r=e.req.param(f)?H:G,d=j(n.config.entitiesCatalog),t=r[i];return t?await t({catalogEntitiesService:o,ctx:e,catalogConfig:d,serverOutDir:n.serverOutDir,store:n}):(u?.error(new Error("Method not allowed")),e.json({message:"Method not allowed"},405))})}export{oe as catalogHandler};
@@ -0,0 +1,12 @@
1
+ import type { Context } from 'hono';
2
+ import type { CatalogEntitiesService } from '../../../../plugins/catalog-entities/database/catalog-entities-service';
3
+ import type { EntityReadModelSchema } from '../../../../plugins/catalog-entities/schemas/read-model-schemas';
4
+ type UpsertPagesStatsParams = {
5
+ ctx: Context;
6
+ catalogEntitiesService: CatalogEntitiesService;
7
+ addedEntities?: EntityReadModelSchema[];
8
+ removedEntities?: EntityReadModelSchema[];
9
+ };
10
+ export declare function upsertPagesStats({ ctx, catalogEntitiesService, addedEntities, removedEntities, }: UpsertPagesStatsParams): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=upsert-pages-stats.d.ts.map
@@ -0,0 +1 @@
1
+ import{envConfig as t}from"../../../../config/env-config.js";async function f({ctx:o,catalogEntitiesService:r,addedEntities:s,removedEntities:n}){if(t.REDOCLY_ENV!=="production"){o.get("logger").info("Skipping pages stats upsert in non-production environment");return}if(!t.BH_API_URL||!t.ORGANIZATION_ID||!t.PROJECT_ID)throw new Error("Pages stats service not configured");const a=o.req.header("apiKey");if(!a)throw new Error("API key is required to upsert pages stats");const{total:i}=await r.getDuplicatedEntitiesCount(s,n),{total:p}=await r.getEntitiesCount("remote",s,n?.length),g={remoteEntityPages:p,duplicatedEntityPages:i,isReported:!1},c=new URL(`/api/orgs/${t.ORGANIZATION_ID}/projects/${t.PROJECT_ID}/project-pages-stats`,t.BH_API_URL).toString();try{const e=await fetch(c,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`},body:JSON.stringify(g)});if(!e.ok)throw new Error(e.statusText)}catch(e){throw new Error(`Failed to upsert project pages stats: ${e?.message}`)}}export{f as upsertPagesStats};
@@ -1,2 +1,2 @@
1
- import{withPathPrefix as O}from"@redocly/theme/core/utils";import{ServerRoutes as _}from"../../../constants/common.js";import{getRequestOrigin as q}from"../utils/get-request-origin.js";const C=new Set(["connection","keep-alive","proxy-authenticate","proxy-connection","proxy-authorization","te","trailer","transfer-encoding","upgrade","host"]),P=new Set(["cookie","cookie2"]),T=new Set(["set-cookie","set-cookie2"]),E="x-redocly-proxy-streaming",H="x-http-method-override",w="x-redocly-cookie";function x(o=O(_.CORS_PROXY)){return async e=>{const r=new URL(e.req.url).pathname;if(r===o||r===`${o}/`)return e.text(`Realm CORS proxy endpoint.
2
- Usage: ${o}/https://api.example.com/path`);const n=L(e.req.url,o);if(!n)return e.text("Invalid proxied URL",400);const i=q(e),c=n.origin===i,h=n.pathname===o||n.pathname.startsWith(`${o}/`);if(c&&!h)return new Response("Please use a direct request",{status:308,headers:{Location:n.toString(),Vary:"origin","Cache-Control":"private"}});const s=new Headers,f=S(e.req.raw.headers);for(const[t,y]of e.req.raw.headers)f.has(t.toLowerCase())||P.has(t.toLowerCase())||s.append(t,y);const d=s.get(w);if(d){const t=e.req.raw.headers.get("cookie")||"";s.set("cookie",t?`${t}; ${d}`:d),s.delete(w)}const u=e.req.raw.headers.get("origin")||"";A(u)&&s.delete("origin");let p=e.req.method;const m=s.get(H);m&&(p=m.toUpperCase(),s.delete(H));const R={method:p,headers:s,redirect:"follow"};p!=="GET"&&p!=="HEAD"&&e.req.raw.body&&(R.body=e.req.raw.body,R.duplex="half");let a;try{a=await fetch(n,R)}catch(t){return e.text(`Failed to proxy request: ${t instanceof Error?t.message:"unknown error"}`,502)}const l=new Headers(a.headers),g=S(a.headers);for(const t of g)l.delete(t);for(const t of T)l.delete(t);return l.set(E,"1"),new Response(a.body,{status:a.status,statusText:a.statusText,headers:l})}}function k(o){try{return decodeURIComponent(o)}catch{return o}}function D(o){return o.replace(/^(https?):\/(?!\/)/i,"$1://")}function $(o,e){return e?o.includes("?")?e==="?"?o:`${o.endsWith("?")||o.endsWith("&")?o:`${o}&`}${e.slice(1)}`:`${o}${e}`:o}function S(o){const e=new Set(C),r=o.get("connection");if(!r)return e;for(const n of r.split(",")){const i=n.trim().toLowerCase();i&&e.add(i)}return e}function A(o){const e=o.toLowerCase();return e.includes(".redocly.app")||e.includes("localhost")}function L(o,e){const r=new URL(o),n=r.pathname===e,i=r.pathname.startsWith(`${e}/`);if(!n&&!i)return null;const c=r.pathname.slice(e.length).replace(/^\/+/,"");if(!c)return null;const h=[c,k(c)];for(const s of h){const f=D(s),d=$(f,r.search);try{const u=new URL(d);if(u.protocol==="http:"||u.protocol==="https:")return u}catch{continue}}return null}const z=E;export{z as CORS_PROXY_STREAM_HEADER,x as corsProxyHandler,L as resolveCorsProxyTarget};
1
+ import{withPathPrefix as _}from"@redocly/theme/core/utils";import{ServerRoutes as q}from"../../../constants/common.js";import{getRequestOrigin as C}from"../utils/get-request-origin.js";const P=new Set(["connection","keep-alive","proxy-authenticate","proxy-connection","proxy-authorization","te","trailer","transfer-encoding","upgrade","host"]),$=new Set(["cookie","cookie2","accept-encoding"]),T=new Set(["set-cookie","set-cookie2","content-encoding","content-length"]),g="x-redocly-proxy-streaming",H="x-http-method-override",w="x-redocly-cookie";function z(o=_(q.CORS_PROXY)){return async e=>{const n=new URL(e.req.url).pathname;if(n===o||n===`${o}/`)return e.text(`Realm CORS proxy endpoint.
2
+ Usage: ${o}/https://api.example.com/path`);const r=I(e.req.url,o);if(!r)return e.text("Invalid proxied URL",400);const i=C(e),c=r.origin===i,h=r.pathname===o||r.pathname.startsWith(`${o}/`);if(c&&!h)return new Response("Please use a direct request",{status:308,headers:{Location:r.toString(),Vary:"origin","Cache-Control":"private"}});const s=new Headers,f=S(e.req.raw.headers);for(const[t,E]of e.req.raw.headers)f.has(t.toLowerCase())||$.has(t.toLowerCase())||s.append(t,E);const d=s.get(w);if(d){const t=e.req.raw.headers.get("cookie")||"";s.set("cookie",t?`${t}; ${d}`:d),s.delete(w)}const u=e.req.raw.headers.get("origin")||"";L(u)&&s.delete("origin");let p=e.req.method;const R=s.get(H);R&&(p=R.toUpperCase(),s.delete(H));const m={method:p,headers:s,redirect:"follow"};p!=="GET"&&p!=="HEAD"&&e.req.raw.body&&(m.body=e.req.raw.body,m.duplex="half");let a;try{a=await fetch(r,m)}catch(t){const E=t instanceof Error?t.message:"unknown error",O=t instanceof Error&&t.cause instanceof Error?`: ${t.cause.message}`:"";return e.text(`Failed to proxy request: ${E}${O}`,502)}const l=new Headers(a.headers),y=S(a.headers);for(const t of y)l.delete(t);for(const t of T)l.delete(t);return l.set(g,"1"),new Response(a.body,{status:a.status,statusText:a.statusText,headers:l})}}function k(o){try{return decodeURIComponent(o)}catch{return o}}function D(o){return o.replace(/^(https?):\/(?!\/)/i,"$1://")}function A(o,e){return e?o.includes("?")?e==="?"?o:`${o.endsWith("?")||o.endsWith("&")?o:`${o}&`}${e.slice(1)}`:`${o}${e}`:o}function S(o){const e=new Set(P),n=o.get("connection");if(!n)return e;for(const r of n.split(",")){const i=r.trim().toLowerCase();i&&e.add(i)}return e}function L(o){const e=o.toLowerCase();return e.includes(".redocly.app")||e.includes("localhost")}function I(o,e){const n=new URL(o),r=n.pathname===e,i=n.pathname.startsWith(`${e}/`);if(!r&&!i)return null;const c=n.pathname.slice(e.length).replace(/^\/+/,"");if(!c)return null;const h=[c,k(c)];for(const s of h){const f=D(s),d=A(f,n.search);try{const u=new URL(d);if(u.protocol==="http:"||u.protocol==="https:")return u}catch{continue}}return null}const U=g;export{U as CORS_PROXY_STREAM_HEADER,z as corsProxyHandler,I as resolveCorsProxyTarget};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/redoc",
3
- "version": "0.131.0-next.9",
3
+ "version": "0.131.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,7 @@
29
29
  "@opentelemetry/sdk-trace-web": "2.0.1",
30
30
  "@opentelemetry/semantic-conventions": "1.34.0",
31
31
  "@redocly/ajv": "8.18.0",
32
- "@redocly/openapi-core": "2.20.1",
32
+ "@redocly/openapi-core": "2.20.5",
33
33
  "@shikijs/transformers": "3.21.0",
34
34
  "@tanstack/react-query": "5.62.3",
35
35
  "@tanstack/react-table": "8.21.3",
@@ -51,7 +51,7 @@
51
51
  "fetch-to-node": "^2.1.0",
52
52
  "fflate": "0.7.4",
53
53
  "flexsearch": "0.7.43",
54
- "graphql": "16.9.0",
54
+ "graphql": "16.12.0",
55
55
  "gray-matter": "4.0.3",
56
56
  "hono": "4.11.10",
57
57
  "htmlparser2": "8.0.2",
@@ -64,7 +64,7 @@
64
64
  "nanoid": "5.0.9",
65
65
  "node-fetch": "3.3.1",
66
66
  "nprogress": "0.2.0",
67
- "openapi-sampler": "1.7.0",
67
+ "openapi-sampler": "^1.7.2",
68
68
  "os-browserify": "0.3.0",
69
69
  "path-browserify": "1.0.1",
70
70
  "picomatch": "2.3.1",
@@ -91,14 +91,14 @@
91
91
  "xpath": "0.0.34",
92
92
  "yaml-ast-parser": "0.0.43",
93
93
  "zod": "^3.25.76",
94
- "@redocly/asyncapi-docs": "1.8.0-next.6",
95
- "@redocly/config": "0.44.0",
96
- "@redocly/graphql-docs": "1.8.0-next.5",
97
- "@redocly/openapi-docs": "3.19.0-next.6",
98
- "@redocly/portal-legacy-ui": "0.14.0-next.0",
99
- "@redocly/portal-plugin-mock-server": "0.16.0-next.6",
100
- "@redocly/realm-asyncapi-sdk": "0.9.0-next.3",
101
- "@redocly/theme": "0.63.0-next.4"
94
+ "@redocly/portal-legacy-ui": "0.14.0",
95
+ "@redocly/config": "0.44.1",
96
+ "@redocly/portal-plugin-mock-server": "0.16.0",
97
+ "@redocly/realm-asyncapi-sdk": "0.9.0",
98
+ "@redocly/asyncapi-docs": "1.8.0",
99
+ "@redocly/theme": "0.63.0",
100
+ "@redocly/graphql-docs": "1.8.0",
101
+ "@redocly/openapi-docs": "3.19.0"
102
102
  },
103
103
  "peerDependencies": {
104
104
  "react": "^19.2.4",
@@ -1 +0,0 @@
1
- import{detectSpec as m,getTypes as f,normalizeTypes as d,normalizeVisitors as u,resolveDocument as w,BaseResolver as h,StatsOAS as S,walkDocument as y}from"@redocly/openapi-core";import{logger as l}from"../../../server/tools/notifiers/logger.js";import{envConfig as g}from"../../../server/config/env-config.js";import{telemetryTraceStep as D}from"../../telemetry/helpers/trace-step.js";import{telemetry as I}from"../../telemetry/index.js";const t={refs:{metric:"References",total:0,color:"red",items:new Set},externalDocs:{metric:"External Documents",total:0,color:"magenta"},schemas:{metric:"Schemas",total:0,color:"white"},parameters:{metric:"Parameters",total:0,color:"yellow",items:new Set},links:{metric:"Links",total:0,color:"cyan",items:new Set},pathItems:{metric:"Path Items",total:0,color:"green"},webhooks:{metric:"Webhooks",total:0,color:"green"},operations:{metric:"Operations",total:0,color:"yellow"},tags:{metric:"Tags",total:0,color:"white",items:new Set}};async function T(s,a){await D("stats.openapi",async()=>{l.info("OpenAPI collector: start processing documents...");const e=(await s.cache.load(".","load-oas-docs")).data,o=[];for(const r of e)if(!r.isVirtual){const n=await v(r);o.push(n),I.sendStatsOpenapiCollectedMessage([{...n,projectBuildId:g.PROJECT_BUILD_ID||""}])}a||console.table(o),l.info("OpenAPI collector: openapi docments processing completed.")})}async function v(s){const a=s.definition,e=m(a),o=d(f(e)),r=u([{severity:"warn",ruleId:"openapi_stats",visitor:S(t)}],o),n={problems:[],specVersion:e,visitorsData:{}},c={source:{absoluteRef:""},parsed:a},i=o.Root;if(!i)throw new Error("Root type not found in OpenAPI spec types");const p=await w({rootDocument:c,rootType:i,externalRefResolver:new h});return y({rootType:i,normalizedVisitors:r,resolvedRefMap:p,document:c,ctx:n}),{path:s.relativePath,refs:t.refs.total,externalDocs:t.externalDocs.total,schemas:t.schemas.total,parameters:t.parameters.total,links:t.links.total,pathItems:t.pathItems.total,webhooks:t.webhooks.total,operations:t.operations.total,tags:t.tags.total,version:e}}export{T as collectOpenapiDocumentsStatistics};