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

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 (29) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/stats/collectors/openapi.d.ts +3 -0
  4. package/dist/cli/stats/collectors/openapi.js +1 -0
  5. package/dist/cli/stats/index.d.ts +7 -0
  6. package/dist/cli/stats/index.js +1 -0
  7. package/dist/cli/stats/options.d.ts +3 -0
  8. package/dist/cli/stats/options.js +1 -0
  9. package/dist/cli/telemetry/index.d.ts +1 -1
  10. package/dist/cli/telemetry/index.js +1 -1
  11. package/dist/client/app/Sidebar/Sidebar.js +1 -1
  12. package/dist/server/fs/cache.js +1 -1
  13. package/dist/server/plugins/asyncapi-docs/get-server-props.js +1 -1
  14. package/dist/server/plugins/asyncapi-docs/index.js +1 -1
  15. package/dist/server/plugins/catalog-entities/database/mappers/map-entity-relation-row.js +1 -1
  16. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +5 -3
  17. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  18. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -1
  19. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  20. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  21. package/dist/server/plugins/markdown/compiler.d.ts +1 -0
  22. package/dist/server/plugins/markdown/compiler.js +1 -1
  23. package/dist/server/plugins/openapi-docs/get-server-props.js +1 -1
  24. package/dist/server/plugins/openapi-docs/index.js +1 -1
  25. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js +1 -1
  26. package/dist/server/store.d.ts +6 -2
  27. package/dist/server/store.js +1 -1
  28. package/dist/server/types/plugins/common.d.ts +1 -0
  29. package/package.json +6 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @redocly/revel
2
2
 
3
+ ## 0.130.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 6238b833f0: Fixed sidebar header layout issue.
8
+
9
+ ### Patch Changes
10
+
11
+ - 134e0817c3: Fixed an issue where project processing could halt indefinitely due to incorrect cache handling.
12
+ - 8e31351cfa: Updated `@redocly/openapi-core` to version `2.14.5`.
13
+ - Updated dependencies [8e31351cfa]
14
+ - Updated dependencies [39d177b9b6]
15
+ - @redocly/openapi-docs@3.18.0-next.1
16
+ - @redocly/realm-asyncapi-sdk@0.8.0-next.1
17
+ - @redocly/asyncapi-docs@1.7.0-next.1
18
+ - @redocly/portal-plugin-mock-server@0.15.0-next.1
19
+ - @redocly/theme@0.62.0-next.0
20
+
21
+ ## 0.130.0-next.1
22
+
23
+ ### Patch Changes
24
+
25
+ - 1bc7e35d32: Fixed API docs performance issues in projects that use Markdoc partial tags.
26
+
3
27
  ## 0.130.0-next.0
4
28
 
5
29
  ### Patch Changes
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import"./cli/utils/node-version-check.js";import n from"mri";import*as r from"node:path";import{tmpdir as P}from"node:os";import*as A from"node:fs";import"./server/node-fetch-polyfill.js";import{cliCommandNames as g}from"./constants/common.js";import{initPlugins as x}from"./server/plugins/lifecycle.js";import{loadEnvVariables as T}from"./server/utils/envs/load-env-variables.js";import{PORTAL_VERSION as y}from"./server/version.js";import{logger as p}from"./server/tools/notifiers/logger.js";import{reporter as o}from"./server/tools/notifiers/reporter.js";import{sha as R}from"./server/utils/crypto/sha.js";import{develop as S}from"./cli/develop.js";import{eject as k}from"./cli/eject/index.js";import{beforeCommand as w}from"./server/utils/lifecycle-hooks.js";import{Store as C}from"./server/store.js";import{prepare as V}from"./cli/prepare/index.js";import{fromCurrentDir as I}from"./server/utils/paths.js";import{translationsCliOpts as L}from"./cli/translations/options.js";import{generateTranslations as M}from"./cli/translations/index.js";import{EntitlementsProvider as N}from"./server/entitlements/entitlements-provider.js";import{isValidPlan as _}from"./server/entitlements/is-valid-plan.js";import{stopAllCompilers as F}from"./server/esbuild/esbuild.js";import{copyLibsqlPrebuiltBinary as U}from"./cli/prepare/libsql/copy-prebuilt-binary.js";import{telemetry as d}from"./cli/telemetry/index.js";const s=process.argv[2];let t;const f={alias:{d:"project-dir",p:"port"},default:{"project-dir":process.env.REDOCLY_CONTENT_DIR||process.cwd(),outdir:"public"}},$={alias:f.alias,default:{...f.default,plan:"enterprise"}},q={alias:{d:"prepareDir"},default:{prepareDir:"public"}},B={boolean:["force"],alias:{f:"force",d:"project-dir"},default:{"project-dir":process.cwd()}};process.on("uncaughtException",async function(e){e?.code==="ERR_INVALID_STATE"?console.log("Ignore premature close error"):(p.error("Uncaught exception occurred. Stopping compilers."),await F(),p.error("Exiting due to uncaught exception"),await o.panic(e))});try{s||await o.panicOnContentError("Command not specified.");const e=N.instance();switch(["prepare","build","serve"].includes(s)&&await e.init(),["eject","translate"].includes(s)&&await e.init({developModePlan:"enterprise"}),s){case"develop":case"preview":const i=n(process.argv.slice(3),$),E=r.resolve(i["project-dir"]),j=r.join(P(),"redocly-public-"+R(E)),l=i.plan.toLowerCase();_(l)||await o.panicOnContentError(`Invalid --plan argument value '${l}'.`),await e.init({developModePlan:l}),t=new C({contentDir:r.resolve(i["project-dir"]),outdir:j,serverOutDir:I(import.meta.url,"./server/esbuild/cache/server")}),await w(g.DEVELOP,i,t),await S(i,t);break;case"prepare":const a=n(process.argv.slice(3),f),u=r.resolve(r.join(a.outdir,"server"));t=new C({contentDir:r.resolve(a["project-dir"]),outdir:r.resolve(a.outdir,"client"),serverOutDir:u}),await w(g.PREPARE,a,t),U(u),await V(a,t);break;case"serve":T();const b=n(process.argv.slice(3),q),O=r.resolve(b.prepareDir);d.sendServeCliCommandExecutedMessage();const v=r.join(O,"server","index.mjs");A.existsSync(v)||await o.panic("Server not found. Please run `realm prepare` first"),import(v).catch(async c=>{await o.panic("Failed to load server",c)});break;case"eject":e.canAccessFeature("themeEjecting")||await o.panicOnContentError('The "eject" command is not available for this project');const m=n(process.argv.slice(3),B),{lifecycleContext:{getConfig:h,fs:D}}=await x({outdir:"",contentDir:r.resolve(m["project-dir"]),setGlobalConfig:()=>null});D.dispose(),d.sendCliCommandEjectExecutedMessage({arguments:m}),await k({...m,config:await h()}),p.clearAllTimeouts();break;case"translate":if(e.canAccessFeature("l10n")){const c=n(process.argv.slice(3),L);d.sendCliCommandTranslateExecutedMessage({arguments:c}),await M(c)}else await o.panicOnContentError('The "translate" command is not available for this project');break;case"--version":console.log(y);break;default:await o.panicOnContentError(`Unknown command "${s}"`)}}catch(e){p.error("Exiting due to uncaught exception"),await o.panic(e)}
2
+ import"./cli/utils/node-version-check.js";import o from"mri";import*as r from"node:path";import{tmpdir as A}from"node:os";import*as x from"node:fs";import"./server/node-fetch-polyfill.js";import{cliCommandNames as g}from"./constants/common.js";import{initPlugins as T}from"./server/plugins/lifecycle.js";import{loadEnvVariables as y}from"./server/utils/envs/load-env-variables.js";import{PORTAL_VERSION as k}from"./server/version.js";import{logger as p}from"./server/tools/notifiers/logger.js";import{reporter as t}from"./server/tools/notifiers/reporter.js";import{sha as R}from"./server/utils/crypto/sha.js";import{develop as S}from"./cli/develop.js";import{eject as V}from"./cli/eject/index.js";import{beforeCommand as w}from"./server/utils/lifecycle-hooks.js";import{Store as C}from"./server/store.js";import{prepare as I}from"./cli/prepare/index.js";import{fromCurrentDir as L}from"./server/utils/paths.js";import{translationsCliOpts as M}from"./cli/translations/options.js";import{generateTranslations as N}from"./cli/translations/index.js";import{EntitlementsProvider as _}from"./server/entitlements/entitlements-provider.js";import{isValidPlan as F}from"./server/entitlements/is-valid-plan.js";import{stopAllCompilers as U}from"./server/esbuild/esbuild.js";import{copyLibsqlPrebuiltBinary as $}from"./cli/prepare/libsql/copy-prebuilt-binary.js";import{telemetry as d}from"./cli/telemetry/index.js";import{stats as q}from"./cli/stats/index.js";import{statsCliOpts as B}from"./cli/stats/options.js";const n=process.argv[2];let i;const f={alias:{d:"project-dir",p:"port"},default:{"project-dir":process.env.REDOCLY_CONTENT_DIR||process.cwd(),outdir:"public"}},G={alias:f.alias,default:{...f.default,plan:"enterprise"}},Y={alias:{d:"prepareDir"},default:{prepareDir:"public"}},z={boolean:["force"],alias:{f:"force",d:"project-dir"},default:{"project-dir":process.cwd()}};process.on("uncaughtException",async function(e){e?.code==="ERR_INVALID_STATE"?console.log("Ignore premature close error"):(p.error("Uncaught exception occurred. Stopping compilers."),await U(),p.error("Exiting due to uncaught exception"),await t.panic(e))});try{n||await t.panicOnContentError("Command not specified.");const e=_.instance();switch(["prepare","serve","stats"].includes(n)&&await e.init(),["eject","translate"].includes(n)&&await e.init({developModePlan:"enterprise"}),n){case"develop":case"preview":const a=o(process.argv.slice(3),G),E=r.resolve(a["project-dir"]),j=r.join(A(),"redocly-public-"+R(E)),l=a.plan.toLowerCase();F(l)||await t.panicOnContentError(`Invalid --plan argument value '${l}'.`),await e.init({developModePlan:l}),i=new C({contentDir:r.resolve(a["project-dir"]),outdir:j,serverOutDir:L(import.meta.url,"./server/esbuild/cache/server")}),await w(g.DEVELOP,a,i),await S(a,i);break;case"prepare":const s=o(process.argv.slice(3),f),u=r.resolve(r.join(s.outdir,"server"));i=new C({contentDir:r.resolve(s["project-dir"]),outdir:r.resolve(s.outdir,"client"),serverOutDir:u}),await w(g.PREPARE,s,i),$(u),await I(s,i);break;case"serve":y();const b=o(process.argv.slice(3),Y),O=r.resolve(b.prepareDir);d.sendServeCliCommandExecutedMessage();const v=r.join(O,"server","index.mjs");x.existsSync(v)||await t.panic("Server not found. Please run `realm prepare` first"),import(v).catch(async c=>{await t.panic("Failed to load server",c)});break;case"eject":e.canAccessFeature("themeEjecting")||await t.panicOnContentError('The "eject" command is not available for this project');const m=o(process.argv.slice(3),z),{lifecycleContext:{getConfig:h,fs:D}}=await T({outdir:"",contentDir:r.resolve(m["project-dir"]),setGlobalConfig:()=>null});D.dispose(),d.sendCliCommandEjectExecutedMessage({arguments:m}),await V({...m,config:await h()}),p.clearAllTimeouts();break;case"translate":if(e.canAccessFeature("l10n")){const c=o(process.argv.slice(3),M);d.sendCliCommandTranslateExecutedMessage({arguments:c}),await N(c)}else await t.panicOnContentError('The "translate" command is not available for this project');break;case"stats":const P=o(process.argv.slice(3),B);await q(P);break;case"--version":console.log(k);break;default:await t.panicOnContentError(`Unknown command "${n}"`)}}catch(e){p.error("Exiting due to uncaught exception"),await t.panic(e)}
@@ -0,0 +1,3 @@
1
+ import type { LifecycleContext } from '../../../server/types';
2
+ export declare function collectOpenapiDocumentsStatistics(lifecycleContext: LifecycleContext, telemetryEnabled: boolean): Promise<void>;
3
+ //# sourceMappingURL=openapi.d.ts.map
@@ -0,0 +1 @@
1
+ import{detectSpec as m,getTypes as f,normalizeTypes as d,normalizeVisitors as u,resolveDocument as w,BaseResolver as h,Stats as S,walkDocument as y}from"@redocly/openapi-core";import{logger as l}from"../../../server/tools/notifiers/logger.js";import{telemetryTraceStep as g}from"../../telemetry/helpers/trace-step.js";import{telemetry as D}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 x(a,r){await g("stats.openapi",async()=>{l.info("OpenAPI collector: start processing documents...");const s=(await a.cache.load(".","load-oas-docs")).data,e=[];for(const o of s)if(!o.isVirtual){const n=await k(o);e.push(n)}D.sendStatsOpenapiCollectedMessage({openapiStats:e.map(o=>JSON.stringify(o))}),r||console.table(e),l.info("OpenAPI collector: openapi docments processing completed.")})}async function k(a){const r=a.definition,s=m(r),e=d(f(s)),o=u([{severity:"warn",ruleId:"stats",visitor:S(t)}],e),n={problems:[],specVersion:s,visitorsData:{}},c={source:{absoluteRef:""},parsed:r},i=e.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:o,resolvedRefMap:p,document:c,ctx:n}),{path:a.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:s}}export{x as collectOpenapiDocumentsStatistics};
@@ -0,0 +1,7 @@
1
+ export type StatsArgs = {
2
+ 'project-dir': string;
3
+ telemetry: boolean;
4
+ verbose: boolean;
5
+ };
6
+ export declare function stats(args: StatsArgs): Promise<void>;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ import{initPlugins as n}from"../../server/plugins/lifecycle.js";import{configParserPlugin as a}from"../../server/plugins/config-parser/index.js";import{openAPIDocsPlugin as c}from"../../server/plugins/openapi-docs/index.js";import{shutdowner as s}from"../../server/tools/shutdowner.js";import{PORTAL_VERSION as p}from"../../server/version.js";import{collectOpenapiDocumentsStatistics as l}from"./collectors/openapi.js";import{telemetry as f}from"../telemetry/index.js";import{telemetryTraceStep as y}from"../telemetry/helpers/trace-step.js";async function I(e){const{"project-dir":o,telemetry:t,verbose:i}=e;f.initialize(p,t,i),await y("stats",async()=>{const r=[a,c],{lifecycleContext:m}=await n({contentDir:o},r);await l(m,t)}),await s.exitWithCode(0)}export{I as stats};
@@ -0,0 +1,3 @@
1
+ import type { Options } from 'mri';
2
+ export declare const statsCliOpts: Options;
3
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ const e={alias:{d:"project-dir",t:"telemetry"},default:{"project-dir":process.cwd(),telemetry:!1,verbose:!1}};export{e as statsCliOpts};
@@ -6,7 +6,7 @@ type TraceStepCallbacks = {
6
6
  declare class CLITelemetryWrapper extends AsyncApiRealmCLI.Telemetry {
7
7
  #private;
8
8
  constructor();
9
- initialize(portalVersion: string): void;
9
+ initialize(portalVersion: string, telemetryEnabled?: boolean, verbose?: boolean): void;
10
10
  addTraceStepCallbacks(event: string, { error, end }: TraceStepCallbacks): void;
11
11
  removeTraceStepCallbacks(event: string): void;
12
12
  }
@@ -1 +1 @@
1
- import{AsyncApiRealmCLI as s}from"@redocly/realm-asyncapi-sdk";import{TELEMETRY_ENABLED as o}from"../../server/constants/common.js";import{shutdowner as c}from"../../server/tools/shutdowner.js";import{PACKAGE_NAME as a}from"../../config/product-gates.js";class i extends s.Telemetry{#e=new Map;constructor(){super(),this.updateCloudEventData(()=>({organization:{id:process.env.ORGANIZATION_ID||"",slug:process.env.ORGANIZATION_SLUG||""},project:{id:process.env.PROJECT_ID||"",slug:""},productType:"cli",sourceDetails:{user:"Anonymous",object:"user",uri:""},request:{source:"cli"}}))}initialize(e){this.init({otel:{serviceName:"realm-cli",serviceVersion:`${a}@${e}`,collectorTraceUrl:process.env.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",isProd:process.env.REDOCLY_ENV==="production",version:"1.0",tracerName:"cli-telemetry"},disabled:!o}),c.registerShutdownCallback(this.#r.bind(this))}addTraceStepCallbacks(e,{error:r,end:t}){this.#e.set(e,{error:r,end:t})}removeTraceStepCallbacks(e){this.#e.delete(e)}async#r(e){for(const[,{error:r,end:t}]of this.#e)e&&r(e),t();this.#e.clear(),await this.forceFlush(),await this.shutdown()}}const l=new i,h=l.tracer;export{l as telemetry,h as telemetryTracer};
1
+ import{AsyncApiRealmCLI as s}from"@redocly/realm-asyncapi-sdk";import{TELEMETRY_ENABLED as o}from"../../server/constants/common.js";import{shutdowner as c}from"../../server/tools/shutdowner.js";import{PACKAGE_NAME as a}from"../../config/product-gates.js";class i extends s.Telemetry{#e=new Map;constructor(){super(),this.updateCloudEventData(()=>({organization:{id:process.env.ORGANIZATION_ID||"",slug:process.env.ORGANIZATION_SLUG||""},project:{id:process.env.PROJECT_ID||"",slug:""},productType:"cli",sourceDetails:{user:"Anonymous",object:"user",uri:""},request:{source:"cli"}}))}initialize(e,r=!1,t=!1){this.init({otel:{serviceName:"realm-cli",serviceVersion:`${a}@${e}`,collectorTraceUrl:process.env.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",isProd:process.env.REDOCLY_ENV==="production",version:"1.0",tracerName:"cli-telemetry"},disabled:!(r&&o),verbose:t}),c.registerShutdownCallback(this.#r.bind(this))}addTraceStepCallbacks(e,{error:r,end:t}){this.#e.set(e,{error:r,end:t})}removeTraceStepCallbacks(e){this.#e.delete(e)}async#r(e){for(const[,{error:r,end:t}]of this.#e)e&&r(e),t();this.#e.clear(),await this.forceFlush(),await this.shutdown()}}const l=new i,h=l.tracer;export{l as telemetry,h as telemetryTracer};
@@ -1,4 +1,4 @@
1
- import e,{useEffect as y,useState as p}from"react";import b from"styled-components";import{Menu as I}from"@redocly/theme/components/Menu/Menu";import{SidebarActions as L}from"@redocly/theme/components/SidebarActions/SidebarActions";import{Sidebar as w}from"@redocly/theme/components/Sidebar/Sidebar";import{VersionPicker as A}from"@redocly/theme/components/VersionPicker/VersionPicker";import{Button as B}from"@redocly/theme/components/Button/Button";import{CatalogEntityHistoryButton as P}from"@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistoryButton";import{ArrowLeftIcon as x}from"@redocly/theme/icons/ArrowLeftIcon/ArrowLeftIcon";import{withPathPrefix as D}from"@redocly/theme/core/utils";import{telemetry as h}from"../telemetry/index.js";import{usePreloadHistory as T}from"../usePreloadHistory";import{useTranslate as C}from"../hooks";import{usePageSharedData as M,usePageVersions as V}from"../../providers/page-data/hooks";import{useSidebarItems as H}from"./useSidebarItems";import{renderAdmonition as R,RequestAccessButton as q}from"./RequestAccessButton";function ie({layoutControls:s}){const{versions:l=[]}=V()||{},g=l.find(t=>t?.active),{translate:a}=C(),{currentItems:m,backLink:n,versionLabel:o,pushDrilldownState:k,popDrilldownState:v}=H(g),[c,S]=p(),{collapsedSidebar:i}=s,d=M("openAPIDocsStore")?.definition.info?.["x-metadata"]?.apiId,E=T(),[u,r]=p(void 0);return y(()=>{const t=setTimeout(()=>r(void 0),350);return()=>clearTimeout(t)},[u]),m.length?e.createElement(e.Fragment,null,e.createElement(w,{collapsed:i,menuItemsAnimation:u,versions:e.createElement(A,{versions:l,onChange:t=>{h.sendVersionPickerSelectionChangeMessage({action:"change"});const f=location.hash?t?.link+location.hash:t?.link;f&&E.push(D(f))}}),menu:e.createElement(I,{items:m,onDrilldownOpen:t=>{r("slideInRight"),k(t)}}),footer:e.createElement("div",{style:{width:"100%"}},!i&&R(c),e.createElement(L,{...s,requestAccessButton:d?e.createElement(q,{apiId:d,status:c,setStatus:S}):null})),header:(n||o!==void 0)&&e.createElement(J,null,n&&e.createElement(j,{icon:e.createElement(x,null),iconPosition:"left",variant:"ghost",size:"medium","data-component-name":"Sidebar/BackButton",to:n.slug,onClick:()=>{r("slideInLeft"),v(),h.sendSidebarDrilldownBackButtonClickedMessage({action:"click"})}},i?"":n.label?e.createElement("div",{"data-translation-key":"sidebar.menu.backToLabel"},a("sidebar.menu.backToLabel",{value:a(n.labelTranslationKey,n.label)})):e.createElement("div",{"data-translation-key":"sidebar.menu.backLabel"},a("sidebar.menu.backLabel"))),o&&!i&&e.createElement(P,{version:o}))})):null}const J=b.div`
1
+ import e,{useEffect as y,useState as p}from"react";import b from"styled-components";import{Menu as I}from"@redocly/theme/components/Menu/Menu";import{SidebarActions as L}from"@redocly/theme/components/SidebarActions/SidebarActions";import{Sidebar as w}from"@redocly/theme/components/Sidebar/Sidebar";import{VersionPicker as A}from"@redocly/theme/components/VersionPicker/VersionPicker";import{Button as B}from"@redocly/theme/components/Button/Button";import{CatalogEntityHistoryButton as P}from"@redocly/theme/components/Catalog/CatalogEntity/CatalogEntityHistory/CatalogEntityHistoryButton";import{ArrowLeftIcon as x}from"@redocly/theme/icons/ArrowLeftIcon/ArrowLeftIcon";import{withPathPrefix as D}from"@redocly/theme/core/utils";import{telemetry as h}from"../telemetry/index.js";import{usePreloadHistory as T}from"../usePreloadHistory";import{useTranslate as C}from"../hooks";import{usePageSharedData as M,usePageVersions as V}from"../../providers/page-data/hooks";import{useSidebarItems as H}from"./useSidebarItems";import{renderAdmonition as R,RequestAccessButton as q}from"./RequestAccessButton";function ie({layoutControls:s}){const{versions:l=[]}=V()||{},g=l.find(t=>t?.active),{translate:a}=C(),{currentItems:m,backLink:n,versionLabel:o,pushDrilldownState:k,popDrilldownState:v}=H(g),[c,S]=p(),{collapsedSidebar:i}=s,d=M("openAPIDocsStore")?.definition.info?.["x-metadata"]?.apiId,E=T(),[u,r]=p(void 0);return y(()=>{const t=setTimeout(()=>r(void 0),350);return()=>clearTimeout(t)},[u]),m.length?e.createElement(e.Fragment,null,e.createElement(w,{collapsed:i,menuItemsAnimation:u,versions:e.createElement(A,{versions:l,onChange:t=>{h.sendVersionPickerSelectionChangeMessage({action:"change"});const f=location.hash?t?.link+location.hash:t?.link;f&&E.push(D(f))}}),menu:e.createElement(I,{items:m,onDrilldownOpen:t=>{r("slideInRight"),k(t)}}),footer:e.createElement("div",{style:{width:"100%"}},!i&&R(c),e.createElement(L,{...s,requestAccessButton:d?e.createElement(q,{apiId:d,status:c,setStatus:S}):null})),header:(n||o)&&e.createElement(J,null,n&&e.createElement(j,{icon:e.createElement(x,null),iconPosition:"left",variant:"ghost",size:"medium","data-component-name":"Sidebar/BackButton",to:n.slug,onClick:()=>{r("slideInLeft"),v(),h.sendSidebarDrilldownBackButtonClickedMessage({action:"click"})}},i?"":n.label?e.createElement("div",{"data-translation-key":"sidebar.menu.backToLabel"},a("sidebar.menu.backToLabel",{value:a(n.labelTranslationKey,n.label)})):e.createElement("div",{"data-translation-key":"sidebar.menu.backLabel"},a("sidebar.menu.backLabel"))),o&&!i&&e.createElement(P,{version:o}))})):null}const J=b.div`
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  gap: var(--menu-header-container-gap);
@@ -1 +1 @@
1
- import{sha1 as M}from"../utils/crypto/sha1.js";import{NestedMap as F}from"./utils/nested-map.js";import{trackAccessStore as u}from"./utils/async-storage.js";import{isLoaderCacheEnabled as L}from"./utils/is-loader-cache-enabled.js";import{LoadError as w}from"./load-error.js";import{createLifecycleContext as S}from"../plugins/lifecycle.js";function c(y,t){return y+":"+t}class W{fs;errors=new Map;#t=new F;#n=new Map;#e=new Map;#s=new Map;#h=new F;#o;#a={};#i=new Map;constructor(t){this.fs=t,this.#o=S(t,this),this.#c()}async load(t,s,n){let e,r;typeof s=="string"?(e=s,r=this.#a[s]):(e=s.name,r=s.loader);const h=c(e,t);if(this.#i.has(h))return this.#i.get(h);const i=n?.join(""),o=i!==void 0?i.length>30?M(i):i:void 0,d=u.getStore()??[],I=!this.#r(t,e,o),f=this.#t.get(e,t);if(I&&f)return d.push({type:"load",loaderId:e,resource:t,hash:f.compoundHash}),f;const l=Promise.withResolvers();this.#i.set(h,l.promise.finally(()=>{this.#i.delete(h)})),o!==void 0&&this.#e.set(h,o);const p=await this.#f(t,e,async()=>{let g;const P=u.getStore()||[],m=[],C=a=>m.push(a);try{g=await r(t,this.#o,C),m.length>0?this.errors.set(h,m):this.errors.delete(h)}catch(a){const v=this.#t.get(e,t)?.data,H=e==="redocly-config"||e==="nearest-redocly-config"?!1:(await this.load(t,"is-ignored")).data;if(!(a instanceof w)&&!H&&this.errors.set(h,[a]),!v)throw a instanceof w?a:new w(a.message,{cause:a,loaderId:e});g=v}const R=M(t+(o??"")+P.map(a=>a.hash).join(""));return d.push({type:"load",loaderId:e,resource:t,hash:R}),{data:g,compoundHash:R}});return this.#d(t),L(e)&&this.#t.set(e,t,p),this.#n.set(h,p.compoundHash),l.resolve(p),l.promise}setLoaders(t){this.#a={...this.#a,...t}}delete(t,s){if(s){const n=c(s,t);this.#t.delete(s,t),this.errors.delete(n),this.#n.delete(n),this.#e.delete(n);const e=this.#s.get(t);if(e){for(const r of e)this.delete(r,s);this.#s.delete(t)}this.#h.delete(s,t)}else for(const n of this.#t.keys())this.delete(t,n)}#d(t){const[s,n]=t.split("#");if(!n)return;const e=this.#s.get(s);e?e.add(t):this.#s.set(s,new Set([t]))}#c(){this.fs.watch(async t=>{for(const s of t)s.event==="unlink"&&this.delete(s.path)})}#r(t,s,n){const e=c(s,t);return n!==void 0&&this.#e.get(e)!==n?!0:(this.#h.get(s,t)??[]).some(i=>{switch(i.type){case"load":const o=c(i.loaderId,i.resource);return this.#n.get(o)!==i.hash||this.#r(i.resource,i.loaderId,this.#e.get(o));case"read":return i.hash!==this.fs.getFileInfo(i.path)?.hash;case"exists":const d=this.fs.getFileInfo(i.path);return i.hash!==(d&&!d.isVirtual?"t":"f");case"scan":return i.hash!==this.fs.getPatternScanHash(i.pattern)}})}#f(t,s,n){const e=[];return this.#h.set(s,t,e),u.run(e,n)}}export{W as Cache};
1
+ import{sha1 as M}from"../utils/crypto/sha1.js";import{NestedMap as F}from"./utils/nested-map.js";import{trackAccessStore as m}from"./utils/async-storage.js";import{isLoaderCacheEnabled as L}from"./utils/is-loader-cache-enabled.js";import{LoadError as w}from"./load-error.js";import{createLifecycleContext as S}from"../plugins/lifecycle.js";function f(y,t){return y+":"+t}class q{fs;errors=new Map;#t=new F;#i=new Map;#e=new Map;#s=new Map;#a=new F;#h;#o={};#n=new Map;constructor(t){this.fs=t,this.#h=S(t,this),this.#c()}async load(t,s,i){let e,r;typeof s=="string"?(e=s,r=this.#o[s]):(e=s.name,r=s.loader);const a=f(e,t);if(this.#n.has(a))return this.#n.get(a);const n=i?.join(""),h=n!==void 0?n.length>30?M(n):n:void 0,d=m.getStore()??[],I=!this.#r(t,e,h),p=this.#t.get(e,t);if(I&&p)return d.push({type:"load",loaderId:e,resource:t,hash:p.compoundHash}),p;const c=Promise.withResolvers();this.#n.set(a,c.promise),h!==void 0&&this.#e.set(a,h);const{status:P,value:l}=await this.#l(t,e,async()=>{let g;const C=m.getStore()||[],u=[],E=o=>u.push(o);try{g=await r(t,this.#h,E),u.length>0?this.errors.set(a,u):this.errors.delete(a)}catch(o){const R=this.#t.get(e,t)?.data,H=e==="redocly-config"||e==="nearest-redocly-config"?!1:(await this.load(t,"is-ignored")).data;if(!(o instanceof w)&&!H&&this.errors.set(a,[o]),!R)return{status:"error",value:o instanceof w?o:new w(o.message,{cause:o,loaderId:e})};g=R}const v=M(t+(h??"")+C.map(o=>o.hash).join(""));return d.push({type:"load",loaderId:e,resource:t,hash:v}),{status:"success",value:{data:g,compoundHash:v}}});return P==="error"?c.reject(l):(this.#d(t),L(e)&&this.#t.set(e,t,l),this.#i.set(a,l.compoundHash),c.resolve(l)),this.#n.delete(a),c.promise}setLoaders(t){this.#o={...this.#o,...t}}delete(t,s){if(s){const i=f(s,t);this.#t.delete(s,t),this.errors.delete(i),this.#i.delete(i),this.#e.delete(i);const e=this.#s.get(t);if(e){for(const r of e)this.delete(r,s);this.#s.delete(t)}this.#a.delete(s,t)}else for(const i of this.#t.keys())this.delete(t,i)}#d(t){const[s,i]=t.split("#");if(!i)return;const e=this.#s.get(s);e?e.add(t):this.#s.set(s,new Set([t]))}#c(){this.fs.watch(async t=>{for(const s of t)s.event==="unlink"&&this.delete(s.path)})}#r(t,s,i){const e=f(s,t);return i!==void 0&&this.#e.get(e)!==i?!0:(this.#a.get(s,t)??[]).some(n=>{switch(n.type){case"load":const h=f(n.loaderId,n.resource);return this.#i.get(h)!==n.hash||this.#r(n.resource,n.loaderId,this.#e.get(h));case"read":return n.hash!==this.fs.getFileInfo(n.path)?.hash;case"exists":const d=this.fs.getFileInfo(n.path);return n.hash!==(d&&!d.isVirtual?"t":"f");case"scan":return n.hash!==this.fs.getPatternScanHash(n.pattern)}})}#l(t,s,i){const e=[];return this.#a.set(s,t,e),m.run(e,i)}}export{q as Cache};
@@ -1 +1 @@
1
- import{getPublicEnvVariables as t}from"../../utils/envs/get-public-env-variables.js";const a=async({fsPath:r},e,{partials:n,variables:o})=>({definitionId:r,...e.props,markdown:{partials:n,variables:{...o,env:t()}}});var s=a;export{s as default};
1
+ import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:e},t,{partials:a,variables:i},o)=>{const s=o.getPartialsForRoute?.(e)||a;return{definitionId:r,...t.props,markdown:{partials:s,variables:{...i,env:n()}}}};var d=l;export{d as default};
@@ -1 +1 @@
1
- import g from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as A}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as b}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getTemplatePath as _}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as F,asyncapiDocsLoader as N}from"./asyncapi-doc-loader.js";import{searchResolver as j}from"./search/search-resolver.js";import{getAiDocumentsStore as L}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as G}from"../../../cli/telemetry/helpers/trace-step.js";const R="asyncapi-docs-";async function tt(l){let d=[],p=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":F,"asyncapi-docs":N},processContent:async(e,a)=>{await G("build.plugin.asyncapi_docs",async()=>{if((await a.getConfig()).plugins?.some(n=>n.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const s=e.createTemplate(v,_("./template/AsyncApiDocs.js")),S=e.registerServerPropsGetter(v,_("./get-server-props.js"));for(const n of await a.fs.scan(/(\.ya?ml|\.json)$/))if(!await a.isPathIgnored(n.relativePath))try{const{data:r,compoundHash:w}=await a.cache.load(n.realRelativePath,"asyncapi-doc");if(!r?.length)continue;d=r.map(({markdocChunks:t,relativePath:c,isVirtual:u,customOutputRelativeFile:m,realRelativePath:y})=>({chunks:t,relativePath:c,realRelativePath:y,isVirtual:m!=null||n.isVirtual||u})),O(r,e.outdir,w);for(const t of r){const c=`${R}${t.relativePath}`,u=T(t.document),{navItems:m,apiItems:y}=$({asyncApiDoc:t.document,protocol:u||""}),I=[{url:A(b,`${C(t.relativePath,".json")}?download`)},{url:A(b,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(c,{document:t.document,apiItems:y,protocol:u,downloadUrls:I}),m.forEach(i=>{const f={fsPath:t.relativePath,slugSuffix:`/${i.link}`,templateId:s,sharedData:[{key:"AsyncApiDefinition",id:c}],getStaticData:D(a.withPathPrefix,i.label),serverPropsGetterIds:[S]};e.addRoute(f),i.items&&i.items.forEach(o=>{e.addRoute({...f,slugSuffix:`/${o.link}`,getStaticData:D(a.withPathPrefix,o.label)}),o.items&&o.items.forEach(h=>{e.addRoute({...f,slugSuffix:`/${h.link}`,getStaticData:D(a.withPathPrefix,o.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:s,hasClientRoutes:!0,getSidebar:i=>{const f=o=>{const h={...o};return o.link&&(h.routeSlug=A(i.slug,o.link),h.link=A(i.slug,o.link)),o.items&&(h.items=o.items.map(f)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:i.slug,link:i.slug},...m.map(f)]},getSearchDocuments:j(e,t.document),getStaticData:D(a.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:L({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:c}]})}}catch(r){console.error(r)}})},afterRoutesCreated:async(e,a)=>{const P=new Set;for(const{chunks:s,relativePath:S,isVirtual:n,realRelativePath:r}of d){const w=(await a.cache.load(r,"asyncapi-doc")).compoundHash;await a.cache.load(S,{loader:async function(){for(const{node:c,markdown:u,pointer:m,key:y,relativePath:I}of s){const{ast:i}=await e.parseMarkdoc({content:u,relativePath:m,isVirtual:n},a,{sharedDataIds:[`${R}${I}`]});c[`x-parsed-md-${y}`]={result:E(i)}}},name:"asyncapi-markdoc-inline-parser"},[w]);for(const{pointer:t}of s)P.add(t)}const k=p.difference(P);for(const s of k)a.cache.delete(s);p=P}}}function D(l,d){return async function(p,e){return{props:{settings:{baseUrlPath:l(p.baseSlug)},disableAutoScroll:!0,seo:{title:d}}}}}function C(l,d){const p=g.posix.dirname(l),e=g.posix.basename(l,g.posix.extname(l))+d;return g.posix.join(p,e)}export{tt as asyncAPIDocsPlugin};
1
+ import A from"path";import{simplifyAstStructure as E}from"@redocly/openapi-docs/lib/utils/simplifyAstStructure.js";import{buildMenuItems as $}from"@redocly/asyncapi-docs/lib/utils/build-menu-items.js";import{findFirstBinding as T}from"@redocly/asyncapi-docs/lib/utils/find-first-binding.js";import{ASYNC_API_DOCS_TEMPLATE_ID as v}from"../../../constants/common.js";import{combineUrls as D}from"@redocly/theme/core/utils";import{PUBLIC_API_DEFINITIONS_FOLDER as b}from"../../constants/common.js";import{logger as x}from"../../tools/notifiers/logger.js";import{getTemplatePath as R}from"./get-template-path.js";import{storeDefinitionBundles as O}from"./store-definition-bundles.js";import{asyncapiDocLoader as F,asyncapiDocsLoader as N}from"./asyncapi-doc-loader.js";import{searchResolver as j}from"./search/search-resolver.js";import{getAiDocumentsStore as L}from"./search/get-ai-search-documents.js";import{telemetryTraceStep as G}from"../../../cli/telemetry/helpers/trace-step.js";const _="asyncapi-docs-";async function tt(d){let p=[],u=new Set;return{id:"asyncapi",requiredEntitlements:["asyncapi"],loaders:{"asyncapi-doc":F,"asyncapi-docs":N},processContent:async(e,a)=>{await G("build.plugin.asyncapi_docs",async()=>{if((await a.getConfig()).plugins?.some(l=>l.startsWith("@redocly/portal-plugin-async-api/"))){x.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");return}const c=e.createTemplate(v,R("./template/AsyncApiDocs.js")),g=e.registerServerPropsGetter(v,R("./get-server-props.js"));for(const l of await a.fs.scan(/(\.ya?ml|\.json)$/))if(!await a.isPathIgnored(l.relativePath))try{const{data:s,compoundHash:w}=await a.cache.load(l.realRelativePath,"asyncapi-doc");if(!s?.length)continue;p=s.map(({markdocChunks:t,relativePath:o,isVirtual:m,customOutputRelativeFile:f,realRelativePath:y})=>({chunks:t,relativePath:o,realRelativePath:y,isVirtual:f!=null||l.isVirtual||m})),O(s,e.outdir,w);for(const t of s){const o=`${_}${t.relativePath}`,m=T(t.document),{navItems:f,apiItems:y}=$({asyncApiDoc:t.document,protocol:m||""}),I=[{url:D(b,`${C(t.relativePath,".json")}?download`)},{url:D(b,`${C(t.relativePath,".yaml")}?download`)}];await e.createSharedData(o,{document:t.document,apiItems:y,protocol:m,downloadUrls:I}),f.forEach(r=>{const n={fsPath:t.relativePath,slugSuffix:`/${r.link}`,templateId:c,sharedData:[{key:"AsyncApiDefinition",id:o}],getStaticData:S(a.withPathPrefix,r.label),serverPropsGetterIds:[g]};e.addRoute(n),r.items&&r.items.forEach(i=>{e.addRoute({...n,slugSuffix:`/${i.link}`,getStaticData:S(a.withPathPrefix,i.label)}),i.items&&i.items.forEach(h=>{e.addRoute({...n,slugSuffix:`/${h.link}`,getStaticData:S(a.withPathPrefix,i.label)})})})}),e.addRoute({fsPath:t.customOutputRelativeFile||t.relativePath,templateId:c,hasClientRoutes:!0,getSidebar:r=>{const n=i=>{const h={...i};return i.link&&(h.routeSlug=D(r.slug,i.link),h.link=D(r.slug,i.link)),i.items&&(h.items=i.items.map(n)),h};return[{type:"link",label:t.document.info?.title??"AsyncAPI Overview",routeSlug:r.slug,link:r.slug},...f.map(n)]},getSearchDocuments:j(e,t.document),getStaticData:S(a.withPathPrefix,t.document.info?.title??"AsyncAPI Docs"),getAiDocumentsStore:L({actions:e,document:t.document,metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}}}),metadata:{type:"asyncapi",title:t.document.info?.title??"AsyncAPI Docs",description:t.document.info?.description??"",...t.document.info?.["x-metadata"]??{}},sharedData:[{key:"AsyncApiDefinition",id:o}]})}}catch(s){console.error(s)}})},afterRoutesCreated:async(e,a)=>{const P=new Set;for(const{chunks:c,relativePath:g,isVirtual:l,realRelativePath:s}of p){const w=e.getAllRoutes().filter(o=>o.fsPath===g).map(o=>o.slug),t=(await a.cache.load(s,"asyncapi-doc")).compoundHash;await a.cache.load(g,{loader:async function(){for(const{node:m,markdown:f,pointer:y,key:I,relativePath:r}of c){const{ast:n}=await e.parseMarkdoc({content:f,relativePath:y,isVirtual:l},a,{sharedDataIds:[`${_}${r}`],routeSlugs:w});m[`x-parsed-md-${I}`]={result:E(n)}}},name:"asyncapi-markdoc-inline-parser"},[t]);for(const{pointer:o}of c)P.add(o)}const k=u.difference(P);for(const c of k)a.cache.delete(c);u=P}}}function S(d,p){return async function(u,e){return{props:{settings:{baseUrlPath:d(u.baseSlug)},disableAutoScroll:!0,seo:{title:p}}}}}function C(d,p){const u=A.posix.dirname(d),e=A.posix.basename(d,A.posix.extname(d))+p;return A.posix.join(u,e)}export{tt as asyncAPIDocsPlugin};
@@ -1 +1 @@
1
- import{readString as e}from"../../utils/read-string.js";function s(t,n=0){return typeof t=="number"?t:n}function g(t){const n=e(t.target_key)??e(t.entityKey)??e(t.entity_key)??"",o=e(t.target_revision)??e(t.entityRevision)??e(t.entity_revision)??"",i=e(t.source_to_target_relation)??e(t.relationName)??e(t.relation_name)??"",r=e(t.direction)??"outgoing",a=s(t.priority,0),c=r==="incoming"?`reverse:${i}`:i;return{targetKey:n,targetRevision:o,sourceToTargetRelation:c,direction:r,priority:a}}export{g as mapEntityRelationRow};
1
+ import{readString as e}from"../../utils/read-string.js";function y(t,i=0){return typeof t=="number"?t:i}function s(t){const i=e(t.target_key)??e(t.entityKey)??e(t.entity_key)??"",n=e(t.target_revision)??e(t.entityRevision)??e(t.entity_revision)??"",r=e(t.source_to_target_relation)??e(t.relationName)??e(t.relation_name)??"",o=e(t.direction)??"outgoing",a=y(t.priority,0);return{targetKey:i,targetRevision:n,sourceToTargetRelation:r,direction:o,priority:a}}export{s as mapEntityRelationRow};
@@ -1,4 +1,4 @@
1
- import{and as l,count as L,eq as n,isNotNull as v,notExists as E,or as D,sql as e}from"drizzle-orm";import{unionAll as f}from"drizzle-orm/sqlite-core";import{logger as b}from"../../../../../tools/notifiers/logger.js";import{VERSION_NOT_SPECIFIED as k}from"@redocly/theme/core/constants";import{applyPagination as S}from"../../../../../providers/database/pagination/index.js";import{FIELDS_TO_SELECT_FOR_ENTITY as c,FIELDS_TO_SELECT_FOR_ENTITY_RELATION as m}from"../utils.js";import{createEntityReadModel as O}from"../../mappers/create-entity-read-model.js";import{createEntityRelation as C}from"../../mappers/create-entity-relation.js";import{entitiesTable as t}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as y}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{CatalogEntitiesRelationsRepository as I}from"./catalog-entities-relations-repository.js";import{CatalogEntitiesBffRepository as g}from"./catalog-entities-bff-repository.js";class j{#e;#t=void 0;#i;#s;constructor(i){this.#e=i,this.#i=new I(this.#e,this.#t||""),this.#s=new g(this.#e,this.#t||"")}async attachDatabase(i){this.#t!==i&&(this.#t=i,await this.#e.client.run(e`ATTACH DATABASE ${i} AS remote`),this.#i=new I(this.#e,i),this.#s=new g(this.#e,i))}async getEntities(i={}){const s=this.#t?f(this.#e.client.select(c).from(e`remote.entities`),this.#e.client.select(c).from(t).where(E(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`)))):this.#e.client.select(c).from(t),r=this.#e.client.select(c).from(s.as("combined_entities")),o=this.#e.client.select(c).from(s.as("combined_entities")).$dynamic(),_=S(o,{...i,limit:void 0,skip:void 0,after:void 0,before:void 0}),a=this.#e.client.$count(_),u=r.$dynamic(),d=i.limit||10,h=S(u,{...i,limit:d+1}),[T,N]=await Promise.all([h.run(),a]),p=T.rows,w=p.length>d;return{items:p.slice(0,d).map(R=>O(R)).filter(R=>R!==null),hasMore:w,total:N}}async getEntityKeysAndVersionsBySourceFile(i){const s=this.#t?f(this.#e.client.select({keyVersion:e`key || ':' || COALESCE(version, ${k})`.as("keyVersion")}).from(e`remote.entities`).where(l(e`source_file = ${i}`,e`source = 'file'`,e`key IS NOT NULL`)),this.#e.client.select({keyVersion:e`${t.key} || ':' || COALESCE(${t.version}, ${k})`.as("keyVersion")}).from(t).where(l(n(t.sourceFile,i),n(t.source,"file"),e`${t.key} IS NOT NULL`,E(this.#e.client.select({key:e.raw("key")}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`))))):this.#e.client.select({keyVersion:e`${t.key} || ':' || COALESCE(${t.version}, ${k})`.as("keyVersion")}).from(t).where(l(n(t.sourceFile,i),n(t.source,"file"),v(t.key))),r=await this.#e.client.selectDistinct({keyVersion:e`combined_keys_versions.keyVersion`}).from(s.as("combined_keys_versions")).run();return new Set(r.rows.map(o=>o.keyVersion))}async listEntityRevisions(i,s){const r=[n(t.key,i),n(t.isDeleted,!1),...s?[n(t.version,s)]:[]],o=this.#t?f(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision"),isCurrent:e.raw("is_current"),createdAt:e.raw("created_at"),updatedAt:e.raw("updated_at"),isDefaultVersion:e.raw("is_default_version")}).from(e`remote.entities`).where(l(e`key = ${i}`,s?e`version = ${s}`:void 0)),this.#e.client.select({version:t.version,revision:t.revision,isCurrent:t.isCurrent,createdAt:t.createdAt,updatedAt:t.updatedAt,isDefaultVersion:t.isDefaultVersion}).from(t).where(l(...r,E(this.#e.client.select({version:e.raw("version")}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.version = ${t.version}`,e`remote.revision = ${t.revision}`)))))):this.#e.client.select({version:t.version,revision:t.revision,isCurrent:t.isCurrent,createdAt:t.createdAt,updatedAt:t.updatedAt,isDefaultVersion:t.isDefaultVersion}).from(t).where(l(...r));return(await this.#e.client.select({version:e.raw("version"),revision:e.raw("revision"),isCurrent:e.raw("is_current"),createdAt:e.raw("created_at"),updatedAt:e.raw("updated_at"),isDefaultVersion:e.raw("is_default_version")}).from(o.as("combined_revisions")).orderBy(e.raw("is_current DESC"),e.raw("updated_at DESC"),e.raw("created_at DESC")).run()).rows.map(a=>({version:a.version||null,revision:a.revision??"",isCurrent:a.is_current!==null?!!a.is_current:!1,createdAt:a.created_at||null,updatedAt:a.updated_at||null,isDefaultVersion:a.is_default_version!==null?!!a.is_default_version:!1}))}async getEntitiesCountByTypes(){const i=this.#t?f(this.#e.client.select({type:e`type`}).from(e`remote.entities`).where(l(n(e.raw("is_current"),1),n(e.raw("is_deleted"),!1))),this.#e.client.select({type:t.type}).from(t).where(l(n(t.isCurrent,!0),n(t.isDeleted,!1),E(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.is_current = 1`)))))):this.#e.client.select({type:t.type}).from(t).where(l(n(t.isCurrent,!0),n(t.isDeleted,!1)));return this.#e.client.select({type:t.type,count:L()}).from(i.as("combined_entities")).groupBy(t.type).where(n(t.isDeleted,!1))}async getEntityByKey(i){const o=(await(this.#t?f(this.#e.client.select(c).from(e`remote.entities`).where(l(n(t.key,i),n(e.raw("is_current"),1),n(e.raw("is_deleted"),!1))),this.#e.client.select(c).from(t).where(l(n(t.key,i),n(t.isCurrent,!0),n(t.isDeleted,!1),E(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.is_current = 1`)))))):this.#e.client.select(c).from(t).where(l(n(t.key,i),n(t.isCurrent,!0),n(t.isDeleted,!1)))).run()).rows[0];return o?O(o):null}async getOneOutdatedEntity(){const i=this.#t?f(this.#e.client.select(c).from(e`remote.entities`),this.#e.client.select(c).from(t).where(E(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`)))):this.#e.client.select(c).from(t),r=(await this.#e.client.select(c).from(i.as("combined_entities")).where(D(e`combined_entities.scorecards_status = 'OUTDATED'`,e`combined_entities.scorecards_status IS NULL`)).orderBy(e`combined_entities.updated_at ASC`).limit(1).run()).rows[0];return r?O(r):null}async getEntitiesRelations(i={}){const s=this.#t?f(this.#e.client.select(m).from(e`remote.entities_relations`),this.#e.client.select(m).from(y).where(E(this.#e.client.select({id:m.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${y.sourceKey}`)))):this.#e.client.select(m).from(y),r=this.#e.client.select(m).from(s.as("combined_entities_relations")).$dynamic(),o=this.#e.client.select(m).from(s.as("combined_entities_relations")).$dynamic(),_=S(o,{...i,limit:void 0,skip:void 0,after:void 0,before:void 0}),a=this.#e.client.$count(_),u=i.limit||10,d=S(r,{...i,limit:u+1}),[h,T]=await Promise.all([d.run(),a]),N=h.rows,p=N.length>u;return{items:N.slice(0,u).map(w=>C(w)).filter(w=>w!==null),hasMore:p,total:T}}async getEntityRelationById(i){const o=(await(this.#t?f(this.#e.client.select(m).from(e`remote.entities_relations`).where(n(y.id,i)),this.#e.client.select(m).from(y).where(l(n(y.id,i),E(this.#e.client.select({id:m.id}).from(e`remote.entities_relations as remote`).where(e`remote.id = ${y.id}`))))):this.#e.client.select(m).from(y).where(n(y.id,i))).run()).rows[0];return o?C(o):null}async getEntitiesWithRelations(i={}){return this.#s.getEntitiesWithRelations(i)}async getEntityWithRelationsByKey(i,s){return this.#s.getEntityWithRelationsByKey(i,s)}async getRelationsForEntity(i,s,r){return this.#i.getRelationsForEntity(i,s,r)}async getRelatedEntities(i,s={}){return this.#i.getRelatedEntities(i,s)}async getCatalogFilters({entitiesTypes:i=[],emptyFilters:s=[]}){if(!s.length)return{};try{return await this.#r(i),(s.includes("domains")||s.includes("owners"))&&await this.#n(),await this.#o(s)}catch(r){return console.error("Error fetching catalog filters:",r),{}}finally{await this.#l()}}async#r(i){if(this.#t?await this.#e.client.run(e`
1
+ import{and as l,count as L,eq as n,isNotNull as v,notExists as y,or as D,sql as e}from"drizzle-orm";import{unionAll as f}from"drizzle-orm/sqlite-core";import{logger as b}from"../../../../../tools/notifiers/logger.js";import{VERSION_NOT_SPECIFIED as k}from"@redocly/theme/core/constants";import{applyPagination as S}from"../../../../../providers/database/pagination/index.js";import{FIELDS_TO_SELECT_FOR_ENTITY as c,FIELDS_TO_SELECT_FOR_ENTITY_RELATION as m}from"../utils.js";import{createEntityReadModel as O}from"../../mappers/create-entity-read-model.js";import{createEntityRelation as C}from"../../mappers/create-entity-relation.js";import{entitiesTable as t}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as E}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{CatalogEntitiesRelationsRepository as I}from"./catalog-entities-relations-repository.js";import{CatalogEntitiesBffRepository as g}from"./catalog-entities-bff-repository.js";class j{#e;#t=void 0;#i;#s;constructor(i){this.#e=i,this.#i=new I(this.#e,this.#t||""),this.#s=new g(this.#e,this.#t||"")}async attachDatabase(i){this.#t!==i&&(this.#t=i,await this.#e.client.run(e`ATTACH DATABASE ${i} AS remote`),this.#i=new I(this.#e,i),this.#s=new g(this.#e,i))}async getEntities(i={}){const s=this.#t?f(this.#e.client.select(c).from(e`remote.entities`),this.#e.client.select(c).from(t).where(y(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`)))):this.#e.client.select(c).from(t),r=this.#e.client.select(c).from(s.as("combined_entities")),o=this.#e.client.select(c).from(s.as("combined_entities")).$dynamic(),_=S(o,{...i,limit:void 0,skip:void 0,after:void 0,before:void 0}),a=this.#e.client.$count(_),u=r.$dynamic(),d=i.limit||10,h=S(u,{...i,limit:d+1}),[T,N]=await Promise.all([h.run(),a]),p=T.rows,w=p.length>d;return{items:p.slice(0,d).map(R=>O(R)).filter(R=>R!==null),hasMore:w,total:N}}async getEntityKeysAndVersionsBySourceFile(i){const s=this.#t?f(this.#e.client.select({keyVersion:e`key || ':' || COALESCE(version, ${k})`.as("keyVersion")}).from(e`remote.entities`).where(l(e`source_file = ${i}`,e`source = 'file'`,e`key IS NOT NULL`)),this.#e.client.select({keyVersion:e`${t.key} || ':' || COALESCE(${t.version}, ${k})`.as("keyVersion")}).from(t).where(l(n(t.sourceFile,i),n(t.source,"file"),e`${t.key} IS NOT NULL`,y(this.#e.client.select({key:e.raw("key")}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`))))):this.#e.client.select({keyVersion:e`${t.key} || ':' || COALESCE(${t.version}, ${k})`.as("keyVersion")}).from(t).where(l(n(t.sourceFile,i),n(t.source,"file"),v(t.key))),r=await this.#e.client.selectDistinct({keyVersion:e`combined_keys_versions.keyVersion`}).from(s.as("combined_keys_versions")).run();return new Set(r.rows.map(o=>o.keyVersion))}async listEntityRevisions(i,s){const r=[n(t.key,i),n(t.isDeleted,!1),...s?[n(t.version,s)]:[]],o=this.#t?f(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision"),isCurrent:e.raw("is_current"),createdAt:e.raw("created_at"),updatedAt:e.raw("updated_at"),isDefaultVersion:e.raw("is_default_version")}).from(e`remote.entities`).where(l(e`key = ${i}`,s?e`version = ${s}`:void 0)),this.#e.client.select({version:t.version,revision:t.revision,isCurrent:t.isCurrent,createdAt:t.createdAt,updatedAt:t.updatedAt,isDefaultVersion:t.isDefaultVersion}).from(t).where(l(...r,y(this.#e.client.select({version:e.raw("version")}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.version = ${t.version}`,e`remote.revision = ${t.revision}`)))))):this.#e.client.select({version:t.version,revision:t.revision,isCurrent:t.isCurrent,createdAt:t.createdAt,updatedAt:t.updatedAt,isDefaultVersion:t.isDefaultVersion}).from(t).where(l(...r));return(await this.#e.client.select({version:e.raw("version"),revision:e.raw("revision"),isCurrent:e.raw("is_current"),createdAt:e.raw("created_at"),updatedAt:e.raw("updated_at"),isDefaultVersion:e.raw("is_default_version")}).from(o.as("combined_revisions")).orderBy(e.raw("is_current DESC"),e.raw("updated_at DESC"),e.raw("created_at DESC")).run()).rows.map(a=>({version:a.version||null,revision:a.revision??"",isCurrent:a.is_current!==null?!!a.is_current:!1,createdAt:a.created_at||null,updatedAt:a.updated_at||null,isDefaultVersion:a.is_default_version!==null?!!a.is_default_version:!1}))}async getEntitiesCountByTypes(){const i=this.#t?f(this.#e.client.select({type:e`type`}).from(e`remote.entities`).where(l(n(e.raw("is_current"),1),n(e.raw("is_deleted"),!1))),this.#e.client.select({type:t.type}).from(t).where(l(n(t.isCurrent,!0),n(t.isDeleted,!1),y(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.is_current = 1`)))))):this.#e.client.select({type:t.type}).from(t).where(l(n(t.isCurrent,!0),n(t.isDeleted,!1)));return this.#e.client.select({type:t.type,count:L()}).from(i.as("combined_entities")).groupBy(t.type).where(n(t.isDeleted,!1))}async getEntityByKey(i){const o=(await(this.#t?f(this.#e.client.select(c).from(e`remote.entities`).where(l(n(t.key,i),n(e.raw("is_current"),1),n(e.raw("is_deleted"),!1))),this.#e.client.select(c).from(t).where(l(n(t.key,i),n(t.isCurrent,!0),n(t.isDeleted,!1),y(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(l(e`remote.key = ${t.key}`,e`remote.is_current = 1`)))))):this.#e.client.select(c).from(t).where(l(n(t.key,i),n(t.isCurrent,!0),n(t.isDeleted,!1)))).run()).rows[0];return o?O(o):null}async getOneOutdatedEntity(){const i=this.#t?f(this.#e.client.select(c).from(e`remote.entities`),this.#e.client.select(c).from(t).where(y(this.#e.client.select({id:c.id}).from(e`remote.entities as remote`).where(e`remote.key = ${t.key}`)))):this.#e.client.select(c).from(t),r=(await this.#e.client.select(c).from(i.as("combined_entities")).where(D(e`combined_entities.scorecards_status = 'OUTDATED'`,e`combined_entities.scorecards_status IS NULL`)).orderBy(e`combined_entities.updated_at ASC`).limit(1).run()).rows[0];return r?O(r):null}async getEntitiesRelations(i={}){const s=this.#t?f(this.#e.client.select(m).from(e`remote.entities_relations`),this.#e.client.select(m).from(E).where(y(this.#e.client.select({id:m.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${E.sourceKey}`)))):this.#e.client.select(m).from(E),r=this.#e.client.select(m).from(s.as("combined_entities_relations")).$dynamic(),o=this.#e.client.select(m).from(s.as("combined_entities_relations")).$dynamic(),_=S(o,{...i,limit:void 0,skip:void 0,after:void 0,before:void 0}),a=this.#e.client.$count(_),u=i.limit||10,d=S(r,{...i,limit:u+1}),[h,T]=await Promise.all([d.run(),a]),N=h.rows,p=N.length>u;return{items:N.slice(0,u).map(w=>C(w)).filter(w=>w!==null),hasMore:p,total:T}}async getEntityRelationById(i){const o=(await(this.#t?f(this.#e.client.select(m).from(e`remote.entities_relations`).where(n(E.id,i)),this.#e.client.select(m).from(E).where(l(n(E.id,i),y(this.#e.client.select({id:m.id}).from(e`remote.entities_relations as remote`).where(e`remote.id = ${E.id}`))))):this.#e.client.select(m).from(E).where(n(E.id,i))).run()).rows[0];return o?C(o):null}async getEntitiesWithRelations(i={}){return this.#s.getEntitiesWithRelations(i)}async getEntityWithRelationsByKey(i,s){return this.#s.getEntityWithRelationsByKey(i,s)}async getRelationsForEntity(i,s,r){return this.#i.getRelationsForEntity(i,s,r)}async getRelatedEntities(i,s={}){return this.#i.getRelatedEntities(i,s)}async getCatalogFilters({entitiesTypes:i=[],emptyFilters:s=[]}){if(!s.length)return{};try{return await this.#r(i),(s.includes("domains")||s.includes("owners"))&&await this.#n(),await this.#o(s)}catch(r){return console.error("Error fetching catalog filters:",r),{}}finally{await this.#l()}}async#r(i){if(this.#t?await this.#e.client.run(e`
2
2
  CREATE TEMP TABLE IF NOT EXISTS temp_combined_entities AS
3
3
  SELECT
4
4
  e.key,
@@ -41,14 +41,15 @@ import{and as l,count as L,eq as n,isNotNull as v,notExists as E,or as D,sql as
41
41
  target_key,
42
42
  source_to_target_relation
43
43
  FROM remote.entities_relations
44
+ WHERE COALESCE(is_deleted, 0) = 0
44
45
  UNION ALL
45
46
  SELECT
46
47
  er.source_key,
47
48
  er.target_key,
48
49
  er.source_to_target_relation
49
50
  FROM entities_relations er
50
- LEFT JOIN remote.entities_relations r ON r.source_key = er.source_key
51
- WHERE r.source_key IS NULL
51
+ LEFT JOIN remote.entities_relations r ON r.source_key = er.source_key AND r.target_key = er.target_key
52
+ WHERE r.source_key IS NULL AND COALESCE(er.is_deleted, 0) = 0
52
53
  `):await this.#e.client.run(e`
53
54
  CREATE TEMP TABLE IF NOT EXISTS temp_combined_relations AS
54
55
  SELECT
@@ -56,6 +57,7 @@ import{and as l,count as L,eq as n,isNotNull as v,notExists as E,or as D,sql as
56
57
  target_key,
57
58
  source_to_target_relation
58
59
  FROM entities_relations
60
+ WHERE COALESCE(is_deleted, 0) = 0
59
61
  `),await this.#e.client.run(e`
60
62
  CREATE INDEX IF NOT EXISTS idx_temp_rel_source ON temp_combined_relations(source_key)
61
63
  `),await this.#e.client.run(e`
@@ -1 +1 @@
1
- import{and as d,desc as k,eq as u,isNull as v,or as R,sql as D}from"drizzle-orm";import{logger as h}from"../../../../../tools/notifiers/logger.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{sha1 as T}from"../../../../../utils/crypto/sha1.js";import{isWebView as O}from"../../../../../../utils/env/is-web-view.js";import{VERSION_NOT_SPECIFIED as S}from"@redocly/theme/core/constants";import{createEntityDbRecord as x}from"../../mappers/create-entity-db-record.js";import{createEntityRelationDbRecordFromFileSchema as I}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{entitiesTable as e}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as o}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{convertFilterToWhereCondition as K}from"../../../../../providers/database/pagination/filter.js";import{compareVersionsDescending as L}from"../../../utils/version-compare.js";const w=15;class Q{#e;#t;#r;constructor(t,r,s){this.#e=t,this.#t=r,this.#r=s}async createEntity({entity:t,fileHash:r,sourceFile:s,revision:a=new Date().toISOString(),isRootEntity:i=!1,isDeleted:n=!1}){try{const{relations:c=[],...l}=t,y=T(JSON.stringify(l)),f=t.version??S;if(await this.#s(t.key,f,y,i,n))return{result:"skipped",entityKey:t.key};const{shouldBeCurrent:g,shouldBeDefaultVersion:m}=await this.#o(t.key,f),E=x({entity:{...t,revision:a,hash:y,isCurrent:g,isDefaultVersion:m,isDeleted:n,version:f},sourceFile:s,organizationId:this.#t,projectId:this.#r,source:"file",fileHash:r}),{key:A,source:U,...F}=E;if(await this.#a({key:A,isCurrent:g,isDefaultVersion:m}),O())return await this.#c(E,c),{result:"created",entityKey:t.key,entityRevision:a,entityVersion:f};const N=this.#e.client.insert(e).values(E).onConflictDoUpdate({target:[e.key,e.source,e.revision,e.version],set:F}),B=c?.length&&c.length>0?this.#e.client.insert(o).values(c.map(V=>I({relation:V,sourceFile:s,fileHash:r,sourceKey:t.key,sourceVersion:f,sourceRevision:a??null,organizationId:this.#t,projectId:this.#r}))).onConflictDoNothing({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision]}).run():Promise.resolve();return await p([N,B],w,async V=>V),{result:"created",entityKey:t.key,entityRevision:a,entityVersion:f}}catch(c){return h.error("Error adding entity",c),{result:"error",entityKey:t.key}}}async deleteEntity(t){try{return await this.#e.client.delete(e).where(u(e.key,t)),t}catch(r){return h.error("Error deleting entity",r),null}}async deleteEntities(t){try{const r=K(t);if(!r)return!1;const s=await this.#e.client.delete(e).where(r).returning({key:e.key,source:e.source,isCurrent:e.isCurrent,isDefaultVersion:e.isDefaultVersion,version:e.version});if(s.length===0)return!0;const a=s.reduce((i,n)=>((n.isCurrent||n.isDefaultVersion)&&i.add(n.key),i),new Set);if(a.size===0)return!0;await p(Array.from(a),w,async i=>this.#u(i));for(const i of s)await this.#e.client.delete(o).where(R(d(u(o.sourceKey,i.key),...i.version?[u(o.sourceVersion,i.version)]:[v(o.sourceVersion)]),d(u(o.targetKey,i.key),...i.version?[u(o.targetVersion,i.version)]:[v(o.targetVersion)])));return!0}catch(r){return h.error("Error deleting entities",r),!1}}async deleteEntityRelation(t){try{return await this.#e.client.delete(o).where(u(o.id,t)),t}catch{return null}}async softDeleteEntities(t,r,s){try{const a=t.map(n=>{const c={type:n.type,key:n.key,title:n.title,summary:n.summary??void 0,tags:n.tags??void 0,metadata:n.metadata??void 0,git:n.git??void 0,contact:n.contact??void 0,links:n.links??void 0,version:n.version??void 0};return this.createEntity({entity:c,revision:r,sourceFile:n.sourceFile??"",fileHash:s,isDeleted:!0})});return await p(a,w,async n=>n)}catch(a){return h.error("Error soft deleting entities",a),[]}}async deleteEntityRelations(t){try{const r=K(t);return r?(await this.#e.client.delete(o).where(r),!0):!1}catch(r){return h.error("Error deleting entity relations",r),!1}}async upsertEntityRelation(t){if(!t)return null;try{const{sourceKey:r,targetKey:s,sourceVersion:a,targetVersion:i,sourceRevision:n,targetRevision:c,...l}=t,y=await this.#e.client.insert(o).values(t).onConflictDoUpdate({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision],set:l}).returning();return y?.length?y[0]:null}catch(r){return h.error("Error creating entity relation",r),null}}async#s(t,r,s,a,i){if(a||i)return!1;const n=await this.#e.client.select({hash:e.hash,isDeleted:e.isDeleted}).from(e).where(d(u(e.key,t),u(e.source,"file"),r?u(e.version,r):v(e.version))).orderBy(k(e.revision)).limit(1).run();if(n.rows.length===0)return!1;const c=n.rows[0];return c.isDeleted?!1:c.hash===s}async#i(t){return(await this.#e.client.select({version:e.version,isDefaultVersion:e.isDefaultVersion,revision:e.revision,createdAt:e.createdAt}).from(e).where(d(u(e.key,t),u(e.source,"file"))).orderBy(k(e.createdAt)).run()).rows.map(s=>({version:s.version,isDefaultVersion:!!s.isDefaultVersion,revision:s.revision,createdAt:new Date(s.createdAt)}))}#n(t){const r=t.find(i=>i.isDefaultVersion);if(r)return r;const{versionedEntities:s,unversionedEntities:a}=t.reduce((i,n)=>(n.version!==null&&n.version!==S?i.versionedEntities.push(n):i.unversionedEntities.push(n),i),{versionedEntities:[],unversionedEntities:[]});if(s.length>0){s.sort((c,l)=>L(c.version,l.version));const i=s[0].version,n=s.filter(c=>c.version===i);return n.sort((c,l)=>l.createdAt.getTime()-c.createdAt.getTime()),n[0]}return a.length>0?(a.sort((i,n)=>n.createdAt.getTime()-i.createdAt.getTime()),a[0]):null}async#o(t,r){const s=await this.#e.client.select({currentDefaultVersion:D`max(case when ${e.isDefaultVersion} = 1 then ${e.version} else null end)`,versionMatchCount:D`count(case when ${e.version} = ${r} then 1 else null end)`}).from(e).where(d(u(e.key,t),u(e.source,"file"))).get(),a=s?.currentDefaultVersion,i=(s?.versionMatchCount??0)>0;return r&&r===a?{shouldBeCurrent:!0,shouldBeDefaultVersion:!1}:{shouldBeCurrent:!i,shouldBeDefaultVersion:!i}}async#a({key:t,isCurrent:r,isDefaultVersion:s}){if(!r&&!s)return;const a={},i=[];r&&(a.isCurrent=!1,i.push(u(e.isCurrent,!0))),s&&(a.isDefaultVersion=!1,i.push(u(e.isDefaultVersion,!0))),await this.#e.client.update(e).set(a).where(d(u(e.key,t),u(e.source,"file"),R(...i))).run()}#u=async t=>{const r=await this.#i(t),s=this.#n(r);if(!s){h.warn("No latest version found for key",t);return}await this.#e.client.update(e).set({isDefaultVersion:!0,isCurrent:!0}).where(d(u(e.key,t),u(e.revision,s.revision),s.version?u(e.version,s.version):v(e.version))).run()};async#c(t,r){const{key:s,source:a,version:i,isDefaultVersion:n,...c}=t,f=(await this.#e.client.select({id:e.id}).from(e).where(d(u(e.key,s),u(e.source,a??"file"),i?u(e.version,i):v(e.version))).limit(1).run()).rows.length>0?this.#e.client.update(e).set(c).where(d(u(e.key,s),u(e.source,a??"file"),i?u(e.version,i):v(e.version))).run():this.#e.client.insert(e).values(t).onConflictDoUpdate({target:[e.key,e.source,e.revision,e.version],set:c}).run(),C=r?.map(g=>{const m=I({relation:g,sourceFile:t.sourceFile??"",fileHash:t.fileHash??"",sourceKey:t.key,sourceVersion:t.version??null,sourceRevision:t.revision??null,organizationId:this.#t,projectId:this.#r});return this.#e.client.insert(o).values(m).onConflictDoUpdate({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision],set:m}).run()})??[];await p([f,...C],w,async g=>g)}async updateEntityScorecardsStatus(t,r){try{return(await this.#e.client.update(e).set({scorecardsStatus:r}).where(u(e.id,t)).returning()).length>0}catch(s){return h.error("Error updating entity scorecards status",s),!1}}async updateEntityScorecardsStatusIfCalculating(t,r){try{return(await this.#e.client.update(e).set({scorecardsStatus:r}).where(D`${e.id} = ${t} AND ${e.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}catch(s){return h.error("Error updating entity scorecards status if calculating",s),!1}}}export{Q as CatalogEntitiesLocalWriteRepository};
1
+ import{and as d,desc as k,eq as u,isNull as v,or as R,sql as D}from"drizzle-orm";import{logger as h}from"../../../../../tools/notifiers/logger.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{sha1 as B}from"../../../../../utils/crypto/sha1.js";import{isWebView as O}from"../../../../../../utils/env/is-web-view.js";import{VERSION_NOT_SPECIFIED as S}from"@redocly/theme/core/constants";import{createEntityDbRecord as x}from"../../mappers/create-entity-db-record.js";import{createEntityRelationDbRecordFromFileSchema as I}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{entitiesTable as e}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as o}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{convertFilterToWhereCondition as K}from"../../../../../providers/database/pagination/filter.js";import{compareVersionsDescending as L}from"../../../utils/version-compare.js";const w=15;class Q{#e;#t;#r;constructor(t,r,s){this.#e=t,this.#t=r,this.#r=s}async createEntity({entity:t,fileHash:r,sourceFile:s,revision:a=new Date().toISOString(),isRootEntity:i=!1,isDeleted:n=!1}){try{const{relations:c=[],...l}=t,y=B(JSON.stringify(l)),f=t.version??S;if(await this.#s(t.key,f,y,i,n))return{result:"skipped",entityKey:t.key};const{shouldBeCurrent:g,shouldBeDefaultVersion:m}=await this.#o(t.key,f),E=x({entity:{...t,revision:a,hash:y,isCurrent:g,isDefaultVersion:m,isDeleted:n,version:f},sourceFile:s,organizationId:this.#t,projectId:this.#r,source:"file",fileHash:r}),{key:A,source:U,...T}=E;if(await this.#a({key:A,isCurrent:g,isDefaultVersion:m}),O())return await this.#c(E,c),{result:"created",entityKey:t.key,entityRevision:a,entityVersion:f};const F=this.#e.client.insert(e).values(E).onConflictDoUpdate({target:[e.key,e.source,e.revision,e.version],set:T}),N=c?.length&&c.length>0?this.#e.client.insert(o).values(c.map(V=>I({relation:V,sourceFile:s,fileHash:r,sourceKey:t.key,sourceVersion:f,sourceRevision:a??null,organizationId:this.#t,projectId:this.#r}))).onConflictDoNothing({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision,o.sourceToTargetRelation]}).run():Promise.resolve();return await p([F,N],w,async V=>V),{result:"created",entityKey:t.key,entityRevision:a,entityVersion:f}}catch(c){return h.error("Error adding entity",c),{result:"error",entityKey:t.key}}}async deleteEntity(t){try{return await this.#e.client.delete(e).where(u(e.key,t)),t}catch(r){return h.error("Error deleting entity",r),null}}async deleteEntities(t){try{const r=K(t);if(!r)return!1;const s=await this.#e.client.delete(e).where(r).returning({key:e.key,source:e.source,isCurrent:e.isCurrent,isDefaultVersion:e.isDefaultVersion,version:e.version});if(s.length===0)return!0;const a=s.reduce((i,n)=>((n.isCurrent||n.isDefaultVersion)&&i.add(n.key),i),new Set);if(a.size===0)return!0;await p(Array.from(a),w,async i=>this.#u(i));for(const i of s)await this.#e.client.delete(o).where(R(d(u(o.sourceKey,i.key),...i.version?[u(o.sourceVersion,i.version)]:[v(o.sourceVersion)]),d(u(o.targetKey,i.key),...i.version?[u(o.targetVersion,i.version)]:[v(o.targetVersion)])));return!0}catch(r){return h.error("Error deleting entities",r),!1}}async deleteEntityRelation(t){try{return await this.#e.client.delete(o).where(u(o.id,t)),t}catch{return null}}async softDeleteEntities(t,r,s){try{const a=t.map(n=>{const c={type:n.type,key:n.key,title:n.title,summary:n.summary??void 0,tags:n.tags??void 0,metadata:n.metadata??void 0,git:n.git??void 0,contact:n.contact??void 0,links:n.links??void 0,version:n.version??void 0};return this.createEntity({entity:c,revision:r,sourceFile:n.sourceFile??"",fileHash:s,isDeleted:!0})});return await p(a,w,async n=>n)}catch(a){return h.error("Error soft deleting entities",a),[]}}async deleteEntityRelations(t){try{const r=K(t);return r?(await this.#e.client.delete(o).where(r),!0):!1}catch(r){return h.error("Error deleting entity relations",r),!1}}async upsertEntityRelation(t){if(!t)return null;try{const{sourceKey:r,targetKey:s,sourceVersion:a,targetVersion:i,sourceRevision:n,targetRevision:c,...l}=t,y=await this.#e.client.insert(o).values(t).onConflictDoUpdate({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision,o.sourceToTargetRelation],set:l}).returning();return y?.length?y[0]:null}catch(r){return h.error("Error creating entity relation",r),null}}async#s(t,r,s,a,i){if(a||i)return!1;const n=await this.#e.client.select({hash:e.hash,isDeleted:e.isDeleted}).from(e).where(d(u(e.key,t),u(e.source,"file"),r?u(e.version,r):v(e.version))).orderBy(k(e.revision)).limit(1).run();if(n.rows.length===0)return!1;const c=n.rows[0];return c.is_deleted?!1:c.hash===s}async#i(t){return(await this.#e.client.select({version:e.version,isDefaultVersion:e.isDefaultVersion,revision:e.revision,createdAt:e.createdAt}).from(e).where(d(u(e.key,t),u(e.source,"file"))).orderBy(k(e.createdAt)).run()).rows.map(s=>({version:s.version,isDefaultVersion:!!s.isDefaultVersion,revision:s.revision,createdAt:new Date(s.createdAt)}))}#n(t){const r=t.find(i=>i.isDefaultVersion);if(r)return r;const{versionedEntities:s,unversionedEntities:a}=t.reduce((i,n)=>(n.version!==null&&n.version!==S?i.versionedEntities.push(n):i.unversionedEntities.push(n),i),{versionedEntities:[],unversionedEntities:[]});if(s.length>0){s.sort((c,l)=>L(c.version,l.version));const i=s[0].version,n=s.filter(c=>c.version===i);return n.sort((c,l)=>l.createdAt.getTime()-c.createdAt.getTime()),n[0]}return a.length>0?(a.sort((i,n)=>n.createdAt.getTime()-i.createdAt.getTime()),a[0]):null}async#o(t,r){const s=await this.#e.client.select({currentDefaultVersion:D`max(case when ${e.isDefaultVersion} = 1 then ${e.version} else null end)`,versionMatchCount:D`count(case when ${e.version} = ${r} then 1 else null end)`}).from(e).where(d(u(e.key,t),u(e.source,"file"))).get(),a=s?.currentDefaultVersion,i=(s?.versionMatchCount??0)>0;return r&&r===a?{shouldBeCurrent:!0,shouldBeDefaultVersion:!1}:{shouldBeCurrent:!i,shouldBeDefaultVersion:!i}}async#a({key:t,isCurrent:r,isDefaultVersion:s}){if(!r&&!s)return;const a={},i=[];r&&(a.isCurrent=!1,i.push(u(e.isCurrent,!0))),s&&(a.isDefaultVersion=!1,i.push(u(e.isDefaultVersion,!0))),await this.#e.client.update(e).set(a).where(d(u(e.key,t),u(e.source,"file"),R(...i))).run()}#u=async t=>{const r=await this.#i(t),s=this.#n(r);if(!s){h.warn("No latest version found for key",t);return}await this.#e.client.update(e).set({isDefaultVersion:!0,isCurrent:!0}).where(d(u(e.key,t),u(e.revision,s.revision),s.version?u(e.version,s.version):v(e.version))).run()};async#c(t,r){const{key:s,source:a,version:i,isDefaultVersion:n,...c}=t,f=(await this.#e.client.select({id:e.id}).from(e).where(d(u(e.key,s),u(e.source,a??"file"),i?u(e.version,i):v(e.version))).limit(1).run()).rows.length>0?this.#e.client.update(e).set(c).where(d(u(e.key,s),u(e.source,a??"file"),i?u(e.version,i):v(e.version))).run():this.#e.client.insert(e).values(t).onConflictDoUpdate({target:[e.key,e.source,e.revision,e.version],set:c}).run(),C=r?.map(g=>{const m=I({relation:g,sourceFile:t.sourceFile??"",fileHash:t.fileHash??"",sourceKey:t.key,sourceVersion:t.version??null,sourceRevision:t.revision??null,organizationId:this.#t,projectId:this.#r});return this.#e.client.insert(o).values(m).onConflictDoUpdate({target:[o.sourceKey,o.targetKey,o.sourceVersion,o.targetVersion,o.sourceRevision,o.targetRevision,o.sourceToTargetRelation],set:m}).run()})??[];await p([f,...C],w,async g=>g)}async updateEntityScorecardsStatus(t,r){try{return(await this.#e.client.update(e).set({scorecardsStatus:r}).where(u(e.id,t)).returning()).length>0}catch(s){return h.error("Error updating entity scorecards status",s),!1}}async updateEntityScorecardsStatusIfCalculating(t,r){try{return(await this.#e.client.update(e).set({scorecardsStatus:r}).where(D`${e.id} = ${t} AND ${e.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}catch(s){return h.error("Error updating entity scorecards status if calculating",s),!1}}}export{Q as CatalogEntitiesLocalWriteRepository};
@@ -1 +1 @@
1
- import{unionAll as w}from"drizzle-orm/sqlite-core";import{and as u,desc as g,eq as y,notExists as p,sql as i}from"drizzle-orm";import{entitiesTable as e}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as t}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{excludeFieldsFromFilter as F,getFirstFilterFieldValue as C}from"../../../../../providers/database/pagination/filter.js";import{applyPagination as D}from"../../../../../providers/database/pagination/index.js";import{createBffRelatedEntityFromQueryRow as T}from"../../mappers/create-bff-related-entity.js";import{mapEntityRelationRow as K}from"../../mappers/map-entity-relation-row.js";class q{#e;#i;constructor(o,n){this.#e=o,this.#i=n}async getRelationsForEntity(o,n,d){const a=await this.#t(o,n,d);return a?(await this.#e.client.select().from(a).run()).rows.map(s=>K(s)):[]}async getRelatedEntities(o,n={}){const d=C(n.filter,"version"),a=C(n.filter,"revision"),r=await this.#t(o,d,a);if(!r)return{items:[],total:0};const s=this.#e.client.select({relationType:r.relationName,direction:r.direction,key:e.key,revision:e.revision,id:e.id,type:e.type,title:e.title,summary:e.summary,metadata:e.metadata,createdAt:e.createdAt,updatedAt:e.updatedAt,source:e.source,sourceFile:e.sourceFile,version:e.version,isDeleted:e.isDeleted,isCurrent:e.isCurrent,dedupRn:i`ROW_NUMBER() OVER (PARTITION BY ${r.entityKey} ORDER BY ${r.priority} ASC, CASE WHEN ${r.entityVersion} = ${e.version} THEN 1 ELSE 0 END DESC, ${e.isCurrent} DESC, ${e.revision} DESC)`.as("dedupRn")}).from(r).innerJoin(e,i`${r.entityKey} = ${e.key} AND (${r.entityRevision} = ${e.revision} OR ${r.entityRevision} = '') AND (${r.entityVersion} = ${e.version} OR ${r.entityVersion} = '')`).as("unique_relations"),m=i`${s.dedupRn} = 1 AND COALESCE(${s.isDeleted}, 0) = 0`,R=this.#e.client.select().from(s).$dynamic(),E=this.#e.client.select().from(s).$dynamic(),$=F(n.filter,["version","revision"]),l={...n,filter:$,baseWhereCondition:m},c=D(E,{...l,limit:void 0,skip:void 0,after:void 0,before:void 0}),N=this.#e.client.$count(c),f=n.limit||10,V=D(R,{...l,limit:f+1}),[A,O]=await Promise.all([V.run(),N]),h=A.rows.filter(v=>v.id!=null).map(v=>T(v)).filter(v=>v!==null),S=h.slice(0,f),B=h.length>f;return{items:S,hasMore:B,total:O}}async#r(o,n){if(n){const s=await(this.#i?w(this.#e.client.select({version:i.raw("version"),revision:i.raw("revision")}).from(i`remote.entities`).where(u(i`key = ${o}`,i`version = ${n}`)).orderBy(i.raw("revision DESC")),this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.version,n),p(this.#e.client.select({id:i.raw("id")}).from(i`remote.entities as remote`).where(u(i`remote.key = ${e.key}`,i`remote.version = ${n}`))))).orderBy(g(e.revision))):this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.version,n))).orderBy(g(e.revision))).limit(1).run();if(s.rows.length>0){const m=s.rows[0];return{version:m.version||null,revision:m.revision||null}}return null}const a=await(this.#i?w(this.#e.client.select({version:i.raw("version"),revision:i.raw("revision")}).from(i`remote.entities`).where(u(i`key = ${o}`,i`is_current = 1`)),this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.isCurrent,!0),p(this.#e.client.select({id:i.raw("id")}).from(i`remote.entities as remote`).where(u(i`remote.key = ${e.key}`,i`remote.is_current = 1`)))))):this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.isCurrent,!0)))).limit(1).run();if(a.rows.length>0){const r=a.rows[0];return{version:r.version||null,revision:r.revision||null}}return null}async#t(o,n,d){const a=d?{version:d,revision:d}:await this.#r(o,n||null),r=n||a?.version||null,s=d||a?.revision||null,m=r?i`(${t.sourceVersion} = ${r} OR ${t.sourceVersion} = '')`:i`${t.sourceVersion} = ''`,R=r?i`(${t.targetVersion} = ${r} OR ${t.targetVersion} = '')`:i`${t.targetVersion} = ''`,E=s?i`(${t.sourceRevision} <= ${s} OR ${t.sourceRevision} = '')`:i`1 = 0`,$=s?i`(${t.targetRevision} <= ${s} OR ${t.targetRevision} = '')`:i`1 = 0`,l=this.#e.client.select({entityKey:t.targetKey,entityRevision:t.targetRevision,entityVersion:t.targetVersion,relationName:t.sourceToTargetRelation,direction:i`'outgoing'`.as("direction"),priority:i`1`.as("priority"),isDeleted:t.isDeleted,rn:i`ROW_NUMBER() OVER (PARTITION BY ${t.targetKey} ORDER BY CASE WHEN ${t.sourceVersion} != '' THEN 1 ELSE 0 END DESC, ${t.sourceRevision} DESC)`.as("rn")}).from(t).where(u(y(t.sourceKey,o),m,E)).as("outgoing_filtered"),c=this.#e.client.select({entityKey:t.sourceKey,entityRevision:t.sourceRevision,entityVersion:t.sourceVersion,relationName:t.targetToSourceRelation,direction:i`'incoming'`.as("direction"),priority:i`2`.as("priority"),isDeleted:t.isDeleted,rn:i`ROW_NUMBER() OVER (PARTITION BY ${t.sourceKey} ORDER BY CASE WHEN ${t.targetVersion} != '' THEN 1 ELSE 0 END DESC, ${t.targetRevision} DESC)`.as("rn")}).from(t).where(u(y(t.targetKey,o),R,$)).as("incoming_filtered");return this.#e.client.select({entityKey:l.entityKey,entityRevision:l.entityRevision,entityVersion:l.entityVersion,relationName:l.relationName,direction:l.direction,priority:l.priority}).from(l).where(i`${l.rn} = 1 AND COALESCE(${l.isDeleted}, 0) = 0`).unionAll(this.#e.client.select({entityKey:c.entityKey,entityRevision:c.entityRevision,entityVersion:c.entityVersion,relationName:c.relationName,direction:c.direction,priority:c.priority}).from(c).where(i`${c.rn} = 1 AND COALESCE(${c.isDeleted}, 0) = 0`)).as("all_relations")}}export{q as CatalogEntitiesRelationsRepository};
1
+ import{unionAll as g}from"drizzle-orm/sqlite-core";import{and as u,desc as p,eq as y,notExists as C,sql as i}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as D}from"@redocly/theme/core/constants";import{entitiesTable as e}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as t}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{excludeFieldsFromFilter as B,getFirstFilterFieldValue as N}from"../../../../../providers/database/pagination/filter.js";import{applyPagination as O}from"../../../../../providers/database/pagination/index.js";import{createBffRelatedEntityFromQueryRow as K}from"../../mappers/create-bff-related-entity.js";import{mapEntityRelationRow as Q}from"../../mappers/map-entity-relation-row.js";class M{#e;#i;constructor(o,n){this.#e=o,this.#i=n}async getRelationsForEntity(o,n,d){const a=await this.#t(o,n,d);return a?(await this.#e.client.select().from(a).run()).rows.map(s=>Q(s)):[]}async getRelatedEntities(o,n={}){const d=N(n.filter,"version"),a=N(n.filter,"revision"),r=await this.#t(o,d,a);if(!r)return{items:[],total:0};const s=this.#e.client.select({relationType:r.relationName,direction:r.direction,key:e.key,revision:e.revision,id:e.id,type:e.type,title:e.title,summary:e.summary,metadata:e.metadata,createdAt:e.createdAt,updatedAt:e.updatedAt,source:e.source,sourceFile:e.sourceFile,version:e.version,isDeleted:e.isDeleted,isCurrent:e.isCurrent,dedupRn:i`ROW_NUMBER() OVER (PARTITION BY ${r.entityKey} ORDER BY ${r.priority} ASC, CASE WHEN ${r.entityRevision} = ${e.revision} THEN 1 ELSE 0 END DESC, CASE WHEN ${r.entityVersion} = ${e.version} THEN 1 ELSE 0 END DESC, ${e.isCurrent} DESC, ${e.revision} DESC)`.as("dedupRn")}).from(r).innerJoin(e,i`${r.entityKey} = ${e.key} AND (${r.entityRevision} = ${e.revision} OR ${r.entityRevision} = '' OR ${e.isCurrent} = 1) AND (${r.entityVersion} = ${e.version} OR ${r.entityVersion} = '' OR ${e.version} = ${D})`).as("unique_relations"),m=i`${s.dedupRn} = 1 AND COALESCE(${s.isDeleted}, 0) = 0`,E=this.#e.client.select().from(s).$dynamic(),$=this.#e.client.select().from(s).$dynamic(),f=B(n.filter,["version","revision"]),R={...n,filter:f,baseWhereCondition:m},l=O($,{...R,limit:void 0,skip:void 0,after:void 0,before:void 0}),c=this.#e.client.$count(l),h=n.limit||10,S=O(E,{...R,limit:h+1}),[V,A]=await Promise.all([S.run(),c]),w=V.rows.filter(v=>v.id!=null).map(v=>K(v)).filter(v=>v!==null),T=w.slice(0,h),F=w.length>h;return{items:T,hasMore:F,total:A}}async#r(o,n){if(n){const s=await(this.#i?g(this.#e.client.select({version:i.raw("version"),revision:i.raw("revision")}).from(i`remote.entities`).where(u(i`key = ${o}`,i`version = ${n}`)).orderBy(i.raw("revision DESC")),this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.version,n),C(this.#e.client.select({id:i.raw("id")}).from(i`remote.entities as remote`).where(u(i`remote.key = ${e.key}`,i`remote.version = ${n}`))))).orderBy(p(e.revision))):this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.version,n))).orderBy(p(e.revision))).limit(1).run();if(s.rows.length>0){const m=s.rows[0];return{version:m.version||null,revision:m.revision||null}}return null}const a=await(this.#i?g(this.#e.client.select({version:i.raw("version"),revision:i.raw("revision")}).from(i`remote.entities`).where(u(i`key = ${o}`,i`is_current = 1`)),this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.isCurrent,!0),C(this.#e.client.select({id:i.raw("id")}).from(i`remote.entities as remote`).where(u(i`remote.key = ${e.key}`,i`remote.is_current = 1`)))))):this.#e.client.select({version:e.version,revision:e.revision}).from(e).where(u(y(e.key,o),y(e.isCurrent,!0)))).limit(1).run();if(a.rows.length>0){const r=a.rows[0];return{version:r.version||null,revision:r.revision||null}}return null}async#t(o,n,d){const a=d?{version:n||null,revision:d}:await this.#r(o,n||null),r=n||a?.version||null,s=d||a?.revision||null,m=!r||r===D,E=m?i`1 = 1`:i`(${t.sourceVersion} = ${r} OR ${t.sourceVersion} = '')`,$=m?i`1 = 1`:i`(${t.targetVersion} = ${r} OR ${t.targetVersion} = '')`,f=s?i`(${t.sourceRevision} <= ${s} OR ${t.sourceRevision} = '')`:i`1 = 0`,R=s?i`(${t.targetRevision} <= ${s} OR ${t.targetRevision} = '')`:i`1 = 0`,l=this.#e.client.select({entityKey:t.targetKey,entityRevision:t.targetRevision,entityVersion:t.targetVersion,relationName:t.sourceToTargetRelation,direction:i`'outgoing'`.as("direction"),priority:i`1`.as("priority"),isDeleted:t.isDeleted,rn:i`ROW_NUMBER() OVER (PARTITION BY ${t.targetKey}, ${t.sourceToTargetRelation} ORDER BY CASE WHEN ${t.sourceVersion} != '' THEN 1 ELSE 0 END DESC, ${t.sourceRevision} DESC)`.as("rn")}).from(t).where(u(y(t.sourceKey,o),E,f)).as("outgoing_filtered"),c=this.#e.client.select({entityKey:t.sourceKey,entityRevision:t.sourceRevision,entityVersion:t.sourceVersion,relationName:t.targetToSourceRelation,direction:i`'incoming'`.as("direction"),priority:i`2`.as("priority"),isDeleted:t.isDeleted,rn:i`ROW_NUMBER() OVER (PARTITION BY ${t.sourceKey}, ${t.targetToSourceRelation} ORDER BY CASE WHEN ${t.targetVersion} != '' THEN 1 ELSE 0 END DESC, ${t.targetRevision} DESC)`.as("rn")}).from(t).where(u(y(t.targetKey,o),$,R)).as("incoming_filtered");return this.#e.client.select({entityKey:l.entityKey,entityRevision:l.entityRevision,entityVersion:l.entityVersion,relationName:l.relationName,direction:l.direction,priority:l.priority}).from(l).where(i`${l.rn} = 1 AND COALESCE(${l.isDeleted}, 0) = 0`).unionAll(this.#e.client.select({entityKey:c.entityKey,entityRevision:c.entityRevision,entityVersion:c.entityVersion,relationName:c.relationName,direction:c.direction,priority:c.priority}).from(c).where(i`${c.rn} = 1 AND COALESCE(${c.isDeleted}, 0) = 0`)).as("all_relations")}}export{M as CatalogEntitiesRelationsRepository};
@@ -1 +1 @@
1
- import{eq as h,sql as f}from"drizzle-orm";import{convertFilterToWhereCondition as w}from"../../../../../providers/database/pagination/filter.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{logger as n}from"../../../../../tools/notifiers/logger.js";import{entitiesTable as r}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{telemetryTraceStep as i}from"../../../../../telemetry/helpers/trace-step.js";import{BaseRepository as _}from"../../../../../providers/database/base-repository.js";import{DatabaseConnectionFactory as b}from"../../../../../providers/database/database-connection-factory.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{createEntityDbRecord as p}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as m}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromDto as C}from"../../mappers/create-entity-relation-db-record-from-dto.js";const I=15;class s extends _{static#e;get transactionsManager(){return this.databaseClient.transactionsManager}constructor(e){super(e)}async sync(){return i("catalog_entities.remote_repository.sync",async()=>{await this.#t(),await this.databaseClient.sync()})}static async getInstance(e){return await i("catalog_entities.remote_repository.get_instance",async t=>{if(!s.#e)try{const o=await b.create("sqld-remote",e);if(!o)return n.error("Failed to create db connection for catalog entities remote repository"),t?.error(new Error("Failed to create db connection for catalog entities remote repository")),s.#e=null,null;s.#e=new s(o)}catch(o){return n.error("Error creating db connection for catalog entities remote repository",o),t?.error(o),s.#e=null,null}return s.#e})}async createEntity(e){return i("catalog_entities.remote_repository.create_entity",async()=>{await this.#t();try{n.info(`Adding entity ${e.key} to remote database`);const t=p({entity:e,organizationId:this.organizationId,projectId:this.projectId,source:"remote",sourceFile:null,fileHash:null}),{key:o,source:d,...u}=t,l=await this.databaseClient.client.insert(r).values(t).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:u}).returning();return l.length?(e.relations&&await this.createEntityRelations(e.relations.map(c=>({...c,sourceKey:e.key,targetKey:c.key}))),m(l[0])):null}catch(t){throw n.error("Error adding entity",t),t}})}async updateEntity(e){return i("catalog_entities.remote_repository.update_entity",async()=>{await this.#t();try{n.info(`Updating entity ${e.key} in remote database`);const t=p({entity:e,organizationId:this.organizationId,projectId:this.projectId,source:"remote",sourceFile:null,fileHash:null}),{key:o,source:d,scorecardsStatus:u,...l}=t,c=await this.databaseClient.client.insert(r).values(t).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:{...l,scorecardsStatus:f`CASE WHEN ${r.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return c.length?m(c[0]):null}catch(t){return n.error("Error updating entity",t),null}})}async deleteEntity(e){return i("catalog_entities.remote_repository.delete_entity",async()=>{await this.#t();try{return await this.databaseClient.client.delete(r).where(h(r.key,e)),e}catch(t){return n.error("Error deleting entity",t),null}})}async createEntityRelations(e){return i("catalog_entities.remote_repository.create_entity_relations",async()=>(await this.#t(),await E(e,I,async t=>this.createEntityRelation(t))))}async createEntityRelation(e){return i("catalog_entities.remote_repository.create_entity_relation",async()=>{if(await this.#t(),!e)return null;try{const t=C(e,this.organizationId,this.projectId),{sourceKey:o,targetKey:d,sourceVersion:u,targetVersion:l,sourceRevision:c,targetRevision:D,...g}=t,y=await this.databaseClient.client.insert(a).values(t).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision],set:g}).returning();return y.length?y[0]:null}catch(t){throw n.error("Error creating entity relation",t),t}})}async deleteEntityRelation(e){return i("catalog_entities.remote_repository.delete_entity_relation",async()=>{await this.#t();try{return await this.databaseClient.client.delete(a).where(h(a.id,e)),e}catch(t){return n.error("Error deleting entity relation",t),null}})}async deleteEntitiesRelations(e){return i("catalog_entities.remote_repository.delete_entities_relations",async()=>{await this.#t();try{const t=w(e);return t?(await this.databaseClient.client.delete(a).where(t),!0):!1}catch(t){return n.error("Error deleting entities relations",t),!1}})}#t(){return i("catalog_entities.remote_repository.db_health",async e=>{if(this.databaseClient.dbClient.$client.closed){const t=new Error("The remote database connection is closed!");throw e?.error(t),t}})}}export{s as CatalogEntitiesRemoteRepository};
1
+ import{eq as h,sql as f}from"drizzle-orm";import{convertFilterToWhereCondition as w}from"../../../../../providers/database/pagination/filter.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{logger as i}from"../../../../../tools/notifiers/logger.js";import{entitiesTable as r}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{telemetryTraceStep as a}from"../../../../../telemetry/helpers/trace-step.js";import{BaseRepository as _}from"../../../../../providers/database/base-repository.js";import{DatabaseConnectionFactory as b}from"../../../../../providers/database/database-connection-factory.js";import{entitiesRelationsTable as n}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{createEntityDbRecord as p}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as g}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromDto as C}from"../../mappers/create-entity-relation-db-record-from-dto.js";const I=15;class s extends _{static#e;get transactionsManager(){return this.databaseClient.transactionsManager}constructor(e){super(e)}async sync(){return a("catalog_entities.remote_repository.sync",async()=>{await this.#t(),await this.databaseClient.sync()})}static async getInstance(e){return await a("catalog_entities.remote_repository.get_instance",async t=>{if(!s.#e)try{const o=await b.create("sqld-remote",e);if(!o)return i.error("Failed to create db connection for catalog entities remote repository"),t?.error(new Error("Failed to create db connection for catalog entities remote repository")),s.#e=null,null;s.#e=new s(o)}catch(o){return i.error("Error creating db connection for catalog entities remote repository",o),t?.error(o),s.#e=null,null}return s.#e})}async createEntity(e){return a("catalog_entities.remote_repository.create_entity",async()=>{await this.#t();try{i.info(`Adding entity ${e.key} to remote database`);const t=p({entity:e,organizationId:this.organizationId,projectId:this.projectId,source:"remote",sourceFile:null,fileHash:null}),{key:o,source:d,...u}=t,l=await this.databaseClient.client.insert(r).values(t).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:u}).returning();return l.length?(e.relations&&await this.createEntityRelations(e.relations.map(c=>({...c,sourceKey:e.key,targetKey:c.key}))),g(l[0])):null}catch(t){throw i.error("Error adding entity",t),t}})}async updateEntity(e){return a("catalog_entities.remote_repository.update_entity",async()=>{await this.#t();try{i.info(`Updating entity ${e.key} in remote database`);const t=p({entity:e,organizationId:this.organizationId,projectId:this.projectId,source:"remote",sourceFile:null,fileHash:null}),{key:o,source:d,scorecardsStatus:u,...l}=t,c=await this.databaseClient.client.insert(r).values(t).onConflictDoUpdate({target:[r.key,r.source,r.revision,r.version],set:{...l,scorecardsStatus:f`CASE WHEN ${r.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return c.length?g(c[0]):null}catch(t){return i.error("Error updating entity",t),null}})}async deleteEntity(e){return a("catalog_entities.remote_repository.delete_entity",async()=>{await this.#t();try{return await this.databaseClient.client.delete(r).where(h(r.key,e)),e}catch(t){return i.error("Error deleting entity",t),null}})}async createEntityRelations(e){return a("catalog_entities.remote_repository.create_entity_relations",async()=>(await this.#t(),await E(e,I,async t=>this.createEntityRelation(t))))}async createEntityRelation(e){return a("catalog_entities.remote_repository.create_entity_relation",async()=>{if(await this.#t(),!e)return null;try{const t=C(e,this.organizationId,this.projectId),{sourceKey:o,targetKey:d,sourceVersion:u,targetVersion:l,sourceRevision:c,targetRevision:D,...m}=t,y=await this.databaseClient.client.insert(n).values(t).onConflictDoUpdate({target:[n.sourceKey,n.targetKey,n.sourceVersion,n.targetVersion,n.sourceRevision,n.targetRevision,n.sourceToTargetRelation],set:m}).returning();return y.length?y[0]:null}catch(t){throw i.error("Error creating entity relation",t),t}})}async deleteEntityRelation(e){return a("catalog_entities.remote_repository.delete_entity_relation",async()=>{await this.#t();try{return await this.databaseClient.client.delete(n).where(h(n.id,e)),e}catch(t){return i.error("Error deleting entity relation",t),null}})}async deleteEntitiesRelations(e){return a("catalog_entities.remote_repository.delete_entities_relations",async()=>{await this.#t();try{const t=w(e);return t?(await this.databaseClient.client.delete(n).where(t),!0):!1}catch(t){return i.error("Error deleting entities relations",t),!1}})}#t(){return a("catalog_entities.remote_repository.db_health",async e=>{if(this.databaseClient.dbClient.$client.closed){const t=new Error("The remote database connection is closed!");throw e?.error(t),t}})}}export{s as CatalogEntitiesRemoteRepository};
@@ -1 +1 @@
1
- import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as v}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as u}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as f}from"@redocly/theme/core/constants";import{resolveEntityVersion as g}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as h}from"../../../utils/catalog-data-collector.js";const E=3;class D{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&h.addExtractor(this.specType),await v(t,E,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){h.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE);return}const a=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(e.realRelativePath),o=new Date().toISOString(),n=this.#a(e);await this.processApiDescription(e,o,n,a),await this.#i(a,e.realRelativePath,o,e.hash),h.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#i=async(t,e,i,r)=>{if(t.size===0)return;const a=Array.from(t).map(s=>{const[l,p]=s.split(":");return{key:l,version:p}}),o=Array.from(new Set(a.map(({key:s})=>s))),n=a.map(({key:s,version:l})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:s},{field:"version",operator:"equal",value:l}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:i,fileHash:r,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:n},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#a(t){const e=t.document?.info?.version??t.definition?.info?.version??null,i=g(e,t.realRelativePath);return i.success?i.version??f:f}}export{D as BaseApiEntitiesExtractor};
1
+ import{FileHashStatus as c}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as E}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as u}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as f}from"@redocly/theme/core/constants";import{resolveEntityVersion as v}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as h}from"../../../utils/catalog-data-collector.js";const g=3;class w{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&h.addExtractor(this.specType),await E(t,g,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){h.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE);return}const a=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(e.realRelativePath);process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true"&&(await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:Array.from(a).map(s=>s.split(":")[0])}),a.clear());const o=new Date().toISOString(),l=this.#a(e);await this.processApiDescription(e,o,l,a),await this.#i(a,e.realRelativePath,o,e.hash),h.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,c.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:1e3,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:c.OUTDATED}]})};#i=async(t,e,i,r)=>{if(t.size===0||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")return;const a=Array.from(t).map(s=>{const[n,p]=s.split(":");return{key:n,version:p}}),o=Array.from(new Set(a.map(({key:s})=>s))),l=a.map(({key:s,version:n})=>({op:u.AND,conditions:[{field:"key",operator:"equal",value:s},{field:"version",operator:"equal",value:n}]}));await this.catalogEntitiesService.softDeleteEntitiesInLocalDatabase({revision:i,fileHash:r,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:o},{op:u.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]}})};#a(t){const e=t.document?.info?.version??t.definition?.info?.version??null,i=v(e,t.realRelativePath);return i.success?i.version??f:f}}export{w as BaseApiEntitiesExtractor};
@@ -24,6 +24,7 @@ type ParsedAstChunk = {
24
24
  type MarkdocInfo = {
25
25
  sharedDataDeps?: Set<string>;
26
26
  dynamicMarkdocComponents?: string[];
27
+ partials?: string[];
27
28
  tagList?: string[];
28
29
  htmlTagsList?: string[];
29
30
  tagOccurrence?: Record<string, number>;
@@ -1 +1 @@
1
- import L from"@markdoc/markdoc";import*as M from"path";import{GATED_MARKDOC_TAGS as A}from"../../constants/entitlements.js";import{logger as O}from"../../tools/notifiers/logger.js";import{reporter as F}from"../../tools/notifiers/reporter.js";import{sha1 as G}from"../../utils/crypto/sha1.js";import{formatMarkdocError as N}from"./errors.js";import{extractFirstHeading as j,visit as x}from"./markdoc/plugins/utils.js";import{attributeResolvers as y}from"./attribute-resolvers/index.js";import{MdResolveError as K}from"./attribute-resolvers/md-resolve-error.js";import{processHtmlTokens as $}from"./html/process-html-tokens.js";import{resolveRawPartials as W}from"./markdoc/resolve-raw-partials.js";import{EntitlementsProvider as Y}from"../../entitlements/entitlements-provider.js";import{MARKDOC_PARTIALS_DEPS_KEY as B}from"../../store.js";import{getLinkOriginalAttrName as U}from"./attribute-resolvers/utils.js";const V="EMPTY";async function q(a,o,e){const n=Y.instance(),{actions:g}=e,{relativePath:s,resolveErrors:_}=a,m=new Set,p=new Set,c=new Set,v={},f=new Set,w={},k={};function E(t,P){const D=P||V;t[D]=(t[D]||0)+1}const S=[];return a.resolveErrors.length=0,x(a.ast,t=>{const P=D();S.push(P.then(r=>{r?.sharedDataIds&&r.sharedDataIds.forEach(d=>m.add(d))}).catch(z));async function D(){const r=[];switch(t.type){case"fence":E(w,t.attributes.language);break;case"link":case"image":await y.nativeMdLink(t,t.type==="link"?"href":"src",s,e);break;case"tag":if(!t.tag)break;const d=o?.tags?.[t.tag];if(!d){A[t.tag]&&!n.canAccessFeature(A[t.tag])&&(t.errors.push({level:"warning",id:"invalid-tag",message:`Undefined tag: ${t.tag}`}),t.tag="",t.type="error",t.attributes={});break}const h=t.tag==="html"?t.attributes.name:t.tag;if((t.tag==="html"?f:c).add(h),v[h]=(v[h]||0)+1,h==="code-snippet"&&E(w,t.attributes.language),d.attributes?.__idx&&(t.attributes.__idx=v[t.tag]),d.dynamicComponentLib&&p.add(d.dynamicComponentLib),!d.attributes)break;if(h==="partial"&&t.attributes?.file){const i=U("file"),l=t[i]||t.attributes.file,b=l.startsWith("/")?l.slice(1):M.posix.normalize(M.posix.join(M.posix.dirname(s),l)),u=(g.getGlobalConfig(B)||{})[b];if(u?.dynamicComponents)for(const R of u.dynamicComponents)p.add(R);if(u?.sharedDataDeps)for(const R of u.sharedDataDeps)m.add(R)}for(const[i,l]of Object.entries(d.attributes)){const b=l.type;if(b&&(b.resolver||l.resolver)){const T=y[b.resolver||l.resolver],u=await T?.(t,i,s,e);u?.sharedDataId&&r.push(u.sharedDataId)}}if(h==="code-walkthrough")for(const i of t.attributes.resolvedFilesets||[])for(const l of i.files||[])E(k,l.language);const I=t.attributes?.attrs;if(I&&t.tag==="html")for(const i of Object.keys(I))i==="src"||i==="srcSet"?await y.htmlSourceAttribute(t,i,s,e):i==="href"&&await y.htmlHref(t,i,s,e);break}return{sharedDataIds:r}}async function z(r){if(!(r instanceof K)){await F.panicOnBuild(r.message);return}_.push(N({type:"resolve_link",meta:{...r.meta,link:r.meta.link??r.meta.rawLink},lines:t.lines,location:t.location,error:{id:"",level:"error",message:r.message,location:t.location}},a.relativePath,a.rawContent))}}),await Promise.all(S),a.sharedDataDeps=m,a.dynamicMarkdocComponents=p,a.validatedAtRevision<g.buildRevision&&(a.markdocErrors=L.validate(a.ast,o).map(t=>N(t,s,a.rawContent)),a.validatedAtRevision=g.buildRevision),{sharedDataDeps:a.sharedDataDeps,dynamicMarkdocComponents:Array.from(a.dynamicMarkdocComponents?.values()??[]),tagList:Array.from(c),htmlTagsList:Array.from(f),tagOccurrence:v,codeSnippetLanguages:w,codeWalkthroughLanguages:k}}const H=new L.Tokenizer({html:!0,allowIndentation:!0,allowComments:!0});H.parser.block.ruler.getRules("reference").length=0;function C(a,o){const e=H.tokenize(o),n=$(e);return{ast:L.parse(n,{file:a,slots:!0}),rawContent:o,resolveErrors:[],markdocErrors:[],relativePath:a,sharedDataDeps:void 0,validatedAtRevision:-1}}async function ft(a,o){const{data:e}=await o.cache.load(a,"markdown-ast");return j(e.ast)}async function dt(a,o){F.clearMarkdocProblems();const e=a.getAllRoutes();let n=0;const g=O.isInteractive();for(const s of e)await a.resolveRouteStaticData(s,o,!0),n++,g&&n%100===0&&O.logInFooter("validate",` \u{1F50D} Status: validating markdoc (${n}/${e.length})`)}async function gt(a,o,e){const n=a.content?G(a.content):"";return await e.context.cache.load(a.relativePath,{loader:s,name:"markdown-inline-parser"},[n,String(e.actions.buildRevision)]);async function s(_,m,p){let c;if(a.content){const f=a.content?a.content:await m.fs.read(a.relativePath),w=await m.getConfig(),k=await W(f,a.relativePath,w.markdown?.partialsFolders,m);c=C(a.relativePath,k)}else c=(await m.cache.load(a.relativePath,"markdown-ast")).data;let v={};if(e.actions.buildRevision!==0&&(v=await q(c,o,e)),!a.isVirtual){for(const f of c.markdocErrors)p(f);for(const f of c.resolveErrors)p(f)}return{ast:c.ast,info:v}}}export{ft as extractMdFirstHeading,C as getAst,gt as parseAndResolveMarkdoc,q as resolveAndValidateMarkdoc,dt as validateAllMarkdowns};
1
+ import L from"@markdoc/markdoc";import*as M from"path";import{GATED_MARKDOC_TAGS as O}from"../../constants/entitlements.js";import{logger as F}from"../../tools/notifiers/logger.js";import{reporter as N}from"../../tools/notifiers/reporter.js";import{sha1 as j}from"../../utils/crypto/sha1.js";import{formatMarkdocError as H}from"./errors.js";import{extractFirstHeading as x,visit as K}from"./markdoc/plugins/utils.js";import{attributeResolvers as y}from"./attribute-resolvers/index.js";import{MdResolveError as $}from"./attribute-resolvers/md-resolve-error.js";import{processHtmlTokens as U}from"./html/process-html-tokens.js";import{resolveRawPartials as W}from"./markdoc/resolve-raw-partials.js";import{EntitlementsProvider as Y}from"../../entitlements/entitlements-provider.js";import{MARKDOC_PARTIALS_DEPS_KEY as B}from"../../store.js";import{getLinkOriginalAttrName as V}from"./attribute-resolvers/utils.js";const q="EMPTY";async function C(a,s,e){const c=Y.instance(),{actions:g}=e,{relativePath:o,resolveErrors:S}=a,f=new Set,u=new Set,l=new Set,w=new Set,n={},k=new Set,b={},_={};function E(t,P){const D=P||q;t[D]=(t[D]||0)+1}const A=[];return a.resolveErrors.length=0,K(a.ast,t=>{const P=D();A.push(P.then(r=>{r?.sharedDataIds&&r.sharedDataIds.forEach(d=>f.add(d))}).catch(G));async function D(){const r=[];switch(t.type){case"fence":E(b,t.attributes.language);break;case"link":case"image":await y.nativeMdLink(t,t.type==="link"?"href":"src",o,e);break;case"tag":if(!t.tag)break;const d=s?.tags?.[t.tag];if(!d){O[t.tag]&&!c.canAccessFeature(O[t.tag])&&(t.errors.push({level:"warning",id:"invalid-tag",message:`Undefined tag: ${t.tag}`}),t.tag="",t.type="error",t.attributes={});break}const p=t.tag==="html"?t.attributes.name:t.tag;if((t.tag==="html"?k:w).add(p),n[p]=(n[p]||0)+1,p==="code-snippet"&&E(b,t.attributes.language),d.attributes?.__idx&&(t.attributes.__idx=n[t.tag]),d.dynamicComponentLib&&u.add(d.dynamicComponentLib),!d.attributes)break;if(p==="partial"&&t.attributes?.file){const i=V("file"),m=t[i]||t.attributes.file,h=m.startsWith("/")?m.slice(1):M.posix.normalize(M.posix.join(M.posix.dirname(o),m));l.add(h);const v=(g.getGlobalConfig(B)||{})[h];if(v?.dynamicComponents)for(const R of v.dynamicComponents)u.add(R);if(v?.sharedDataDeps)for(const R of v.sharedDataDeps)f.add(R)}for(const[i,m]of Object.entries(d.attributes)){const h=m.type;if(h&&(h.resolver||m.resolver)){const T=y[h.resolver||m.resolver],v=await T?.(t,i,o,e);v?.sharedDataId&&r.push(v.sharedDataId)}}if(p==="code-walkthrough")for(const i of t.attributes.resolvedFilesets||[])for(const m of i.files||[])E(_,m.language);const I=t.attributes?.attrs;if(I&&t.tag==="html")for(const i of Object.keys(I))i==="src"||i==="srcSet"?await y.htmlSourceAttribute(t,i,o,e):i==="href"&&await y.htmlHref(t,i,o,e);break}return{sharedDataIds:r}}async function G(r){if(!(r instanceof $)){await N.panicOnBuild(r.message);return}S.push(H({type:"resolve_link",meta:{...r.meta,link:r.meta.link??r.meta.rawLink},lines:t.lines,location:t.location,error:{id:"",level:"error",message:r.message,location:t.location}},a.relativePath,a.rawContent))}}),await Promise.all(A),a.sharedDataDeps=f,a.dynamicMarkdocComponents=u,a.validatedAtRevision<g.buildRevision&&(a.markdocErrors=L.validate(a.ast,s).map(t=>H(t,o,a.rawContent)),a.validatedAtRevision=g.buildRevision),{sharedDataDeps:a.sharedDataDeps,dynamicMarkdocComponents:Array.from(a.dynamicMarkdocComponents?.values()??[]),partials:Array.from(l),tagList:Array.from(w),htmlTagsList:Array.from(k),tagOccurrence:n,codeSnippetLanguages:b,codeWalkthroughLanguages:_}}const z=new L.Tokenizer({html:!0,allowIndentation:!0,allowComments:!0});z.parser.block.ruler.getRules("reference").length=0;function J(a,s){const e=z.tokenize(s),c=U(e);return{ast:L.parse(c,{file:a,slots:!0}),rawContent:s,resolveErrors:[],markdocErrors:[],relativePath:a,sharedDataDeps:void 0,validatedAtRevision:-1}}async function dt(a,s){const{data:e}=await s.cache.load(a,"markdown-ast");return x(e.ast)}async function gt(a,s){N.clearMarkdocProblems();const e=a.getAllRoutes();let c=0;const g=F.isInteractive();for(const o of e)await a.resolveRouteStaticData(o,s,!0),c++,g&&c%100===0&&F.logInFooter("validate",` \u{1F50D} Status: validating markdoc (${c}/${e.length})`)}async function vt(a,s,e){const c=a.content?j(a.content):"";return await e.context.cache.load(a.relativePath,{loader:o,name:"markdown-inline-parser"},[c,String(e.actions.buildRevision)]);async function o(S,f,u){let l;if(a.content){const n=a.content?a.content:await f.fs.read(a.relativePath),k=await f.getConfig(),b=await W(n,a.relativePath,k.markdown?.partialsFolders,f);l=J(a.relativePath,b)}else l=(await f.cache.load(a.relativePath,"markdown-ast")).data;let w={};if(e.actions.buildRevision!==0&&(w=await C(l,s,e)),!a.isVirtual){for(const n of l.markdocErrors)u(n);for(const n of l.resolveErrors)u(n)}return{ast:l.ast,info:w}}}export{dt as extractMdFirstHeading,J as getAst,vt as parseAndResolveMarkdoc,C as resolveAndValidateMarkdoc,gt as validateAllMarkdowns};
@@ -1 +1 @@
1
- import{getPublicEnvVariables as t}from"../../utils/envs/get-public-env-variables.js";const a=async({fsPath:r},e,{partials:n,variables:o})=>({definitionId:r,...e.props,markdown:{partials:n,variables:{...o,env:t()}}});var s=a;export{s as default};
1
+ import{getPublicEnvVariables as n}from"../../utils/envs/get-public-env-variables.js";const l=async({fsPath:r,slug:e},t,{variables:a,partials:i},o)=>{const s=o.getPartialsForRoute?.(e)||i;return{definitionId:r,...t.props,markdown:{partials:s,variables:{...a,env:n()}}}};var d=l;export{d as default};
@@ -1 +1 @@
1
- import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as $,PUBLIC_RBAC_SCOPE_ITEM as j}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as oe,OPENAPI_SHARED_DATA_PREFIX as U}from"../../constants/plugins/openapi-docs.js";import{isDevelopMode as V}from"../../utils/envs/is-develop-mode.js";import{searchResolver as ae}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as re,shouldAddRoute as se}from"./utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as ne}from"./store-definition-bundles.js";import{definitionLoader as ie,definitionsLoader as pe}from"./load-definition.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{fromCurrentDir as ce}from"../../utils/paths.js";import{telemetryTraceStep as le}from"../../../cli/telemetry/helpers/trace-step.js";const w="openapi-spec-download";async function Oe(){let L=[],A={},M=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":pe,"load-oas":ie},processContent:async(e,i)=>{await le("build.plugin.openapi_docs",async c=>{e.createRequestHandler(w,ce(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})});const R=e.createTemplate($,b("./template/OpenAPIDocs.js")),a=e.registerServerPropsGetter($,b("./get-server-props.js")),s=e.registerServerPropsGetter(oe,b("./get-server-props-custom-fields.js")),p=await i.getConfig();c?.setAttribute("config",JSON.stringify(p.openapi||{}));const S=p.rules?.["custom-fields-schema"];A={};const l=await e.loadOpenApiDefinitions(i);L=l.map(({markdocChunks:m,relativePath:f,customOutputRelativeFile:n,isVirtual:r,realRelativePath:h})=>({chunks:m,relativePath:f,realRelativePath:h,isVirtual:n!=null||r})),ne(l,e.outdir);const u={};for(const m of l||[]){const{definition:f,config:n,relativePath:r,customOutputRelativeFile:h,contentItems:_,flatItems:k,parser:E,options:B,rawOptions:q,hash:J}=m,N=h||r,o=[],x={},{definition:Q}=E||{},{info:d}=Q||{},v=d?.["x-metadata"],O=!!n.openapi?.excludeFromSearch||!!n.theme?.openapi?.excludeFromSearch||!!p.openapi?.excludeFromSearch||!!p.theme?.openapi?.excludeFromSearch,G={title:d?.title,description:d?.description,summary:d?.summary,...n.metadata,...v},g={untagged:[],tagged:new Map};for(const t of k){const{id:C,href:I,operationDefinition:y}=t;if(y){const{tags:P}=y;if(P)for(const T of P)g.tagged.has(T)||g.tagged.set(T,[]),g.tagged.get(T)?.push(t);else g.untagged.push(t);V()&&(x[`#${y.pointer}`]=t.href)}if(!se({item:t}))continue;const F=t,Y=F.type==="section"&&!!F.infoDefinition,z=I.split("#")[0]+"/",K=t?.operationDefinition?.[D];o.push({excludeFromSearch:O,slugSuffix:z,fsPath:N,httpVerb:t?.httpVerb||"",path:r,templateId:R,[D]:K||n.rbac,getAiDocumentsStore:de({parser:E,options:B,info:d,tagOperations:g,openapiContentItem:F,metadata:G,relativePath:r,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:Y,excludeFromSearch:O}),getStaticData:async P=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:P.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:C,disableAutoScroll:!0}})})}o[0]={...o[0],metadata:{type:"openapi",...G},hasClientRoutes:!0,getSidebar:(t,C)=>{const I=[];return re({contentItems:_,sidebarItems:I,routeSlug:t.slug,navItem:C}),I},getNavText:()=>d?.title,getSearchDocuments:ae(E,B,k,e.getSearchFacets,e.setSearchFacets,O)},v?.apiId&&(u[v.apiId]={slug:o[0]?.slug||""});const W=o[0];o[0]=o[o.length-1],o[o.length-1]=W;for(const t of o)e.addRoute({...t,serverPropsGetterIds:S?[a,s]:[a]});const X=V()?r:void 0,H=`${U}${r}`;A[H]={fsPath:N,definition:f,options:q,sourcePath:X,routesMapping:x,hash:J};for(const t of o)e.addRoute({...t,sharedData:[{id:H,key:"openAPIDocsStore"}],serverPropsGetterIds:S?[a,s]:[a]})}e.setGlobalData({apiProducts:u})})},afterRoutesCreated:async(e,i)=>{const c=new Set;for(const{chunks:a,relativePath:s,isVirtual:p,realRelativePath:S}of L){const l=(await i.cache.load(S,"load-oas")).compoundHash;await i.cache.load(s,{loader:async function(){for(const{node:m,markdown:f,pointer:n,key:r,relativePath:h}of a){const{ast:_}=await e.parseMarkdoc({content:f,relativePath:n,isVirtual:p},i,{sharedDataIds:[`${U}${h}`]});m[`x-parsed-md-${r}`]={result:Z(_)}}},name:"openapi-markdoc-inline-parser"},[l]);for(const{pointer:u}of a)c.add(u)}const R=M.difference(c);for(const a of R)i.cache.delete(a);M=c;for(const[a,s]of Object.entries(A))await e.createSharedData(a,{...s,baseSlug:e.getRouteByFsPath(s.fsPath)?.baseSlug},s.hash)}}}export{Oe as openAPIDocsPlugin};
1
+ import{simplifyAstStructure as Z}from"@redocly/openapi-docs";import{REDOCLY_TEAMS_RBAC as D}from"@redocly/config";import{OPENAPI_DOCS_TEMPLATE_ID as $,PUBLIC_RBAC_SCOPE_ITEM as j}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as ee,PUBLIC_API_DEFINITIONS_FOLDER as te}from"../../constants/common.js";import{OPENAPI_CUSTOM_FIELDS_SERVER_PROPS_GETTER_ID as oe,OPENAPI_SHARED_DATA_PREFIX as U}from"../../constants/plugins/openapi-docs.js";import{isDevelopMode as V}from"../../utils/envs/is-develop-mode.js";import{searchResolver as ae}from"./search/search-resolver.js";import{convertOpenAPIDocs2Sidebar as re,shouldAddRoute as se}from"./utils.js";import{getTemplatePath as b}from"./get-template-path.js";import{storeDefinitionBundles as ne}from"./store-definition-bundles.js";import{definitionLoader as ie,definitionsLoader as pe}from"./load-definition.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{fromCurrentDir as ce}from"../../utils/paths.js";import{telemetryTraceStep as le}from"../../../cli/telemetry/helpers/trace-step.js";const w="openapi-spec-download";async function ve(){let L=[],A={},M=new Set;return{id:"openapi",requiredEntitlements:["openapi"],loaders:{"load-oas-docs":pe,"load-oas":ie},processContent:async(e,p)=>{await le("build.plugin.openapi_docs",async u=>{e.createRequestHandler(w,ce(import.meta.url,"./spec-download.api.js")),e.addApiRoute({slug:te+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})}),e.addApiRoute({slug:ee+"/*",requestHandlerId:w,httpMethod:"all",[D]:j,getStaticData:async()=>({props:{}})});const R=e.createTemplate($,b("./template/OpenAPIDocs.js")),a=e.registerServerPropsGetter($,b("./get-server-props.js")),s=e.registerServerPropsGetter(oe,b("./get-server-props-custom-fields.js")),d=await p.getConfig();u?.setAttribute("config",JSON.stringify(d.openapi||{}));const g=d.rules?.["custom-fields-schema"];A={};const m=await e.loadOpenApiDefinitions(p);L=m.map(({markdocChunks:r,relativePath:f,customOutputRelativeFile:i,isVirtual:n,realRelativePath:c})=>({chunks:r,relativePath:f,realRelativePath:c,isVirtual:i!=null||n})),ne(m,e.outdir);const S={};for(const r of m||[]){const{definition:f,config:i,relativePath:n,customOutputRelativeFile:c,contentItems:_,flatItems:k,parser:E,options:B,rawOptions:q,hash:J}=r,N=c||n,o=[],x={},{definition:Q}=E||{},{info:l}=Q||{},O=l?.["x-metadata"],v=!!i.openapi?.excludeFromSearch||!!i.theme?.openapi?.excludeFromSearch||!!d.openapi?.excludeFromSearch||!!d.theme?.openapi?.excludeFromSearch,G={title:l?.title,description:l?.description,summary:l?.summary,...i.metadata,...O},h={untagged:[],tagged:new Map};for(const t of k){const{id:C,href:I,operationDefinition:y}=t;if(y){const{tags:P}=y;if(P)for(const T of P)h.tagged.has(T)||h.tagged.set(T,[]),h.tagged.get(T)?.push(t);else h.untagged.push(t);V()&&(x[`#${y.pointer}`]=t.href)}if(!se({item:t}))continue;const F=t,Y=F.type==="section"&&!!F.infoDefinition,z=I.split("#")[0]+"/",K=t?.operationDefinition?.[D];o.push({excludeFromSearch:v,slugSuffix:z,fsPath:N,metadata:{subType:"openapi-operation"},httpVerb:t?.httpVerb||"",path:n,templateId:R,[D]:K||i.rbac,getAiDocumentsStore:de({parser:E,options:B,info:l,tagOperations:h,openapiContentItem:F,metadata:G,relativePath:n,getSearchFacets:e.getSearchFacets,includeInLLMsTxt:Y,excludeFromSearch:v}),getStaticData:async P=>({props:{dynamicMarkdocComponents:["openapi"],baseSlug:P.baseSlug,seo:t["x-metadata"]?.seo||{title:t.name,description:t.description},itemId:C,disableAutoScroll:!0}})})}o[0]={...o[0],metadata:{type:"openapi",...G},hasClientRoutes:!0,getSidebar:(t,C)=>{const I=[];return re({contentItems:_,sidebarItems:I,routeSlug:t.slug,navItem:C}),I},getNavText:()=>l?.title,getSearchDocuments:ae(E,B,k,e.getSearchFacets,e.setSearchFacets,v)},O?.apiId&&(S[O.apiId]={slug:o[0]?.slug||""});const W=o[0];o[0]=o[o.length-1],o[o.length-1]=W;for(const t of o)e.addRoute({...t,serverPropsGetterIds:g?[a,s]:[a]});const X=V()?n:void 0,H=`${U}${n}`;A[H]={fsPath:N,definition:f,options:q,sourcePath:X,routesMapping:x,hash:J};for(const t of o)e.addRoute({...t,sharedData:[{id:H,key:"openAPIDocsStore"}],serverPropsGetterIds:g?[a,s]:[a]})}e.setGlobalData({apiProducts:S})})},afterRoutesCreated:async(e,p)=>{const u=new Set;for(const{chunks:a,relativePath:s,isVirtual:d,realRelativePath:g}of L){const m=e.getAllRoutes().filter(r=>r.fsPath===s).map(r=>r.slug),S=(await p.cache.load(g,"load-oas")).compoundHash;await p.cache.load(s,{loader:async function(){for(const{node:f,markdown:i,key:n,relativePath:c}of a){const{ast:_}=await e.parseMarkdoc({content:i,relativePath:c,isVirtual:d},p,{sharedDataIds:[`${U}${c}`],routeSlugs:m});f[`x-parsed-md-${n}`]={result:Z(_)}}},name:"openapi-markdoc-inline-parser"},[S]);for(const{pointer:r}of a)u.add(r)}const R=M.difference(u);for(const a of R)p.cache.delete(a);M=u;for(const[a,s]of Object.entries(A))await e.createSharedData(a,{...s,baseSlug:e.getRouteByFsPath(s.fsPath)?.baseSlug},s.hash)}}}export{ve as openAPIDocsPlugin};
@@ -1 +1 @@
1
- import{sqliteTable as i,text as e,integer as r,index as o,uniqueIndex as n}from"drizzle-orm/sqlite-core";const l=i("entities_relations",{id:e("id").primaryKey(),organizationId:e("organization_id").notNull(),projectId:e("project_id").notNull(),sourceKey:e("source_key").notNull(),sourceVersion:e("source_version").default("").notNull(),sourceRevision:e("source_revision").default("").notNull(),sourceToTargetRelation:e("source_to_target_relation").notNull(),targetKey:e("target_key").notNull(),targetVersion:e("target_version").default("").notNull(),targetRevision:e("target_revision").default("").notNull(),targetToSourceRelation:e("target_to_source_relation").notNull(),sourceFile:e("source_file"),fileHash:e("file_hash"),isDeleted:r("is_deleted",{mode:"boolean"}).default(!1),createdAt:e("created_at").notNull(),updatedAt:e("updated_at").notNull()},t=>[o("idx_entities_relations_source_key").on(t.sourceKey,t.isDeleted),o("idx_entities_relations_target_key").on(t.targetKey,t.isDeleted),o("idx_entities_relations_source_target").on(t.sourceToTargetRelation),o("idx_entities_relations_target_source").on(t.targetToSourceRelation),n("idx_entities_relations_unique").on(t.sourceKey,t.targetKey,t.sourceVersion,t.targetVersion,t.sourceRevision,t.targetRevision)]);export{l as entitiesRelationsTable};
1
+ import{sqliteTable as i,text as e,integer as r,index as o,uniqueIndex as n}from"drizzle-orm/sqlite-core";const u=i("entities_relations",{id:e("id").primaryKey(),organizationId:e("organization_id").notNull(),projectId:e("project_id").notNull(),sourceKey:e("source_key").notNull(),sourceVersion:e("source_version").default("").notNull(),sourceRevision:e("source_revision").default("").notNull(),sourceToTargetRelation:e("source_to_target_relation").notNull(),targetKey:e("target_key").notNull(),targetVersion:e("target_version").default("").notNull(),targetRevision:e("target_revision").default("").notNull(),targetToSourceRelation:e("target_to_source_relation").notNull(),sourceFile:e("source_file"),fileHash:e("file_hash"),isDeleted:r("is_deleted",{mode:"boolean"}).default(!1),createdAt:e("created_at").notNull(),updatedAt:e("updated_at").notNull()},t=>[o("idx_entities_relations_source_key").on(t.sourceKey,t.isDeleted),o("idx_entities_relations_target_key").on(t.targetKey,t.isDeleted),o("idx_entities_relations_source_target").on(t.sourceToTargetRelation),o("idx_entities_relations_target_source").on(t.targetToSourceRelation),n("idx_entities_relations_unique").on(t.sourceKey,t.targetKey,t.sourceVersion,t.targetVersion,t.sourceRevision,t.targetRevision,t.sourceToTargetRelation)]);export{u as entitiesRelationsTable};
@@ -1,3 +1,4 @@
1
+ import type { Node } from '@markdoc/markdoc';
1
2
  import type { JSX } from 'react';
2
3
  import type { CommonError, GlobalData } from '../types/index.js';
3
4
  import type { WildcardRedirectsTree } from './types';
@@ -43,6 +44,7 @@ export declare class Store {
43
44
  sharedDataDeps: Map<string, Set<string>>;
44
45
  sharedDataMarkdocComponents: Map<string, Set<string>>;
45
46
  routesDynamicComponents: Map<string, Set<string>>;
47
+ routesPartials: Map<string, string[]>;
46
48
  ssr: {
47
49
  preBodyTags: string[];
48
50
  postBodyTags: string[];
@@ -108,7 +110,7 @@ export declare class Store {
108
110
  variables?: Record<string, any> | undefined;
109
111
  functions?: Record<string, import("@markdoc/markdoc").ConfigFunction> | undefined;
110
112
  validation?: {
111
- parents?: import("@markdoc/markdoc").Node[];
113
+ parents?: Node[];
112
114
  validateFunctions?: boolean;
113
115
  environment?: string;
114
116
  };
@@ -119,13 +121,14 @@ export declare class Store {
119
121
  info: {
120
122
  sharedDataDeps?: Set<string>;
121
123
  dynamicMarkdocComponents?: string[];
124
+ partials?: string[];
122
125
  tagList?: string[];
123
126
  htmlTagsList?: string[];
124
127
  tagOccurrence?: Record<string, number>;
125
128
  codeSnippetLanguages?: Record<string, number>;
126
129
  codeWalkthroughLanguages?: Record<string, number>;
127
130
  };
128
- ast: import("@markdoc/markdoc").Node;
131
+ ast: Node;
129
132
  compoundHash: string;
130
133
  }>;
131
134
  loadOpenApiDefinitions(context: LifecycleContext): Promise<OpenApiBundledDefinition[]>;
@@ -141,6 +144,7 @@ export declare class Store {
141
144
  createSharedData: (id: string, data: unknown, hash?: string) => Promise<string>;
142
145
  addRouteSharedData: (routeSlug: string, dataKey: string, dataId: string) => void;
143
146
  getRouteSharedDataByFsPath: (fsPath: string) => Record<string, string>;
147
+ getPartialsForRoute: (slug: string) => Record<string, Node>;
144
148
  addRoute: (route: PageRouteInit) => void;
145
149
  addRouteSharedDataToAllLocales: (slug: string, dataKey: string, dataId: string) => void;
146
150
  addApiRoute: (route: ApiRoute) => void;
@@ -1 +1 @@
1
- import A from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as P}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as T}from"../utils/guards/is-object.js";import{mapObject as O}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as M}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as k}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as L}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as G}from"./ssr/render.js";import{readStaticData as I,writeStaticData as N}from"./utils/static-data.js";import{parseAndResolveMarkdoc as V}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as j}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as y}from"./entitlements/entitlements-provider.js";import{isL10nPath as H}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as U}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as K}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as q}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map"},g="markdown/partials",Ee="markdown/partials-deps",v="PLAN_GATES",$=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORG_ID"],be="userDefinedApiFunctions";class E{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#e={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#t=new Map;constructor({outdir:e,contentDir:t,serverMode:s=!1,serverOutDir:r}){this.#r=t,this.outdir=e,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(e,t){const s=this.listeners.get(e);s?s.add(t):this.listeners.set(e,new Set([t]))}queueEvent=(e,t,...s)=>{this.#t.set(e+String(t),[e,t,...s])};runListeners=(e,t,...s)=>{for(const r of this.listeners.get(e)||new Set)t?r(t,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(e=>{this.#i=e})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const e of this.#t.values())this.runListeners(...e);this.#t.clear()}startEsbuildRun(){this.#n=new Promise(e=>{this.#c=e})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await q("build.reload_markdoc_options",async()=>{const e=y.instance(),t=await j(this.serverOutDir),s=Object.fromEntries(Object.entries(t.tags).filter(([r])=>D[r]!=null?e.canAccessFeature(D[r]):!0));this.#s={...t,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=e=>{const t=this.globalData,s={...this.globalData,...e};this.globalData=s,JSON.stringify(s)!==JSON.stringify(t)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;parseMarkdoc=async(e,t,s)=>{const{data:{info:r,ast:a},compoundHash:i}=await V(e,this.markdocOptions,{actions:this,context:t});for(const o of r.sharedDataDeps||[]){for(const n of s?.routeSlugs||[])this.addRouteSharedData(n,o,o);for(const n of s?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(o),this.sharedDataDeps.set(n,c)}}for(const o of r.dynamicMarkdocComponents||[]){for(const n of s?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(o),this.routesDynamicComponents.set(n,c)}for(const n of s?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(o),this.sharedDataMarkdocComponents.set(n,c)}}return{info:r,ast:a,compoundHash:i}};async loadOpenApiDefinitions(e){return(await e.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(e){return(await e.cache.load(".","asyncapi-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setGlobalConfig=e=>{const t=Object.keys(e);for(const i of t)for(const o in this.replacedEnvVars)if(o===i||o.startsWith(`${i}:`)){const n=o.split(":"),{error:c,value:d}=w(e,n);(c||d!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=U(e);for(const i of r)this.unsetEnvVars.add(i);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,t)=>{if(!y.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(e).toLowerCase();this.config.redirects[a]=t,a.endsWith("*")&&K(this.config.wildcardRedirectsTree,a)};getRedirect=e=>{const t=f(e).toLowerCase();return x(t,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(e,t,s)=>{if(s&&this.#e[e]===s)return e;const r=JSON.stringify(t),a=s??L(r);return this.#e[e]===a||(this.#e[e]=a,await B(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,t,s)=>{const r=M(e),a=this.routesSharedData.get(r)||{};a[t]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${e}, ${t}, ${s}`)};getRouteSharedDataByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.routesSharedData.get(t)||{}:{}};addRoute=e=>{const s={...J(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:s}),p.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,t,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const i=C(e,u,a.code,r);this.addRouteSharedData(i,t,s)}};addApiRoute=e=>{this.apiRoutes.push(e),p.verbose("Created API route %s",e.slug)};addMiddleware=e=>{this.middleware.push(e),p.verbose("Created middleware %s",e.id)};getRouteByFsPath=e=>{const t=this.routesByFsPath.get(e);return t?this.getRouteBySlug(t):void 0};getRouteBySlug=(e,t={})=>{const{followRedirect:s=!0}=t,r=this.getRedirect(e);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(e)};slugHasRouteOrRedirect=e=>{if(this.routesBySlug.has(e))return!0;const t=this.getRedirect(e);if(!t)return!1;if(!k(t.to))return!0;const s=f(t.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=e=>this.newRoutes.filter(t=>t.templateId===e);getAllRoutesForLocale=(e=u)=>{const t=Array.from(this.routesBySlug.values()),s=e.toLowerCase();return t.filter(r=>e===u?!H(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,t)=>(this.templates.set(e,t),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,t)=>(this.apiRoutesRequestHandlers.set(e,t),e);registerServerPropsGetter=(e,t)=>(this.serverPropsGetters.set(e,t),e);registerPagePropsGetter=(e,t)=>{this.pagePropsGetters.set(e,t)};async writeRouteStaticData(e,t){const s=await this.resolveRouteStaticData(e,t,!1);s&&N(e.slug,s,this.outdir)}async resolveRouteStaticData(e,t,s){if(this.serverMode)return I(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(d,l)=>this.parseMarkdoc(d,l,{routeSlugs:[e.slug]})},a=await e.getStaticData?.(e,r)||{},i=new Set(this.routesDynamicComponents.get(e.slug)),o=this.routesSharedData.get(e.slug)||{};for(const d of Object.values(o)){const l=this.sharedDataMarkdocComponents.get(d);l&&l.forEach(h=>i.add(h));const m=this.sharedDataDeps.get(d);m&&m.forEach(h=>this.addRouteSharedData(e.slug,h,h))}const n=this.getGlobalConfig("seo"),c=a?.frontmatter||{};return{...a,frontmatter:{...c,seo:{...c?.seo,title:c?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(i),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:P,...n,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,t){if(!e?.length)return;const s=typeof e[0]=="string"?e.join(""):G(e);s&&(t==="head"?this.ssr.headTags.push(s):t==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());e.push([s,a]);break;case"object":s==="config"&&e.push([s,await this.getConfigWithEnvPlaceholders()]),e.push([s,this[s]]);break;default:throw new Error("Invalid format")}const t=Object.fromEntries(e);return t[v]=F("PLAN_GATES"),t}static fromJson(e,t){const s=new E(t);for(const[a,i]of Object.entries(R))switch(i){case"map":s[a]=new Map(e[a]);break;case"object":if(a==="config"){s.setGlobalConfig(e[a]);break}s[a]=e[a];break;default:throw new Error("Invalid format")}s.config[g]=W(s.config[g]||{});const r=e[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const t in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[t],r=t.split(":"),a=r.pop(),{error:i,value:o}=w(e,r);if(i||!T(o)&&!Array.isArray(o)){await S.panicOnBuild(`Failed to replace env var with env name for ${t}`);continue}o[a]=s}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(s=>!$.includes(s));if(e.length===0)return;const t=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await S.panicOnBuildContentError(t)}}function W(b){return O(b,e=>A.Ast.fromJSON(JSON.stringify(e)))}export{g as MARKDOC_PARTIALS_DATA_KEY,Ee as MARKDOC_PARTIALS_DEPS_KEY,E as Store,be as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import b from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as A}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as T}from"../utils/guards/is-object.js";import{mapObject as M}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as O}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as k}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as L}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as G}from"./ssr/render.js";import{readStaticData as I,writeStaticData as N}from"./utils/static-data.js";import{parseAndResolveMarkdoc as V}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as j}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as y}from"./entitlements/entitlements-provider.js";import{isL10nPath as H}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as U}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as K}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as q}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",Et="markdown/partials-deps",v="PLAN_GATES",$=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORG_ID"],Pt="userDefinedApiFunctions";class E{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await q("build.reload_markdoc_options",async()=>{const t=y.instance(),e=await j(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await V(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=w(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=U(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!y.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&K(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??L(r);return this.#t[t]===a||(this.#t[t]=a,await B(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=O(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...J(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=C(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!k(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!H(r.fsPath):r.slug.startsWith(`/${s}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&N(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return I(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:A,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):G(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=F("PLAN_GATES"),e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=W(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=w(t,r);if(c||!T(o)&&!Array.isArray(o)){await S.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!$.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await S.panicOnBuildContentError(e)}}function W(P){return M(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,Et as MARKDOC_PARTIALS_DEPS_KEY,E as Store,Pt as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -52,6 +52,7 @@ export type GetServerPropsContext = {
52
52
  getGlobalConfig<T = unknown>(key: string): T | undefined;
53
53
  getGlobalData: () => GlobalData;
54
54
  getRouteSharedDataByFsPath: (routeFsPath: string) => Record<string, string> | undefined;
55
+ getPartialsForRoute?: (slug: string) => Record<string, Node>;
55
56
  serverOutDir: string;
56
57
  };
57
58
  export type GetServerPropsFn<TData extends PageStaticData = PageStaticData, TProps extends PageProps = PageProps> = (route: PageRouteDetails<TData, TProps>, data: TData, mdOptions: MdOptions, actions: GetServerPropsContext) => Promise<TProps>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/revel",
3
- "version": "0.130.0-next.0",
3
+ "version": "0.130.0-next.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -32,7 +32,7 @@
32
32
  "@opentelemetry/sdk-trace-web": "2.0.1",
33
33
  "@opentelemetry/semantic-conventions": "1.34.0",
34
34
  "@redocly/ajv": "8.17.1",
35
- "@redocly/openapi-core": "2.14.3",
35
+ "@redocly/openapi-core": "2.14.5",
36
36
  "@shikijs/transformers": "3.21.0",
37
37
  "@tanstack/react-query": "5.62.3",
38
38
  "@tanstack/react-table": "8.21.3",
@@ -93,13 +93,13 @@
93
93
  "xml-crypto": "6.0.1",
94
94
  "xpath": "0.0.34",
95
95
  "yaml-ast-parser": "0.0.43",
96
- "@redocly/asyncapi-docs": "1.7.0-next.0",
96
+ "@redocly/asyncapi-docs": "1.7.0-next.1",
97
97
  "@redocly/config": "0.41.2",
98
98
  "@redocly/graphql-docs": "1.7.0-next.0",
99
- "@redocly/openapi-docs": "3.18.0-next.0",
99
+ "@redocly/openapi-docs": "3.18.0-next.1",
100
100
  "@redocly/portal-legacy-ui": "0.13.0-next.0",
101
- "@redocly/portal-plugin-mock-server": "0.15.0-next.0",
102
- "@redocly/realm-asyncapi-sdk": "0.8.0-next.0",
101
+ "@redocly/portal-plugin-mock-server": "0.15.0-next.1",
102
+ "@redocly/realm-asyncapi-sdk": "0.8.0-next.1",
103
103
  "@redocly/theme": "0.62.0-next.0"
104
104
  },
105
105
  "peerDependencies": {