@redocly/revel-reef 0.130.0-next.1 → 0.130.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/eject/resolveEjectParams.js +1 -1
  4. package/dist/cli/stats/collectors/openapi.d.ts +3 -0
  5. package/dist/cli/stats/collectors/openapi.js +1 -0
  6. package/dist/cli/stats/index.d.ts +7 -0
  7. package/dist/cli/stats/index.js +1 -0
  8. package/dist/cli/stats/options.d.ts +3 -0
  9. package/dist/cli/stats/options.js +1 -0
  10. package/dist/cli/telemetry/index.d.ts +1 -1
  11. package/dist/cli/telemetry/index.js +1 -1
  12. package/dist/client/app/Sidebar/Sidebar.js +1 -1
  13. package/dist/server/fs/cache.js +1 -1
  14. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +2 -2
  15. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  16. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +8 -0
  17. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.js +1 -0
  18. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-read-model.js +1 -1
  19. package/dist/server/plugins/catalog-entities/database/mappers/map-entity-relation-row.js +1 -1
  20. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.d.ts +2 -2
  21. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-bff-repository.js +14 -14
  22. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +2 -2
  23. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +5 -3
  24. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +2 -2
  25. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  26. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.d.ts +2 -1
  27. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  28. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-relations-repository.js +1 -1
  29. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  30. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  31. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.js +1 -1
  32. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +4 -3
  33. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  34. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +2 -2
  35. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +1 -1
  36. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.js +1 -1
  37. package/dist/server/plugins/catalog-entities/get-server-props.js +1 -1
  38. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  39. package/dist/server/plugins/catalog-entities/schemas/database-schemas.d.ts +3 -0
  40. package/dist/server/plugins/catalog-entities/schemas/database-schemas.js +1 -1
  41. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.d.ts +12 -0
  42. package/dist/server/plugins/catalog-entities/schemas/dto-schemas.js +1 -1
  43. package/dist/server/plugins/catalog-entities/schemas/read-model-schemas.d.ts +1 -0
  44. package/dist/server/plugins/catalog-entities/types/extractors.d.ts +4 -4
  45. package/dist/server/plugins/config-parser/loaders/content-slugs-loader.js +1 -1
  46. package/dist/server/plugins/default-theme/index.js +1 -1
  47. package/dist/server/plugins/openapi-docs/index.js +1 -1
  48. package/dist/server/plugins/search/ai-indexer/prepare-ai-search-documents.js +1 -1
  49. package/dist/server/plugins/search/documents/search-documents.js +1 -1
  50. package/dist/server/plugins/sso/index.js +1 -1
  51. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0005_catalog-relations-constraint-fix.sql +2 -0
  52. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0006_add-catalog-entitities-attributes-table.sql +11 -0
  53. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0005_snapshot.json +393 -0
  54. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0006_snapshot.json +458 -0
  55. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/_journal.json +14 -0
  56. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.d.ts +143 -0
  57. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js +1 -0
  58. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js +1 -1
  59. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0007_catalog-relations-constraint-fix.sql +2 -0
  60. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0008_add-catalog-entitities-attributes-table.sql +11 -0
  61. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0007_snapshot.json +833 -0
  62. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0008_snapshot.json +898 -0
  63. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/_journal.json +14 -0
  64. package/dist/server/utils/rbac.d.ts +11 -7
  65. package/dist/server/utils/rbac.js +1 -1
  66. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  67. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @redocly/revel-reef
2
2
 
3
+ ## 0.130.0-next.3
4
+
5
+ ### Minor Changes
6
+
7
+ - e24e828523: Added ejectable `DocumentationLayoutTop` and `DocumentationLayoutBottom` to customize component positions in `DocumentationLayout`.
8
+
9
+ ### Patch Changes
10
+
11
+ - d309b3d828: Fixed language icon rendering issues in API docs.
12
+ - 3af7a906b4: Fixed an issue where URLs of OpenAPI docs pages could automatically receive `-1` suffixes.
13
+ - Updated dependencies [9562d72bd7]
14
+ - Updated dependencies [d309b3d828]
15
+ - Updated dependencies [e24e828523]
16
+ - @redocly/openapi-docs@3.18.0-next.2
17
+ - @redocly/theme@0.62.0-next.1
18
+ - @redocly/asyncapi-docs@1.7.0-next.2
19
+ - @redocly/portal-plugin-mock-server@0.15.0-next.2
20
+ - @redocly/graphql-docs@1.7.0-next.0
21
+
22
+ ## 0.129.2
23
+
24
+ ### Patch Changes
25
+
26
+ - 237e61721c: Fixed an issue where project processing could halt indefinitely due to incorrect cache handling.
27
+
28
+ ## 0.130.0-next.2
29
+
30
+ ### Minor Changes
31
+
32
+ - 6238b833f0: Fixed sidebar header layout issue.
33
+
34
+ ### Patch Changes
35
+
36
+ - 134e0817c3: Fixed an issue where project processing could halt indefinitely due to incorrect cache handling.
37
+ - 8e31351cfa: Updated `@redocly/openapi-core` to version `2.14.5`.
38
+ - Updated dependencies [8e31351cfa]
39
+ - Updated dependencies [39d177b9b6]
40
+ - @redocly/openapi-docs@3.18.0-next.1
41
+ - @redocly/realm-asyncapi-sdk@0.8.0-next.1
42
+ - @redocly/asyncapi-docs@1.7.0-next.1
43
+ - @redocly/portal-plugin-mock-server@0.15.0-next.1
44
+ - @redocly/theme@0.62.0-next.0
45
+
3
46
  ## 0.130.0-next.1
4
47
 
5
48
  ### 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)}
@@ -1 +1 @@
1
- import*as a from"path";import{DEFAULT_THEME_NAME as i,USER_THEME_ALIAS as k}from"../../constants/common.js";import{logger as T}from"../../server/tools/notifiers/logger.js";import{reporter as F}from"../../server/tools/notifiers/reporter.js";import{resolveTheme as y}from"./resolveTheme.js";import{EntitlementsProvider as A}from"../../server/entitlements/entitlements-provider.js";const v=["markdoc/attributes/code-walkthrough-filesets.ts","markdoc/attributes/code-walkthrough-filters.ts","markdoc/components/CodeWalkthrough/**","markdoc/tags/code-step.ts","markdoc/tags/code-toggle.ts","markdoc/tags/code-walkthrough.ts"],m=["./core/**","./markdoc/**/default.*","**/__mocks__/**","**/index.*","**/utils/**/*","**/__tests__/**/*","**/__snapshots__/**/*","**/*.stories.*","**/variables.*",...v],C=["./components/CatalogClassic/CatalogClassicCard.*","./components/ColorModeSwitcher/**","./components/Feedback/**","./components/Filter/**","./components/Footer/**","./components/LanguagePicker/**","./components/Menu/**","./components/Navbar/**","./components/PageNavigation/**","./components/Product/**","./components/Search/**","./components/UserMenu/**","./layouts/RootLayout.*","./layouts/NotFound.*","./layouts/Forbidden.*","./icons/**","./markdoc/**","./ext/**"];async function j(t){const[p,n]=t._,{theme:l,force:d,onSuccess:g,onError:u,onOverride:h,config:E}=t,_=A.instance(),s=a.resolve(t["project-dir"]);let o=l;o||(o=i);const r=await y(s,E.plugins||[],o,n);r||await F.panicOnContentError(`Theme ${o} not found. Skipping eject.`);const e=r?.config.ejectIgnore;e&&!Array.isArray(e)&&T.warn("'ejectIgnore' must be of type Array. Skipping.");const c=await _.getPackageEjectIgnore(),f={force:d,onSuccess:g,onError:u,onOverride:h,onlyFiles:o===i?C:void 0,ignoreFiles:Array.isArray(e)?[...e,...c,...m]:[...c,...m]};return{objectType:p,pathToThemeFolder:r?.pluginDirAbsolutePath,pathToPortalCustomThemeFolder:a.resolve(s,k),componentToEject:n,theme:o,options:f}}export{m as DEFAULT_IGNORED_FILES,C as EJECTABLE_FILES,j as default};
1
+ import*as c from"path";import{DEFAULT_THEME_NAME as i,USER_THEME_ALIAS as k}from"../../constants/common.js";import{logger as y}from"../../server/tools/notifiers/logger.js";import{reporter as T}from"../../server/tools/notifiers/reporter.js";import{resolveTheme as F}from"./resolveTheme.js";import{EntitlementsProvider as A}from"../../server/entitlements/entitlements-provider.js";const L=["markdoc/attributes/code-walkthrough-filesets.ts","markdoc/attributes/code-walkthrough-filters.ts","markdoc/components/CodeWalkthrough/**","markdoc/tags/code-step.ts","markdoc/tags/code-toggle.ts","markdoc/tags/code-walkthrough.ts"],m=["./core/**","./markdoc/**/default.*","**/__mocks__/**","**/index.*","**/utils/**/*","**/__tests__/**/*","**/__snapshots__/**/*","**/*.stories.*","**/variables.*",...L],v=["./components/CatalogClassic/CatalogClassicCard.*","./components/ColorModeSwitcher/**","./components/Feedback/**","./components/Filter/**","./components/Footer/**","./components/LanguagePicker/**","./components/Menu/**","./components/Navbar/**","./components/PageNavigation/**","./components/Product/**","./components/Search/**","./components/UserMenu/**","./layouts/RootLayout.*","./layouts/NotFound.*","./layouts/Forbidden.*","./layouts/DocumentationLayoutTop.*","./layouts/DocumentationLayoutBottom.*","./icons/**","./markdoc/**","./ext/**"];async function C(t){const[p,n]=t._,{theme:l,force:d,onSuccess:u,onError:g,onOverride:h,config:E}=t,_=A.instance(),s=c.resolve(t["project-dir"]);let o=l;o||(o=i);const r=await F(s,E.plugins||[],o,n);r||await T.panicOnContentError(`Theme ${o} not found. Skipping eject.`);const e=r?.config.ejectIgnore;e&&!Array.isArray(e)&&y.warn("'ejectIgnore' must be of type Array. Skipping.");const a=await _.getPackageEjectIgnore(),f={force:d,onSuccess:u,onError:g,onOverride:h,onlyFiles:o===i?v:void 0,ignoreFiles:Array.isArray(e)?[...e,...a,...m]:[...a,...m]};return{objectType:p,pathToThemeFolder:r?.pluginDirAbsolutePath,pathToPortalCustomThemeFolder:c.resolve(s,k),componentToEject:n,theme:o,options:f}}export{m as DEFAULT_IGNORED_FILES,v as EJECTABLE_FILES,C as default};
@@ -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};
@@ -123,11 +123,11 @@ export declare class CatalogEntitiesService {
123
123
  * @param filter - The conditions used to select which entity relations to delete.
124
124
  */
125
125
  deleteEntityRelationsInLocalDatabase(filter: Filter): Promise<void>;
126
- getEntitiesWithRelations(paginationParams?: PaginationParams): Promise<BffCatalogEntityList>;
126
+ getEntitiesWithRelations(paginationParams?: PaginationParams, rbacTeams?: string[]): Promise<BffCatalogEntityList>;
127
127
  getEntityWithRelationsByKey(entityKey: string, filter?: {
128
128
  revision?: string | null;
129
129
  version?: string | null;
130
- }): Promise<BffCatalogEntity | null>;
130
+ }, rbacTeams?: string[]): Promise<BffCatalogEntity | null>;
131
131
  getRelatedEntities(entityKey: string, paginationParams?: PaginationParams): Promise<BffCatalogRelatedEntityList>;
132
132
  softDeleteEntitiesInLocalDatabase({ filter, revision, fileHash, }: {
133
133
  filter: Filter;
@@ -1 +1 @@
1
- import{entityFileSchema as d}from"@redocly/config";import{deepMerge as y}from"../../../../utils/object/deep-merge.js";import{promiseMapLimit as c}from"../../../utils/async/promise-map-limit.js";import{logger as r}from"../../../tools/notifiers/logger.js";import{entityRelationDtoSchema as h}from"../schemas/dto-schemas.js";import{CatalogEntitiesLocalRepository as m}from"./repositories/local/catalog-entities-local-repository.js";import{CatalogEntitiesRemoteRepository as R}from"./repositories/remote/catalog-entities-remote-repository.js";import{prepareListResponse as o}from"../../../web-server/utils/prepare-list-response.js";import{ENTITY_RELATION_FROM_DATABASE as l}from"./mappers/field-transformations.js";import{createValidator as u}from"../utils/ajv-validator.js";import{hasOptionsChanged as w}from"../utils/has-options-changed.js";const E=15,f=u(h,{errorPrefix:"Entity relation validation failed:",dataVar:"entity relation"}),p=u(d,{errorPrefix:"Entity file validation failed:",dataVar:"entity"});class n{static#a;static#i;#t;#e;constructor(t,e){this.#t=t,this.#e=e}static async#n(t){const[e,a]=await Promise.all([m.getInstance(t),t.runOnlyLocalDatabase?null:R.getInstance(t)]),i=new n(e,a);a&&(process.env.NODE_ENV==="development"&&r.info("Attaching remote database to local database"),await i.#t.attachDatabase(a.path)),n.#a=i,n.#i=t}static async getInstance(t){return t.runOnlyLocalDatabase===void 0&&(t.runOnlyLocalDatabase=process.env.REDOCLY_LOCAL_DEV==="true"||process.env.CI==="true"),t.removeExisting===void 0&&(t.removeExisting=!1),(!n.#a||w(n.#i,t))&&await n.#n(t),n.#a}async transaction(...t){return this.#t.transactionsManager.transaction(...t)}async getEntities(t){await this.#e?.sync();const{items:e,total:a,hasMore:i}=await this.#t.getEntities(t);return o({data:e,params:t,totalCount:a,hasMore:i})}async getEntityByKey(t){return await this.#e?.sync(),await this.#t.getEntityByKey(t)}async getEntityKeysAndVersionsBySourceFile(t){return await this.#e?.sync(),this.#t.getEntityKeysAndVersionsBySourceFile(t)}async getEntitiesCountByTypes(){return await this.#e?.sync(),this.#t.getEntitiesCountByTypes()}async getCatalogFilters(t){return await this.#e?.sync(),this.#t.getCatalogFilters(t)}async createEntity(t){return this.#e?this.#e.createEntity(t):(r.warn("No remote database found"),null)}async createEntities(t){const e=this.#e;return e?await c(t,E,async a=>e.createEntity(a).then(i=>({status:"ok",resource:i})).catch(i=>({key:a.key,status:"error",error:i}))):(r.warn("No remote database found"),[])}getEntitySources(){return this.#t.getEntitySources()}async createEntityInLocalDatabase(t){return this.#t.createEntity(t)}async createEntitiesInLocalDatabase(t){await this.#t.createEntities(t)}async createEntityRelationInLocalDatabase(t){await this.#t.createEntityRelation(t)}async createEntityRelationsInLocalDatabase(t){await this.#t.createEntityRelations(t)}async updateEntityByKey(t,e){const a=await this.#t.getEntityByKey(t);if(!a)throw new Error(`Entity with key ${t} not found`);const i=y(a,e),s=p(i);return await this.#e?.updateEntity({...s,id:a.id,createdAt:a.createdAt||""})}async deleteEntityByKey(t){const e=await this.#e?.deleteEntity(t);return await this.#s(t),e}async deleteEntitiesInLocalDatabase(t){await this.#t.deleteEntities(t)}async getEntityRelationById(t){return await this.#e?.sync(),await this.#t.getEntityRelationById(t)}async getEntitiesRelations(t={}){await this.#e?.sync();const{items:e,total:a,hasMore:i}=await this.#t.getEntitiesRelations(t);return o({data:e,params:t,totalCount:a,nameTransformationsFromDatabase:l,hasMore:i})}async createEntityRelation(t){return this.#e?.createEntityRelation(t)}async createEntitiesRelations(t){const e=this.#e;return e?await c(t,E,async a=>e.createEntityRelation(a).then(i=>({status:"ok",resource:i})).catch(i=>({key:a.sourceKey,status:"error",error:i}))):(r.warn("No remote database found"),[])}async updateEntityRelation(t,e){const a=await this.#t.getEntityRelationById(t);if(!a)throw new Error(`Entity relation with id ${t} not found`);const i=y(a,e),s=f(i);return this.#e?.createEntityRelation(s)}async deleteEntityRelation(t){let e=await this.#e?.deleteEntityRelation(t);return e||(e=await this.#t.deleteEntityRelation(t)),e}async deleteEntityRelationsInLocalDatabase(t){await this.#t.deleteEntityRelations(t)}async getEntitiesWithRelations(t={}){await this.#e?.sync();const{items:e,total:a,hasMore:i}=await this.#t.getEntitiesWithRelations(t);return o({data:e,params:t,totalCount:a,hasMore:i})}async getEntityWithRelationsByKey(t,e){return this.#t.getEntityWithRelationsByKey(t,e)}async getRelatedEntities(t,e={}){await this.#e?.sync();const{items:a,total:i,hasMore:s}=await this.#t.getRelatedEntities(t,e);return o({data:a,params:e,totalCount:i,nameTransformationsFromDatabase:l,hasMore:s})}async#s(t){await this.#e?.deleteEntitiesRelations({op:"OR",conditions:[{field:"source_key",operator:"equal",value:t},{field:"target_key",operator:"equal",value:t}]})}async softDeleteEntitiesInLocalDatabase({filter:t,revision:e,fileHash:a}){await this.#t.softDeleteEntities({filter:t,revision:e,fileHash:a})}async listEntityRevisions(t,e){return await this.#e?.sync(),this.#t.listEntityRevisions(t,e)}async updateEntityScorecardsStatus(t,e){return await this.#e?.sync(),this.#t.updateEntityScorecardsStatus(t,e)}async updateEntityScorecardsStatusIfCalculating(t,e){return await this.#e?.sync(),this.#t.updateEntityScorecardsStatusIfCalculating(t,e)}async getOutdatedEntity(){return await this.#e?.sync(),this.#t.getOneOutdatedEntity()}}export{n as CatalogEntitiesService};
1
+ import{entityFileSchema as d}from"@redocly/config";import{deepMerge as y}from"../../../../utils/object/deep-merge.js";import{promiseMapLimit as c}from"../../../utils/async/promise-map-limit.js";import{logger as r}from"../../../tools/notifiers/logger.js";import{entityRelationDtoSchema as h}from"../schemas/dto-schemas.js";import{CatalogEntitiesLocalRepository as m}from"./repositories/local/catalog-entities-local-repository.js";import{CatalogEntitiesRemoteRepository as R}from"./repositories/remote/catalog-entities-remote-repository.js";import{prepareListResponse as o}from"../../../web-server/utils/prepare-list-response.js";import{ENTITY_RELATION_FROM_DATABASE as l}from"./mappers/field-transformations.js";import{createValidator as u}from"../utils/ajv-validator.js";import{hasOptionsChanged as w}from"../utils/has-options-changed.js";const E=15,f=u(h,{errorPrefix:"Entity relation validation failed:",dataVar:"entity relation"}),p=u(d,{errorPrefix:"Entity file validation failed:",dataVar:"entity"});class s{static#a;static#i;#t;#e;constructor(t,e){this.#t=t,this.#e=e}static async#n(t){const[e,a]=await Promise.all([m.getInstance(t),t.runOnlyLocalDatabase?null:R.getInstance(t)]),i=new s(e,a);a&&(process.env.NODE_ENV==="development"&&r.info("Attaching remote database to local database"),await i.#t.attachDatabase(a.path)),s.#a=i,s.#i=t}static async getInstance(t){return t.runOnlyLocalDatabase===void 0&&(t.runOnlyLocalDatabase=process.env.REDOCLY_LOCAL_DEV==="true"||process.env.CI==="true"),t.removeExisting===void 0&&(t.removeExisting=!1),(!s.#a||w(s.#i,t))&&await s.#n(t),s.#a}async transaction(...t){return this.#t.transactionsManager.transaction(...t)}async getEntities(t){await this.#e?.sync();const{items:e,total:a,hasMore:i}=await this.#t.getEntities(t);return o({data:e,params:t,totalCount:a,hasMore:i})}async getEntityByKey(t){return await this.#e?.sync(),await this.#t.getEntityByKey(t)}async getEntityKeysAndVersionsBySourceFile(t){return await this.#e?.sync(),this.#t.getEntityKeysAndVersionsBySourceFile(t)}async getEntitiesCountByTypes(){return await this.#e?.sync(),this.#t.getEntitiesCountByTypes()}async getCatalogFilters(t){return await this.#e?.sync(),this.#t.getCatalogFilters(t)}async createEntity(t){return this.#e?this.#e.createEntity(t):(r.warn("No remote database found"),null)}async createEntities(t){const e=this.#e;return e?await c(t,E,async a=>e.createEntity(a).then(i=>({status:"ok",resource:i})).catch(i=>({key:a.key,status:"error",error:i}))):(r.warn("No remote database found"),[])}getEntitySources(){return this.#t.getEntitySources()}async createEntityInLocalDatabase(t){return this.#t.createEntity(t)}async createEntitiesInLocalDatabase(t){await this.#t.createEntities(t)}async createEntityRelationInLocalDatabase(t){await this.#t.createEntityRelation(t)}async createEntityRelationsInLocalDatabase(t){await this.#t.createEntityRelations(t)}async updateEntityByKey(t,e){const a=await this.#t.getEntityByKey(t);if(!a)throw new Error(`Entity with key ${t} not found`);const i=y(a,e),n=p(i);return await this.#e?.updateEntity({...n,id:a.id,createdAt:a.createdAt||""})}async deleteEntityByKey(t){const e=await this.#e?.deleteEntity(t);return await this.#s(t),e}async deleteEntitiesInLocalDatabase(t){await this.#t.deleteEntities(t)}async getEntityRelationById(t){return await this.#e?.sync(),await this.#t.getEntityRelationById(t)}async getEntitiesRelations(t={}){await this.#e?.sync();const{items:e,total:a,hasMore:i}=await this.#t.getEntitiesRelations(t);return o({data:e,params:t,totalCount:a,nameTransformationsFromDatabase:l,hasMore:i})}async createEntityRelation(t){return this.#e?.createEntityRelation(t)}async createEntitiesRelations(t){const e=this.#e;return e?await c(t,E,async a=>e.createEntityRelation(a).then(i=>({status:"ok",resource:i})).catch(i=>({key:a.sourceKey,status:"error",error:i}))):(r.warn("No remote database found"),[])}async updateEntityRelation(t,e){const a=await this.#t.getEntityRelationById(t);if(!a)throw new Error(`Entity relation with id ${t} not found`);const i=y(a,e),n=f(i);return this.#e?.createEntityRelation(n)}async deleteEntityRelation(t){let e=await this.#e?.deleteEntityRelation(t);return e||(e=await this.#t.deleteEntityRelation(t)),e}async deleteEntityRelationsInLocalDatabase(t){await this.#t.deleteEntityRelations(t)}async getEntitiesWithRelations(t={},e){await this.#e?.sync();const{items:a,total:i,hasMore:n}=await this.#t.getEntitiesWithRelations(t,e);return o({data:a,params:t,totalCount:i,hasMore:n})}async getEntityWithRelationsByKey(t,e,a){return this.#t.getEntityWithRelationsByKey(t,e,a)}async getRelatedEntities(t,e={}){await this.#e?.sync();const{items:a,total:i,hasMore:n}=await this.#t.getRelatedEntities(t,e);return o({data:a,params:e,totalCount:i,nameTransformationsFromDatabase:l,hasMore:n})}async#s(t){await this.#e?.deleteEntitiesRelations({op:"OR",conditions:[{field:"source_key",operator:"equal",value:t},{field:"target_key",operator:"equal",value:t}]})}async softDeleteEntitiesInLocalDatabase({filter:t,revision:e,fileHash:a}){await this.#t.softDeleteEntities({filter:t,revision:e,fileHash:a})}async listEntityRevisions(t,e){return await this.#e?.sync(),this.#t.listEntityRevisions(t,e)}async updateEntityScorecardsStatus(t,e){return await this.#e?.sync(),this.#t.updateEntityScorecardsStatus(t,e)}async updateEntityScorecardsStatusIfCalculating(t,e){return await this.#e?.sync(),this.#t.updateEntityScorecardsStatusIfCalculating(t,e)}async getOutdatedEntity(){return await this.#e?.sync(),this.#t.getOneOutdatedEntity()}}export{s as CatalogEntitiesService};
@@ -0,0 +1,8 @@
1
+ import type { DatabaseEntityAttributesDto } from '../../../../providers/database/databases/catalog-sqlite/schemas/entities-attributes-table';
2
+ export declare function createEntityAttributesDbRecord({ rbacTeams, entityKey, organizationId, projectId, }: {
3
+ rbacTeams: string[];
4
+ entityKey: string;
5
+ organizationId: string;
6
+ projectId: string;
7
+ }): DatabaseEntityAttributesDto;
8
+ //# sourceMappingURL=create-entity-attributes-db-record.d.ts.map
@@ -0,0 +1 @@
1
+ import{ulid as o}from"ulid";function c({rbacTeams:e,entityKey:r,organizationId:i,projectId:n}){const t=new Date().toISOString();return{id:`cea_${o()}`,organizationId:i,projectId:n,entityKey:r,rbacTeams:JSON.stringify(e),createdAt:t,updatedAt:t}}export{c as createEntityAttributesDbRecord};
@@ -1 +1 @@
1
- import{logger as l}from"../../../../tools/notifiers/logger.js";import{entityDatabaseSchema as r}from"../../schemas/database-schemas.js";import{validateWithResult as t}from"../../utils/ajv-validator.js";const o=a=>"project_id"in a&&"organization_id"in a&&"created_at"in a;function d(a){if(o(a)){const s=t(r,a);if(!s.success)return l.warn(`Invalid database catalog entity for entity ${a.key}, error: ${s.error}`),null;const e=s.data||{};return{id:e.id,type:e.type,key:e.key||"",title:e.title||"",summary:e.summary||null,tags:e.tags?JSON.parse(e.tags):null,metadata:e.metadata?JSON.parse(e.metadata):null,git:e.git?JSON.parse(e.git):null,contact:e.contact?JSON.parse(e.contact):null,links:e.links?JSON.parse(e.links):null,source:e.source||"file",sourceFile:e.source_file||null,version:e.version||null,revision:e.revision??"",hash:e.hash||null,isCurrent:e.is_current,isDefaultVersion:e.is_default_version??!1,createdAt:e.created_at||null,updatedAt:e.updated_at||null,isDeleted:e.is_deleted??!1,object:"catalogEntity"}}return{...a,tags:a.tags?JSON.parse(a.tags):null,metadata:a.metadata?JSON.parse(a.metadata):null,git:a.git?JSON.parse(a.git):null,contact:a.contact?JSON.parse(a.contact):null,links:a.links?JSON.parse(a.links):null,source:a.source||"file",version:a.version||null,revision:a.revision??"",hash:a.hash||null,isCurrent:a.isCurrent,isDefaultVersion:a.isDefaultVersion??!1,isDeleted:a.isDeleted??!1,object:"catalogEntity"}}export{d as createEntityReadModel};
1
+ import{logger as r}from"../../../../tools/notifiers/logger.js";import{entityDatabaseSchema as l}from"../../schemas/database-schemas.js";import{validateWithResult as t}from"../../utils/ajv-validator.js";const o=e=>"project_id"in e&&"organization_id"in e&&"created_at"in e;function d(e){if(o(e)){const s=t(l,e);if(!s.success)return r.warn(`Invalid database catalog entity for entity ${e.key}, error: ${s.error}`),null;const a=s.data||{};return{id:a.id,type:a.type,key:a.key||"",title:a.title||"",summary:a.summary||null,tags:a.tags?JSON.parse(a.tags):null,metadata:a.metadata?JSON.parse(a.metadata):null,git:a.git?JSON.parse(a.git):null,contact:a.contact?JSON.parse(a.contact):null,links:a.links?JSON.parse(a.links):null,source:a.source||"file",sourceFile:a.source_file||null,version:a.version||null,revision:a.revision??"",hash:a.hash||null,isCurrent:a.is_current,isDefaultVersion:a.is_default_version??!1,createdAt:a.created_at||null,updatedAt:a.updated_at||null,isDeleted:a.is_deleted??!1,object:"catalogEntity",rbacTeams:a.rbac_teams?JSON.parse(a.rbac_teams):[]}}return{...e,tags:e.tags?JSON.parse(e.tags):null,metadata:e.metadata?JSON.parse(e.metadata):null,git:e.git?JSON.parse(e.git):null,contact:e.contact?JSON.parse(e.contact):null,links:e.links?JSON.parse(e.links):null,source:e.source||"file",version:e.version||null,revision:e.revision??"",hash:e.hash||null,isCurrent:e.isCurrent,isDefaultVersion:e.isDefaultVersion??!1,isDeleted:e.isDeleted??!1,object:"catalogEntity"}}export{d as createEntityReadModel};
@@ -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};
@@ -5,10 +5,10 @@ import type { ListResult } from './catalog-entities-local-read-repository.js';
5
5
  export declare class CatalogEntitiesBffRepository {
6
6
  #private;
7
7
  constructor(db: DatabaseClient, attachedDatabasePath: string);
8
- getEntitiesWithRelations(paginationParams?: PaginationParams): Promise<ListResult<BffCatalogEntity>>;
8
+ getEntitiesWithRelations(paginationParams?: PaginationParams, rbacTeams?: string[]): Promise<ListResult<BffCatalogEntity>>;
9
9
  getEntityWithRelationsByKey(entityKey: string, filter?: {
10
10
  revision?: string | null;
11
11
  version?: string | null;
12
- }): Promise<BffCatalogEntity | null>;
12
+ }, rbacTeams?: string[]): Promise<BffCatalogEntity | null>;
13
13
  }
14
14
  //# sourceMappingURL=catalog-entities-bff-repository.d.ts.map
@@ -1,38 +1,38 @@
1
- import{and as c,desc as M,eq as s,notExists as $,sql as e}from"drizzle-orm";import{unionAll as C}from"drizzle-orm/sqlite-core";import{logger as Q}from"../../../../../tools/notifiers/logger.js";import{entitiesTable as i}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{applyPagination as D}from"../../../../../providers/database/pagination/index.js";import{applyFilter as j,excludeFieldsFromFilter as H,getAllFilterFieldValues as S}from"../../../../../providers/database/pagination/filter.js";import{createBffEntity as O}from"../../mappers/create-bff-entity.js";import{FIELDS_TO_SELECT_FOR_ENTITY as n,FIELDS_TO_SELECT_FOR_ENTITY_RELATION as R,createEntityFieldsForSelect as A}from"../utils.js";class U{#e;#t;constructor(t,o){this.#e=t,this.#t=o}async getEntitiesWithRelations(t={}){const o=S(t.filter,"owners");if(o.length>0)return this.#c(t,o);const d=S(t.filter,"domains");return d.length>0?this.#l(t,d):this.#a(t)}async#c(t,o){const d=this.#s(),l=this.#n(),m=this.#o(),y=l.as("combined_relations"),u=m.as("combined_target_entities"),h=o.map(r=>e`
1
+ import{and as n,desc as H,eq as s,notExists as k,sql as e,or as B,isNull as z,exists as V,inArray as q}from"drizzle-orm";import{unionAll as p}from"drizzle-orm/sqlite-core";import{logger as j}from"../../../../../tools/notifiers/logger.js";import{entitiesTable as i}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-table.js";import{entitiesRelationsTable as S}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-relations-table.js";import{entitiesAttributesTable as y}from"../../../../../providers/database/databases/catalog-sqlite/schemas/entities-attributes-table.js";import{applyPagination as A}from"../../../../../providers/database/pagination/index.js";import{applyFilter as x,excludeFieldsFromFilter as J,getAllFilterFieldValues as W}from"../../../../../providers/database/pagination/filter.js";import{createBffEntity as F}from"../../mappers/create-bff-entity.js";import{FIELDS_TO_SELECT_FOR_ENTITY as a,FIELDS_TO_SELECT_FOR_ENTITY_RELATION as N,createEntityFieldsForSelect as $}from"../utils.js";class re{#e;#t;constructor(t,o){this.#e=t,this.#t=o}async getEntitiesWithRelations(t={},o){const m=W(t.filter,"owners");if(m.length>0)return this.#l(t,m,o);const l=W(t.filter,"domains");return l.length>0?this.#a(t,l,o):this.#m(t,o)}async#l(t,o,m){const l=this.#n(m),c=this.#o(),h=this.#c(),w=c.as("combined_relations"),g=h.as("combined_target_entities"),u=o.map(r=>e`
2
2
  EXISTS (
3
- SELECT 1 FROM (${l}) cr
3
+ SELECT 1 FROM (${c}) cr
4
4
  WHERE cr.source_key = ${r}
5
5
  AND cr.source_to_target_relation = 'owns'
6
6
  AND cr.target_key = base_entities.key
7
7
  )
8
- `),_=h.length===1?h[0]:e`(${e.join(h,e` OR `)})`,b=S(t.filter,"domains");let w=_;if(b.length>0){const r=b.map(a=>e`
8
+ `),_=u.length===1?u[0]:e`(${e.join(u,e` OR `)})`,R=W(t.filter,"domains");let v=_;if(R.length>0){const r=R.map(d=>e`
9
9
  EXISTS (
10
- SELECT 1 FROM (${l}) cr
11
- JOIN (${m}) d ON d.key = ${a}
10
+ SELECT 1 FROM (${c}) cr
11
+ JOIN (${h}) d ON d.key = ${d}
12
12
  WHERE d.type = 'domain'
13
13
  AND d.is_current = 1
14
- AND cr.source_key = ${a}
14
+ AND cr.source_key = ${d}
15
15
  AND cr.target_key = base_entities.key
16
16
  AND cr.source_to_target_relation = 'hasParts'
17
17
  )
18
- `),f=r.length===1?r[0]:e`(${e.join(r,e` OR `)})`;w=e`(${_} AND ${f})`}const p=H(t.filter,["owners","domains"]),g={...t,filter:p,baseWhereCondition:w},E=this.#e.client.select(n).from(d.as("base_entities")).$dynamic();try{const r=this.#e.client.select(n).from(d.as("base_entities")).$dynamic();D(r,{...g,limit:void 0,skip:void 0,after:void 0,before:void 0});const f=this.#e.client.$count(r),a=t.limit||10;D(E,{...g,limit:a+1});const v=E.as("paged_entities"),W=this.#e.client.with(y,u,v).select({...A("paged_entities"),domains:this.#i("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(v),[F,I]=await Promise.all([W.run(),f]),k=F.rows,L=k.length>a;return{items:k.slice(0,a).map(N=>O(N)).filter(N=>N!==null),hasMore:L,total:I}}catch(r){return Q.error("Error getting entities with relations (owner optimized path):",r),{items:[],hasMore:!1,total:0}}}async#l(t,o){const d=this.#s(),l=this.#n(),m=this.#o(),y=l.as("combined_relations"),u=m.as("combined_target_entities"),h=o.map(r=>e`
18
+ `),f=r.length===1?r[0]:e`(${e.join(r,e` OR `)})`;v=e`(${_} AND ${f})`}const T=J(t.filter,["owners","domains"]),b={...t,filter:T,baseWhereCondition:v},E=this.#e.client.select(a).from(l.as("base_entities")).$dynamic();try{const r=this.#e.client.select(a).from(l.as("base_entities")).$dynamic();A(r,{...b,limit:void 0,skip:void 0,after:void 0,before:void 0});const f=this.#e.client.$count(r),d=t.limit||10;A(E,{...b,limit:d+1});const C=E.as("paged_entities"),I=this.#e.client.with(w,g,C).select({...$("paged_entities"),domains:this.#s("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(C),[L,Q]=await Promise.all([I.run(),f]),O=L.rows,M=O.length>d;return{items:O.slice(0,d).map(D=>F(D)).filter(D=>D!==null),hasMore:M,total:Q}}catch(r){return j.error("Error getting entities with relations (owner optimized path): "+r.message),{items:[],hasMore:!1,total:0}}}async#a(t,o,m){const l=this.#n(m),c=this.#o(),h=this.#c(),w=c.as("combined_relations"),g=h.as("combined_target_entities"),u=o.map(r=>e`
19
19
  EXISTS (
20
- SELECT 1 FROM (${l}) cr
21
- JOIN (${m}) d ON d.key = ${r}
20
+ SELECT 1 FROM (${c}) cr
21
+ JOIN (${h}) d ON d.key = ${r}
22
22
  WHERE d.type = 'domain'
23
23
  AND d.is_current = 1
24
24
  AND cr.source_key = ${r}
25
25
  AND cr.target_key = base_entities.key
26
26
  AND cr.source_to_target_relation = 'hasParts'
27
27
  )
28
- `),_=h.length===1?h[0]:e`(${e.join(h,e` OR `)})`,b=S(t.filter,"owners");let w=_;if(b.length>0){const r=b.map(a=>e`
28
+ `),_=u.length===1?u[0]:e`(${e.join(u,e` OR `)})`,R=W(t.filter,"owners");let v=_;if(R.length>0){const r=R.map(d=>e`
29
29
  EXISTS (
30
- SELECT 1 FROM (${l}) cr
31
- WHERE cr.source_key = ${a}
30
+ SELECT 1 FROM (${c}) cr
31
+ WHERE cr.source_key = ${d}
32
32
  AND cr.source_to_target_relation = 'owns'
33
33
  AND cr.target_key = base_entities.key
34
34
  )
35
- `),f=r.length===1?r[0]:e`(${e.join(r,e` OR `)})`;w=e`(${_} AND ${f})`}const p=H(t.filter,["domains","owners"]),g={...t,filter:p,baseWhereCondition:w},E=this.#e.client.select(n).from(d.as("base_entities")).$dynamic();try{const r=this.#e.client.select(n).from(d.as("base_entities")).$dynamic();D(r,{...g,limit:void 0,skip:void 0,after:void 0,before:void 0});const f=this.#e.client.$count(r),a=t.limit||10;D(E,{...g,limit:a+1});const v=E.as("paged_entities"),W=this.#e.client.with(y,u,v).select({...A("paged_entities"),domains:this.#i("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(v),[F,I]=await Promise.all([W.run(),f]),k=F.rows,L=k.length>a;return{items:k.slice(0,a).map(N=>O(N)).filter(N=>N!==null),hasMore:L,total:I}}catch(r){return Q.error("Error getting entities with relations (domain optimized path):",r),{items:[],hasMore:!1,total:0}}}async#a(t){const o=this.#s(),d=this.#n(),l=this.#o(),m=d.as("combined_relations"),y=l.as("combined_target_entities"),u=this.#e.client.select(n).from(o.as("base_entities")).$dynamic(),{whereCondition:h}=j(u,t.filter);h&&u.where(h);try{const _=this.#e.client.select(n).from(o.as("base_entities")).$dynamic();h&&_.where(h);const b=this.#e.client.$count(_),w=t.limit||10;D(u,{...t,limit:w+1});const p=u.as("paged_entities"),g=this.#e.client.with(m,y,p).select({...A("paged_entities"),domains:this.#i("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(p),[E,r]=await Promise.all([g.run(),b]),f=E.rows,a=f.length>w;return{items:f.slice(0,w).map(v=>O(v)).filter(v=>v!==null),hasMore:a,total:r}}catch(_){return Q.error("Error getting entities with relations (optimized path):",_),{items:[],hasMore:!1,total:0}}}#s(){return this.#t?C(this.#e.client.select(n).from(e`remote.entities`).where(c(s(e.raw("is_current"),1),s(e.raw("is_deleted"),!1))),this.#e.client.select(n).from(i).where(c(s(i.isCurrent,!0),s(i.isDeleted,!1),$(this.#e.client.select({id:n.id}).from(e`remote.entities as remote`).where(c(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select(n).from(i).where(c(s(i.isCurrent,!0),s(i.isDeleted,!1)))}#n(){return this.#t?C(this.#e.client.select(R).from(e`remote.entities_relations`),this.#e.client.select(R).from(T).where($(this.#e.client.select({id:R.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${T.sourceKey}`)))):this.#e.client.select(R).from(T)}#o(){return this.#t?C(this.#e.client.select(n).from(e`remote.entities`).where(c(s(e.raw("is_current"),1),s(e.raw("is_deleted"),!1))),this.#e.client.select(n).from(i).where(c(s(i.isCurrent,!0),s(i.isDeleted,!1),$(this.#e.client.select({id:n.id}).from(e`remote.entities as remote`).where(c(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select(n).from(i).where(c(s(i.isCurrent,!0),s(i.isDeleted,!1)))}async getEntityWithRelationsByKey(t,o){if(!t||t.trim()==="")return null;const d=o?.revision,l=o?.version,m=d?null:await this.#d(t,l||null),y=l??m?.version,u=d||m?.revision||null,_=(this.#t?C(this.#e.client.select(n).from(e`remote.entities`).where(s(i.key,t)),this.#e.client.select(n).from(i).where(c(s(i.key,t),$(this.#e.client.select({id:n.id}).from(e`remote.entities as remote`).where(e`remote.key = ${i.key}`))))):this.#e.client.select(n).from(i).where(s(i.key,t))).as("e"),w=(this.#t?C(this.#e.client.select(R).from(e`remote.entities_relations`),this.#e.client.select(R).from(T).where($(this.#e.client.select({id:R.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${T.sourceKey}`)))):this.#e.client.select(R).from(T)).as("combined_relations"),g=(this.#t?C(this.#e.client.select(n).from(e`remote.entities`),this.#e.client.select(n).from(i).where($(this.#e.client.select({id:n.id}).from(e`remote.entities as remote`).where(e`remote.key = ${i.key}`)))):this.#e.client.select(n).from(i)).as("combined_target_entities"),E=this.#e.client.with(_,w,g).select({...A("e"),domains:this.#i("e").as("domains"),owners:this.#r("e").as("owners")}).from(_).$dynamic();u?E.where(c(s(e.raw("revision"),u),y?s(e.raw("version"),y):void 0)):E.where(s(e.raw("is_current"),1)),E.limit(1);const r=await E.run();if(r.rows.length===0)return null;const f=r.rows[0];return O(f)}async#d(t,o){if(o){const y=await(this.#t?C(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision")}).from(e`remote.entities`).where(c(e`key = ${t}`,e`version = ${o}`)).orderBy(e.raw("revision DESC")),this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(c(s(i.key,t),s(i.version,o),$(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(c(e`remote.key = ${i.key}`,e`remote.version = ${o}`))))).orderBy(M(i.revision))):this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(c(s(i.key,t),s(i.version,o))).orderBy(M(i.revision))).limit(1).run();if(y.rows.length>0){const u=y.rows[0];return{version:u.version||null,revision:u.revision||null}}return null}const l=await(this.#t?C(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision")}).from(e`remote.entities`).where(c(e`key = ${t}`,e`is_current = 1`)),this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(c(s(i.key,t),s(i.isCurrent,!0),$(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(c(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(c(s(i.key,t),s(i.isCurrent,!0)))).limit(1).run();if(l.rows.length>0){const m=l.rows[0];return{version:m.version||null,revision:m.revision||null}}return null}#i(t){return e`
35
+ `),f=r.length===1?r[0]:e`(${e.join(r,e` OR `)})`;v=e`(${_} AND ${f})`}const T=J(t.filter,["domains","owners"]),b={...t,filter:T,baseWhereCondition:v},E=this.#e.client.select(a).from(l.as("base_entities")).$dynamic();try{const r=this.#e.client.select(a).from(l.as("base_entities")).$dynamic();A(r,{...b,limit:void 0,skip:void 0,after:void 0,before:void 0});const f=this.#e.client.$count(r),d=t.limit||10;A(E,{...b,limit:d+1});const C=E.as("paged_entities"),I=this.#e.client.with(w,g,C).select({...$("paged_entities"),domains:this.#s("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(C),[L,Q]=await Promise.all([I.run(),f]),O=L.rows,M=O.length>d;return{items:O.slice(0,d).map(D=>F(D)).filter(D=>D!==null),hasMore:M,total:Q}}catch(r){return j.error("Error getting entities with relations (domain optimized path): "+r.message),{items:[],hasMore:!1,total:0}}}async#m(t,o){const m=this.#n(o),l=this.#o(),c=this.#c(),h=l.as("combined_relations"),w=c.as("combined_target_entities"),g=this.#e.client.select(a).from(m.as("base_entities")).$dynamic(),{whereCondition:u}=x(g,t.filter);u&&g.where(u);try{const _=this.#e.client.select(a).from(m.as("base_entities")).$dynamic();u&&_.where(u);const R=this.#e.client.$count(_),v=t.limit||10;A(g,{...t,limit:v+1});const T=g.as("paged_entities"),b=this.#e.client.with(h,w,T).select({...$("paged_entities"),domains:this.#s("paged_entities").as("domains"),owners:this.#r("paged_entities").as("owners")}).from(T),[E,r]=await Promise.all([b.run(),R]),f=E.rows,d=f.length>v;return{items:f.slice(0,v).map(C=>F(C)).filter(C=>C!==null),hasMore:d,total:r}}catch(_){return j.error("Error getting entities with relations (optimized path): "+_.message),{items:[],hasMore:!1,total:0}}}#n(t){return this.#t?p(this.#e.client.select($("entities")).from(e`remote.entities`).leftJoin(e`remote.entities_attributes`,s(i.key,y.entityKey)).where(n(s(e.raw("is_current"),1),s(e.raw("is_deleted"),!1),this.#i(t))),this.#e.client.select($("entities")).from(i).leftJoin(y,s(i.key,y.entityKey)).where(n(s(i.isCurrent,!0),s(i.isDeleted,!1),this.#i(t),k(this.#e.client.select({id:a.id}).from(e`remote.entities as remote`).where(n(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select($("entities")).from(i).leftJoin(y,s(i.key,y.entityKey)).where(n(s(i.isCurrent,!0),s(i.isDeleted,!1),this.#i(t)))}#o(){return this.#t?p(this.#e.client.select(N).from(e`remote.entities_relations`),this.#e.client.select(N).from(S).where(k(this.#e.client.select({id:N.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${S.sourceKey}`)))):this.#e.client.select(N).from(S)}#c(){return this.#t?p(this.#e.client.select(a).from(e`remote.entities`).where(n(s(e.raw("is_current"),1),s(e.raw("is_deleted"),!1))),this.#e.client.select(a).from(i).where(n(s(i.isCurrent,!0),s(i.isDeleted,!1),k(this.#e.client.select({id:a.id}).from(e`remote.entities as remote`).where(n(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select(a).from(i).where(n(s(i.isCurrent,!0),s(i.isDeleted,!1)))}async getEntityWithRelationsByKey(t,o,m){if(!t||t.trim()==="")return null;const l=o?.revision,c=o?.version,h=l?null:await this.#d(t,c||null),w=c??h?.version,g=l||h?.revision||null,_=(this.#t?p(this.#e.client.select($("entities")).from(e`remote.entities`).leftJoin(e`remote.entities_attributes`,s(i.key,y.entityKey)).where(n(s(i.key,t),this.#i(m))),this.#e.client.select($("entities")).from(i).leftJoin(y,s(i.key,y.entityKey)).where(n(s(i.key,t),this.#i(m),k(this.#e.client.select({id:a.id}).from(e`remote.entities as remote`).where(n(e`remote.key = ${i.key}`,this.#i(m))))))):this.#e.client.select($("entities")).from(i).leftJoin(y,s(i.key,y.entityKey)).where(n(s(i.key,t),this.#i(m)))).as("e"),v=(this.#t?p(this.#e.client.select(N).from(e`remote.entities_relations`),this.#e.client.select(N).from(S).where(k(this.#e.client.select({id:N.id}).from(e`remote.entities_relations as remote`).where(e`remote.source_key = ${S.sourceKey}`)))):this.#e.client.select(N).from(S)).as("combined_relations"),b=(this.#t?p(this.#e.client.select(a).from(e`remote.entities`),this.#e.client.select(a).from(i).where(k(this.#e.client.select({id:a.id}).from(e`remote.entities as remote`).where(e`remote.key = ${i.key}`)))):this.#e.client.select(a).from(i)).as("combined_target_entities"),E=this.#e.client.with(_,v,b).select({...$("e"),domains:this.#s("e").as("domains"),owners:this.#r("e").as("owners")}).from(_).$dynamic();g?E.where(n(s(e.raw("revision"),g),w?s(e.raw("version"),w):void 0)):E.where(s(e.raw("is_current"),1)),E.limit(1);const r=await E.run();if(r.rows.length===0)return null;const f=r.rows[0];return F(f)}async#d(t,o){if(o){const h=await(this.#t?p(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision")}).from(e`remote.entities`).where(n(e`key = ${t}`,e`version = ${o}`)).orderBy(e.raw("revision DESC")),this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(n(s(i.key,t),s(i.version,o),k(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(n(e`remote.key = ${i.key}`,e`remote.version = ${o}`))))).orderBy(H(i.revision))):this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(n(s(i.key,t),s(i.version,o))).orderBy(H(i.revision))).limit(1).run();if(h.rows.length>0){const w=h.rows[0];return{version:w.version||null,revision:w.revision||null}}return null}const l=await(this.#t?p(this.#e.client.select({version:e.raw("version"),revision:e.raw("revision")}).from(e`remote.entities`).where(n(e`key = ${t}`,e`is_current = 1`)),this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(n(s(i.key,t),s(i.isCurrent,!0),k(this.#e.client.select({id:e.raw("id")}).from(e`remote.entities as remote`).where(n(e`remote.key = ${i.key}`,e`remote.is_current = 1`)))))):this.#e.client.select({version:i.version,revision:i.revision}).from(i).where(n(s(i.key,t),s(i.isCurrent,!0)))).limit(1).run();if(l.rows.length>0){const c=l.rows[0];return{version:c.version||null,revision:c.revision||null}}return null}#s(t){return e`
36
36
  COALESCE(
37
37
  (
38
38
  SELECT json_group_array(
@@ -109,4 +109,4 @@ import{and as c,desc as M,eq as s,notExists as $,sql as e}from"drizzle-orm";impo
109
109
  ),
110
110
  json_array()
111
111
  )
112
- `}}export{U as CatalogEntitiesBffRepository};
112
+ `}#i(t){if(!(!t||t.length===0))return B(z(y.rbacTeams),e`json_array_length(${y.rbacTeams}) = 0`,V(this.#e.client.select({id:e.raw("1")}).from(e`json_each(${y.rbacTeams}) as entity_teams`).where(q(e`entity_teams.value`,t))))}}export{re as CatalogEntitiesBffRepository};
@@ -31,11 +31,11 @@ export declare class CatalogEntitiesLocalReadRepository {
31
31
  getOneOutdatedEntity(): Promise<EntityReadModelSchema | null>;
32
32
  getEntitiesRelations(paginationParams?: PaginationParams): Promise<ListResult<EntityRelationReadModelSchema>>;
33
33
  getEntityRelationById(id: string): Promise<EntityRelationReadModelSchema | null>;
34
- getEntitiesWithRelations(paginationParams?: PaginationParams): Promise<ListResult<BffCatalogEntity>>;
34
+ getEntitiesWithRelations(paginationParams?: PaginationParams, rbacTeams?: string[]): Promise<ListResult<BffCatalogEntity>>;
35
35
  getEntityWithRelationsByKey(entityKey: string, filter?: {
36
36
  revision?: string | null;
37
37
  version?: string | null;
38
- }): Promise<BffCatalogEntity | null>;
38
+ }, rbacTeams?: string[]): Promise<BffCatalogEntity | null>;
39
39
  getRelationsForEntity(key: string, version?: string | null, revision?: string | null): Promise<{
40
40
  targetKey: string;
41
41
  targetRevision: string;
@@ -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={},s){return this.#s.getEntitiesWithRelations(i,s)}async getEntityWithRelationsByKey(i,s,r){return this.#s.getEntityWithRelationsByKey(i,s,r)}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`
@@ -49,11 +49,11 @@ export declare class CatalogEntitiesLocalRepository extends BaseRepository {
49
49
  sourceKey: string;
50
50
  targetKey: string;
51
51
  } | null>;
52
- getEntitiesWithRelations(paginationParams?: PaginationParams): Promise<import("./catalog-entities-local-read-repository.js").ListResult<import("@redocly/theme").BffCatalogEntity>>;
52
+ getEntitiesWithRelations(paginationParams?: PaginationParams, rbacTeams?: string[]): Promise<import("./catalog-entities-local-read-repository.js").ListResult<import("@redocly/theme").BffCatalogEntity>>;
53
53
  getEntityWithRelationsByKey(entityKey: string, filter?: {
54
54
  revision?: string | null;
55
55
  version?: string | null;
56
- }): Promise<import("@redocly/theme").BffCatalogEntity | null>;
56
+ }, rbacTeams?: string[]): Promise<import("@redocly/theme").BffCatalogEntity | null>;
57
57
  getRelatedEntities(entityKey: string, paginationParams?: PaginationParams): Promise<import("./catalog-entities-local-read-repository.js").ListResult<import("@redocly/theme").BffCatalogRelatedEntity>>;
58
58
  createEntity(createEntityParams: CreateEntityParams): Promise<CreateEntityResult>;
59
59
  createEntities(createEntitiesParams: CreateEntityParams[]): Promise<void>;
@@ -1 +1 @@
1
- import{promiseMapLimit as o}from"../../../../../utils/async/promise-map-limit.js";import{logger as R}from"../../../../../tools/notifiers/logger.js";import{DatabaseConnectionFactory as f}from"../../../../../providers/database/database-connection-factory.js";import{BaseRepository as p}from"../../../../../providers/database/base-repository.js";import{CatalogEntitiesLocalReadRepository as m}from"./catalog-entities-local-read-repository.js";import{CatalogEntitiesLocalWriteRepository as w}from"./catalog-entities-local-write-repository.js";import{createEntityRelationDbRecordFromDto as E}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{hasOptionsChanged as C}from"../../../utils/has-options-changed.js";const l=50;class s extends p{static#i;static#n;#t;#e;#s={};constructor(t){super(t),this.#t=new m(this.databaseClient),this.#e=new w(this.databaseClient,this.organizationId,this.projectId)}get transactionsManager(){return this.databaseClient.transactionsManager}getEntitySources(){return this.#s}static async getInstance(t){const e=C(s.#n,t);if(!s.#i||e){const n=await f.create("catalog-local",t);if(!n)throw new Error("Failed to create db connection for catalog entities local repository");s.#i=new s(n),s.#n=t}return s.#i}async attachDatabase(t){await this.#t.attachDatabase(t)}getEntities(t={}){return this.#t.getEntities(t)}getEntityByKey(t){return this.#t.getEntityByKey(t)}getEntityKeysAndVersionsBySourceFile(t){return this.#t.getEntityKeysAndVersionsBySourceFile(t)}getEntitiesCountByTypes(){return this.#t.getEntitiesCountByTypes()}getEntitiesRelations(t={}){return this.#t.getEntitiesRelations(t)}getEntityRelationById(t){return this.#t.getEntityRelationById(t)}getEntitiesWithRelations(t={}){return this.#t.getEntitiesWithRelations(t)}getEntityWithRelationsByKey(t,e){return this.#t.getEntityWithRelationsByKey(t,e)}getRelatedEntities(t,e={}){return this.#t.getRelatedEntities(t,e)}createEntity(t){return t.isRootEntity&&(this.#s[t.sourceFile]={key:t.entity.key,version:t.entity.version??void 0}),this.#e.createEntity(t)}async createEntities(t){await o(t,l,async e=>this.createEntity(e))}createEntityRelation(t){const e=E(t,this.organizationId,this.projectId);return this.#e.upsertEntityRelation(e)}async createEntityRelations(t){await o(t,l,async e=>this.createEntityRelation(e))}deleteEntity(t){return this.#e.deleteEntity(t)}async softDeleteEntities({filter:t,revision:e,fileHash:n}){const c=await this.getEntities({filter:t}),i=await this.#e.softDeleteEntities(c.items,e,n);await this.softDeleteEntitiesRelations(i,e)}async softDeleteEntitiesRelations(t,e){try{const n=t.filter(i=>i.result==="created");if(n.length===0)return!0;const c=await o(n,l,async i=>(await this.#t.getRelationsForEntity(i.entityKey,i.entityVersion,e)).map(r=>{if(!r)return null;const y=r.direction,a=r.sourceToTargetRelation,u=r.targetKey,d=y==="outgoing"?i.entityKey:u,h=y==="outgoing"?u:i.entityKey,g=y==="outgoing"?a:a.startsWith("reverse:")?a.slice(8):a;return!g||!d||!h?null:E({type:g,sourceKey:d,targetKey:h,sourceVersion:i.entityVersion,targetVersion:i.entityVersion,sourceRevision:e,targetRevision:e,isDeleted:!0},this.organizationId,this.projectId)}).filter(r=>r!==null));return await o(c.flat(),l,async i=>this.#e.upsertEntityRelation(i)),!0}catch(n){return R.error("Error soft deleting entity relations",n),!1}}deleteEntities(t){return this.#e.deleteEntities(t)}deleteEntityRelation(t){return this.#e.deleteEntityRelation(t)}deleteEntityRelations(t){return this.#e.deleteEntityRelations(t)}getCatalogFilters(t){return this.#t.getCatalogFilters(t)}listEntityRevisions(t,e){return this.#t.listEntityRevisions(t,e)}updateEntityScorecardsStatus(t,e){return this.#e.updateEntityScorecardsStatus(t,e)}updateEntityScorecardsStatusIfCalculating(t,e){return this.#e.updateEntityScorecardsStatusIfCalculating(t,e)}getOneOutdatedEntity(){return this.#t.getOneOutdatedEntity()}}export{s as CatalogEntitiesLocalRepository};
1
+ import{promiseMapLimit as o}from"../../../../../utils/async/promise-map-limit.js";import{logger as R}from"../../../../../tools/notifiers/logger.js";import{DatabaseConnectionFactory as f}from"../../../../../providers/database/database-connection-factory.js";import{BaseRepository as p}from"../../../../../providers/database/base-repository.js";import{CatalogEntitiesLocalReadRepository as m}from"./catalog-entities-local-read-repository.js";import{CatalogEntitiesLocalWriteRepository as w}from"./catalog-entities-local-write-repository.js";import{createEntityRelationDbRecordFromDto as E}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{hasOptionsChanged as C}from"../../../utils/has-options-changed.js";const l=50;class s extends p{static#i;static#n;#t;#e;#s={};constructor(t){super(t),this.#t=new m(this.databaseClient),this.#e=new w(this.databaseClient,this.organizationId,this.projectId)}get transactionsManager(){return this.databaseClient.transactionsManager}getEntitySources(){return this.#s}static async getInstance(t){const e=C(s.#n,t);if(!s.#i||e){const n=await f.create("catalog-local",t);if(!n)throw new Error("Failed to create db connection for catalog entities local repository");s.#i=new s(n),s.#n=t}return s.#i}async attachDatabase(t){await this.#t.attachDatabase(t)}getEntities(t={}){return this.#t.getEntities(t)}getEntityByKey(t){return this.#t.getEntityByKey(t)}getEntityKeysAndVersionsBySourceFile(t){return this.#t.getEntityKeysAndVersionsBySourceFile(t)}getEntitiesCountByTypes(){return this.#t.getEntitiesCountByTypes()}getEntitiesRelations(t={}){return this.#t.getEntitiesRelations(t)}getEntityRelationById(t){return this.#t.getEntityRelationById(t)}getEntitiesWithRelations(t={},e){return this.#t.getEntitiesWithRelations(t,e)}getEntityWithRelationsByKey(t,e,n){return this.#t.getEntityWithRelationsByKey(t,e,n)}getRelatedEntities(t,e={}){return this.#t.getRelatedEntities(t,e)}createEntity(t){return t.isRootEntity&&(this.#s[t.sourceFile]={key:t.entity.key,version:t.entity.version??void 0}),this.#e.createEntity(t)}async createEntities(t){await o(t,l,async e=>this.createEntity(e))}createEntityRelation(t){const e=E(t,this.organizationId,this.projectId);return this.#e.upsertEntityRelation(e)}async createEntityRelations(t){await o(t,l,async e=>this.createEntityRelation(e))}deleteEntity(t){return this.#e.deleteEntity(t)}async softDeleteEntities({filter:t,revision:e,fileHash:n}){const c=await this.getEntities({filter:t}),i=await this.#e.softDeleteEntities(c.items,e,n);await this.softDeleteEntitiesRelations(i,e)}async softDeleteEntitiesRelations(t,e){try{const n=t.filter(i=>i.result==="created");if(n.length===0)return!0;const c=await o(n,l,async i=>(await this.#t.getRelationsForEntity(i.entityKey,i.entityVersion,e)).map(r=>{if(!r)return null;const y=r.direction,a=r.sourceToTargetRelation,u=r.targetKey,d=y==="outgoing"?i.entityKey:u,h=y==="outgoing"?u:i.entityKey,g=y==="outgoing"?a:a.startsWith("reverse:")?a.slice(8):a;return!g||!d||!h?null:E({type:g,sourceKey:d,targetKey:h,sourceVersion:i.entityVersion,targetVersion:i.entityVersion,sourceRevision:e,targetRevision:e,isDeleted:!0},this.organizationId,this.projectId)}).filter(r=>r!==null));return await o(c.flat(),l,async i=>this.#e.upsertEntityRelation(i)),!0}catch(n){return R.error("Error soft deleting entity relations",n),!1}}deleteEntities(t){return this.#e.deleteEntities(t)}deleteEntityRelation(t){return this.#e.deleteEntityRelation(t)}deleteEntityRelations(t){return this.#e.deleteEntityRelations(t)}getCatalogFilters(t){return this.#t.getCatalogFilters(t)}listEntityRevisions(t,e){return this.#t.listEntityRevisions(t,e)}updateEntityScorecardsStatus(t,e){return this.#e.updateEntityScorecardsStatus(t,e)}updateEntityScorecardsStatusIfCalculating(t,e){return this.#e.updateEntityScorecardsStatusIfCalculating(t,e)}getOneOutdatedEntity(){return this.#t.getOneOutdatedEntity()}}export{s as CatalogEntitiesLocalRepository};
@@ -11,6 +11,7 @@ export type CreateEntityParams = {
11
11
  isRootEntity?: boolean;
12
12
  revision?: string;
13
13
  isDeleted?: boolean;
14
+ rbacTeams?: string[];
14
15
  };
15
16
  export type CreateEntityResult = {
16
17
  result: 'created';
@@ -24,7 +25,7 @@ export type CreateEntityResult = {
24
25
  export declare class CatalogEntitiesLocalWriteRepository {
25
26
  #private;
26
27
  constructor(db: DatabaseClient, organizationId: string, projectId: string);
27
- createEntity({ entity, fileHash, sourceFile, revision, isRootEntity, isDeleted, }: CreateEntityParams): Promise<CreateEntityResult>;
28
+ createEntity({ entity, fileHash, sourceFile, revision, isRootEntity, isDeleted, rbacTeams, }: CreateEntityParams): Promise<CreateEntityResult>;
28
29
  deleteEntity(entityKey: string): Promise<string | null>;
29
30
  /**
30
31
  * Deletes entities based on a filter.