@redocly/revel-reef 0.128.0-next.5 → 0.128.0-next.7

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 (90) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +54 -0
  3. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  4. package/dist/constants/common.d.ts +2 -0
  5. package/dist/constants/common.js +1 -1
  6. package/dist/server/constants/plugins/catalog-entities.d.ts +1 -0
  7. package/dist/server/constants/plugins/catalog-entities.js +1 -1
  8. package/dist/server/esbuild/esbuild.js +2 -2
  9. package/dist/server/node-bundle-entry.js +1 -1
  10. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +8 -0
  11. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.js +1 -1
  12. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.js +1 -1
  13. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.d.ts +5 -0
  14. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-read-repository.js +6 -6
  15. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +8 -0
  16. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.js +1 -1
  17. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.d.ts +3 -0
  18. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  19. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.d.ts +1 -0
  20. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  21. package/dist/server/plugins/catalog-entities/database/repositories/utils.d.ts +2 -0
  22. package/dist/server/plugins/catalog-entities/database/repositories/utils.js +1 -1
  23. package/dist/server/plugins/catalog-entities/entities/types.d.ts +1 -0
  24. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.d.ts +2 -1
  25. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/arazzo-entities-extractor.js +1 -1
  26. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/asyncapi-entities-extractor.d.ts +2 -1
  27. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +1 -11
  28. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  29. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.d.ts +2 -1
  30. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/graphql-entities-extractor.js +1 -1
  31. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/openapi-entities-extractor.d.ts +2 -1
  32. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
  33. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  34. package/dist/server/plugins/catalog-entities/types/extractors.d.ts +16 -0
  35. package/dist/server/plugins/catalog-entities/types/extractors.js +0 -0
  36. package/dist/server/plugins/catalog-entities/utils/catalog-data-collector.d.ts +20 -0
  37. package/dist/server/plugins/catalog-entities/utils/catalog-data-collector.js +1 -0
  38. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.d.ts +2 -0
  39. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.js +1 -0
  40. package/dist/server/plugins/scorecards/workers/scorecards.d.ts +14 -0
  41. package/dist/server/plugins/scorecards/workers/scorecards.js +1 -0
  42. package/dist/server/providers/database/databases/catalog-sqlite/migrations/0002_add-scorecards-status.sql +1 -0
  43. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/0002_snapshot.json +385 -0
  44. package/dist/server/providers/database/databases/catalog-sqlite/migrations/meta/_journal.json +7 -0
  45. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-table.d.ts +19 -0
  46. package/dist/server/providers/database/databases/catalog-sqlite/schemas/entities-table.js +1 -1
  47. package/dist/server/providers/database/databases/main-sqlite/migrations/0003_file-path-added.sql +1 -0
  48. package/dist/server/providers/database/databases/main-sqlite/migrations/0004_add-scorecards-tables.sql +10 -0
  49. package/dist/server/providers/database/databases/main-sqlite/migrations/meta/0004_snapshot.json +221 -0
  50. package/dist/server/providers/database/databases/main-sqlite/migrations/meta/_journal.json +7 -0
  51. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.d.ts +162 -0
  52. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.js +1 -0
  53. package/dist/server/providers/database/databases/sqld-sqlite/drizzle.config.js +1 -1
  54. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0003_add-scorecards-tables.sql +61 -0
  55. package/dist/server/providers/database/databases/sqld-sqlite/migrations/0004_add-scorecards-status.sql +1 -0
  56. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0003_snapshot.json +796 -0
  57. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/0004_snapshot.json +803 -0
  58. package/dist/server/providers/database/databases/sqld-sqlite/migrations/meta/_journal.json +14 -0
  59. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-evaluations-table.d.ts +124 -0
  60. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-evaluations-table.js +1 -0
  61. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-level-states-table.d.ts +48 -0
  62. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-level-states-table.js +1 -0
  63. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-levels-table.d.ts +186 -0
  64. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-levels-table.js +1 -0
  65. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-states-table.d.ts +177 -0
  66. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-result-states-table.js +1 -0
  67. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-results-table.d.ts +179 -0
  68. package/dist/server/providers/database/databases/sqld-sqlite/schemas/scorecard-results-table.js +1 -0
  69. package/dist/server/providers/database/pagination/types.d.ts +9 -0
  70. package/dist/server/utils/is-catalog-entities-enabled.d.ts +2 -0
  71. package/dist/server/utils/is-catalog-entities-enabled.js +1 -0
  72. package/dist/server/utils/is-scorecards-enabled.d.ts +3 -0
  73. package/dist/server/utils/is-scorecards-enabled.js +1 -0
  74. package/dist/server/web-server/dev-server.js +1 -1
  75. package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
  76. package/dist/server/web-server/routes/catalog/bff-catalog-revisions.d.ts +4 -0
  77. package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -0
  78. package/dist/server/web-server/routes/catalog/bff-catalog.d.ts +0 -1
  79. package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
  80. package/dist/server/web-server/routes/catalog/catalog-relations.js +1 -1
  81. package/dist/server/web-server/routes/catalog/catalog.js +1 -1
  82. package/dist/server/web-server/routes/index.js +1 -1
  83. package/dist/server/workers/scorecards-worker-pool.d.ts +4 -0
  84. package/dist/server/workers/scorecards-worker-pool.js +1 -0
  85. package/dist/server/workers/scorecards-worker.d.ts +2 -0
  86. package/dist/server/workers/scorecards-worker.js +1 -0
  87. package/dist/server/workers/types.d.ts +6 -0
  88. package/dist/utils/object/allowlist-object.d.ts +16 -0
  89. package/dist/utils/object/allowlist-object.js +1 -0
  90. package/package.json +7 -7
@@ -1 +1 @@
1
- import{sql as a}from"drizzle-orm";const i=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),key:a.raw(t+"key"),type:a.raw(t+"type"),title:a.raw(t+"title"),summary:a.raw(t+"summary"),tags:a.raw(t+"tags"),metadata:a.raw(t+"metadata"),git:a.raw(t+"git"),contact:a.raw(t+"contact"),links:a.raw(t+"links"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at"),source:a.raw(t+"source"),sourceFile:a.raw(t+"source_file"),fileHash:a.raw(t+"file_hash"),version:a.raw(t+"version"),revision:a.raw(t+"revision"),hash:a.raw(t+"hash"),isCurrent:a.raw(t+"is_current")}},s=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),sourceKey:a.raw(t+"source_key"),sourceId:a.raw(t+"source_id"),sourceVersion:a.raw(t+"source_version"),sourceRevision:a.raw(t+"source_revision"),sourceToTargetRelation:a.raw(t+"source_to_target_relation"),targetKey:a.raw(t+"target_key"),targetId:a.raw(t+"target_id"),targetVersion:a.raw(t+"target_version"),targetRevision:a.raw(t+"target_revision"),targetToSourceRelation:a.raw(t+"target_to_source_relation"),fileHash:a.raw(t+"file_hash"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at")}},n=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id"),organizationId:a.raw(r+"organization_id"),projectId:a.raw(r+"project_id"),key:a.raw(r+"key"),type:a.raw(r+"type"),title:a.raw(r+"title"),summary:a.raw(r+"summary"),tags:a.raw(r+"tags"),metadata:a.raw(r+"metadata"),git:a.raw(r+"git"),contact:a.raw(r+"contact"),links:a.raw(r+"links"),createdAt:a.raw(r+"created_at"),updatedAt:a.raw(r+"updated_at"),source:a.raw(r+"source"),sourceFile:a.raw(r+"source_file"),fileHash:a.raw(r+"file_hash"),version:a.raw(r+"version"),revision:a.raw(r+"revision"),hash:a.raw(r+"hash"),isCurrent:a.raw(r+"is_current")}},w=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id").as("id"),organizationId:a.raw(r+"organization_id").as("organization_id"),projectId:a.raw(r+"project_id").as("project_id"),key:a.raw(r+"key").as("key"),type:a.raw(r+"type").as("type"),title:a.raw(r+"title").as("title"),summary:a.raw(r+"summary").as("summary"),tags:a.raw(r+"tags").as("tags"),metadata:a.raw(r+"metadata").as("metadata"),git:a.raw(r+"git").as("git"),contact:a.raw(r+"contact").as("contact"),links:a.raw(r+"links").as("links"),createdAt:a.raw(r+"created_at").as("created_at"),updatedAt:a.raw(r+"updated_at").as("updated_at"),source:a.raw(r+"source").as("source"),sourceFile:a.raw(r+"source_file").as("source_file"),fileHash:a.raw(r+"file_hash").as("file_hash"),version:a.raw(r+"version").as("version"),revision:a.raw(r+"revision").as("revision"),hash:a.raw(r+"hash").as("hash"),isCurrent:a.raw(r+"is_current").as("is_current")}},c=i(),d=s();export{c as FIELDS_TO_SELECT_FOR_ENTITY,d as FIELDS_TO_SELECT_FOR_ENTITY_RELATION,i as createEntityFieldsForSelect,s as createEntityRelationFieldsForSelect,n as createQualifiedEntityFieldsForSelect,w as createQualifiedEntityFieldsForSelectWithAliases};
1
+ import{sql as a}from"drizzle-orm";const i=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),key:a.raw(t+"key"),type:a.raw(t+"type"),title:a.raw(t+"title"),summary:a.raw(t+"summary"),tags:a.raw(t+"tags"),metadata:a.raw(t+"metadata"),git:a.raw(t+"git"),contact:a.raw(t+"contact"),links:a.raw(t+"links"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at"),source:a.raw(t+"source"),sourceFile:a.raw(t+"source_file"),fileHash:a.raw(t+"file_hash"),version:a.raw(t+"version"),revision:a.raw(t+"revision"),hash:a.raw(t+"hash"),isCurrent:a.raw(t+"is_current"),scorecardsStatus:a.raw(t+"scorecards_status")}},s=(e="",r)=>{const t=e?`${e}.`:"";return{id:r?a.raw(t+"id").as(r):a.raw(t+"id"),organizationId:a.raw(t+"organization_id"),projectId:a.raw(t+"project_id"),sourceKey:a.raw(t+"source_key"),sourceId:a.raw(t+"source_id"),sourceVersion:a.raw(t+"source_version"),sourceRevision:a.raw(t+"source_revision"),sourceToTargetRelation:a.raw(t+"source_to_target_relation"),targetKey:a.raw(t+"target_key"),targetId:a.raw(t+"target_id"),targetVersion:a.raw(t+"target_version"),targetRevision:a.raw(t+"target_revision"),targetToSourceRelation:a.raw(t+"target_to_source_relation"),fileHash:a.raw(t+"file_hash"),createdAt:a.raw(t+"created_at"),updatedAt:a.raw(t+"updated_at")}},n=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id"),organizationId:a.raw(r+"organization_id"),projectId:a.raw(r+"project_id"),key:a.raw(r+"key"),type:a.raw(r+"type"),title:a.raw(r+"title"),summary:a.raw(r+"summary"),tags:a.raw(r+"tags"),metadata:a.raw(r+"metadata"),git:a.raw(r+"git"),contact:a.raw(r+"contact"),links:a.raw(r+"links"),createdAt:a.raw(r+"created_at"),updatedAt:a.raw(r+"updated_at"),source:a.raw(r+"source"),sourceFile:a.raw(r+"source_file"),fileHash:a.raw(r+"file_hash"),version:a.raw(r+"version"),revision:a.raw(r+"revision"),hash:a.raw(r+"hash"),isCurrent:a.raw(r+"is_current")}},c=(e="")=>{const r=e?`${e}.`:"";return{id:a.raw(r+"entity_id").as("id"),organizationId:a.raw(r+"organization_id").as("organization_id"),projectId:a.raw(r+"project_id").as("project_id"),key:a.raw(r+"key").as("key"),type:a.raw(r+"type").as("type"),title:a.raw(r+"title").as("title"),summary:a.raw(r+"summary").as("summary"),tags:a.raw(r+"tags").as("tags"),metadata:a.raw(r+"metadata").as("metadata"),git:a.raw(r+"git").as("git"),contact:a.raw(r+"contact").as("contact"),links:a.raw(r+"links").as("links"),createdAt:a.raw(r+"created_at").as("created_at"),updatedAt:a.raw(r+"updated_at").as("updated_at"),source:a.raw(r+"source").as("source"),sourceFile:a.raw(r+"source_file").as("source_file"),fileHash:a.raw(r+"file_hash").as("file_hash"),version:a.raw(r+"version").as("version"),revision:a.raw(r+"revision").as("revision"),hash:a.raw(r+"hash").as("hash"),isCurrent:a.raw(r+"is_current").as("is_current")}},w=i(),d=s();export{w as FIELDS_TO_SELECT_FOR_ENTITY,d as FIELDS_TO_SELECT_FOR_ENTITY_RELATION,i as createEntityFieldsForSelect,s as createEntityRelationFieldsForSelect,n as createQualifiedEntityFieldsForSelect,c as createQualifiedEntityFieldsForSelectWithAliases};
@@ -2,4 +2,5 @@ export type EntitiesFileSchema = {
2
2
  path: string;
3
3
  entities: unknown[];
4
4
  };
5
+ export type ScorecardsStatus = 'UP_TO_DATE' | 'CANCELLED' | 'OUTDATED' | 'CALCULATING';
5
6
  //# sourceMappingURL=types.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import type { BundledDefinition } from '../../../../arazzo-docs/arazzo-doc-loader.js';
2
2
  import type { EntityFileSchema } from '@redocly/config';
3
- import { BaseApiEntitiesExtractor, type BaseApiEntitiesExtractorParams } from './base.js';
3
+ import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
4
+ import { BaseApiEntitiesExtractor } from './base.js';
4
5
  type Params = BaseApiEntitiesExtractorParams;
5
6
  export declare class ArazzoEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
6
7
  #private;
@@ -1 +1 @@
1
- import h from"node:path";import{removeLeadingSlash as u}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as y}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as d}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as g}from"./base.js";import{resolveEntityVersion as w}from"../../../utils/resolve-entity-version.js";const m=15;class A extends g{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t){const o=u(t.realRelativePath),a=t.document.info.title,c=o.replace(/\.[^.]+$/,""),e=p(c.replace(/[\\/]/g,"-")),r=t.document["x-redocly-catalog-key"],n=typeof r=="string"&&r.trim()?p(r.trim()):e,l=t.document.info.version,s=w(l,t.realRelativePath);if(!s.success)throw new Error(`Arazzo "${a}" in file "${t.realRelativePath}" has conflicting versions: spec version "${s.fileVersion}" differs from folder version "${s.folderVersion}". Entity will not be created.`);return{type:this.type,key:n,title:a,summary:t.document.info.description?d(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:o},version:s.version}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t){const o=new Set;if(!this.#t(t))return this.context.logger.warn(`Skipping Arazzo description without source descriptions: ${t.realRelativePath}`),o;const a=this.mapApiDescriptionToEntity(t);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),o.add(a.key),await this.#e(t,a.key,a.version,o);const c=t.document.sourceDescriptions||[];return await y(c,m,async e=>{if(!(e.type!=="openapi"||!e.url))try{const r=this.resolveSourceDescriptionUrl(e.url,t.realRelativePath);if(!r){!e.url.startsWith("http://")&&!e.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${e.url}`);return}const n=await this.context.cache.load(r,"load-oas");if(!(n.data&&Array.isArray(n.data)&&n.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${r}`);return}const s=n.data[0],i=p(u(s.realRelativePath).replace(/\.[^.]+$/,"").replace(/[\\/]/g,"-"));await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a.key,type:"relatesTo",targetKey:i,fileHash:t.hash}),await this.#r(t,e.name,s,a.key,i,a.version)}catch(r){this.context.logger.warn(`Failed to create relation to OpenAPI source "${e.url}": ${r instanceof Error?r.message:"Unknown error"}`)}}),o}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,c)=>{try{const e=t.document.components?.inputs,r=e?Object.entries(e):[],n=[];for(const[l,s]of r)n.push(async()=>{const i=await this.#a({schemaName:l,schema:s,description:t,parentKey:o,parentVersion:a});c.add(i),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:a,targetVersion:a})});if(n.length===0)return;await y(n,m,l=>l())}catch(e){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${e instanceof Error?e.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:c,parentVersion:e})=>{const r={type:"data-schema",key:`${c}-${p(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash}),r.key};#r=async(t,o,a,c,e,r)=>{const n=t.document.workflows||[];if(n.length===0)return;const l=new Set;for(const s of n)for(const i of s.steps||[]){if(!i.operationId)continue;const f=i.operationId.startsWith(`${o}.`)?i.operationId.substring(`${o}.`.length):i.operationId;f&&l.add(f)}l.size!==0&&await y(Array.from(l),m,async s=>{try{const i=`${e}-${p(s)}`;await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:c,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:r,targetVersion:r})}catch(i){this.context.logger.warn(`Failed to create relation to operation "${s}": ${i instanceof Error?i.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),c=a.startsWith("@")?a.slice(1):a,[e]=c.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return u(h.posix.normalize(e));const r=h.posix.dirname(o);return e.startsWith(r+"/")?h.posix.normalize(e):h.posix.normalize(h.posix.join(r,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{A as ArazzoEntitiesExtractor};
1
+ import h from"node:path";import{removeLeadingSlash as u}from"@redocly/theme/core/utils";import{toKebabCase as p}from"../../../../../../utils/string/to-kebab-case.js";import{promiseMapLimit as y}from"../../../../../utils/async/promise-map-limit.js";import{removeMarkdocTags as d}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{resolveEntityVersion as g}from"../../../utils/resolve-entity-version.js";import{BaseApiEntitiesExtractor as w}from"./base.js";const m=15;class A extends w{constructor(t){super("arazzo",t)}mapApiDescriptionToEntity(t){const o=u(t.realRelativePath),a=t.document.info.title,c=o.replace(/\.[^.]+$/,""),e=p(c.replace(/[\\/]/g,"-")),r=t.document["x-redocly-catalog-key"],n=typeof r=="string"&&r.trim()?p(r.trim()):e,l=t.document.info.version,s=g(l,t.realRelativePath);if(!s.success)throw new Error(`Arazzo "${a}" in file "${t.realRelativePath}" has conflicting versions: spec version "${s.fileVersion}" differs from folder version "${s.folderVersion}". Entity will not be created.`);return{type:this.type,key:n,title:a,summary:t.document.info.description?d(t.document.info.description):null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:o},version:s.version}}async loadApiDescriptions(){return(await this.context.cache.load(".","arazzo-docs")).data}async processApiDescription(t){const o=new Set;if(!this.#t(t))return this.context.logger.warn(`Skipping Arazzo description without source descriptions: ${t.realRelativePath}`),o;const a=this.mapApiDescriptionToEntity(t);await this.catalogEntitiesService.createEntityInLocalDatabase({entity:a,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),o.add(a.key),await this.#e(t,a.key,a.version,o);const c=t.document.sourceDescriptions||[];return await y(c,m,async e=>{if(!(e.type!=="openapi"||!e.url))try{const r=this.resolveSourceDescriptionUrl(e.url,t.realRelativePath);if(!r){!e.url.startsWith("http://")&&!e.url.startsWith("https://")&&this.context.logger.warn(`Could not resolve URL to local path: ${e.url}`);return}const n=await this.context.cache.load(r,"load-oas");if(!(n.data&&Array.isArray(n.data)&&n.data.length>0)){this.context.logger.warn(`No OpenAPI definition found at path: ${r}`);return}const s=n.data[0],i=p(u(s.realRelativePath).replace(/\.[^.]+$/,"").replace(/[\\/]/g,"-"));await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:a.key,type:"relatesTo",targetKey:i,fileHash:t.hash}),await this.#r(t,e.name,s,a.key,i,a.version)}catch(r){this.context.logger.warn(`Failed to create relation to OpenAPI source "${e.url}": ${r instanceof Error?r.message:"Unknown error"}`)}}),o}#t=t=>!!t?.document?.sourceDescriptions&&t.document.sourceDescriptions.length>0;#e=async(t,o,a,c)=>{try{const e=t.document.components?.inputs,r=e?Object.entries(e):[],n=[];for(const[l,s]of r)n.push(async()=>{const i=await this.#a({schemaName:l,schema:s,description:t,parentKey:o,parentVersion:a});c.add(i),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:o,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:a,targetVersion:a})});if(n.length===0)return;await y(n,m,l=>l())}catch(e){this.context.logger.warn(`Failed to create data schema entities for Arazzo description: ${e instanceof Error?e.message:"Unknown error"}`)}};#a=async({schemaName:t,schema:o,description:a,parentKey:c,parentVersion:e})=>{const r={type:"data-schema",key:`${c}-${p(t)}`,title:t,summary:o.description||o.title||null,tags:["arazzo"],metadata:{specType:this.specType,descriptionFile:a.realRelativePath,schema:"{}"},version:e};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:r,sourceFile:a.realRelativePath,fileHash:a.hash}),r.key};#r=async(t,o,a,c,e,r)=>{const n=t.document.workflows||[];if(n.length===0)return;const l=new Set;for(const s of n)for(const i of s.steps||[]){if(!i.operationId)continue;const f=i.operationId.startsWith(`${o}.`)?i.operationId.substring(`${o}.`.length):i.operationId;f&&l.add(f)}l.size!==0&&await y(Array.from(l),m,async s=>{try{const i=`${e}-${p(s)}`;await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:c,type:"uses",targetKey:i,fileHash:t.hash,sourceVersion:r,targetVersion:r})}catch(i){this.context.logger.warn(`Failed to create relation to operation "${s}": ${i instanceof Error?i.message:"Unknown error"}`)}})};resolveSourceDescriptionUrl(t,o){try{const a=t.trim(),c=a.startsWith("@")?a.slice(1):a,[e]=c.split("#");if(e.startsWith("http://")||e.startsWith("https://"))return null;if(e.startsWith("/"))return u(h.posix.normalize(e));const r=h.posix.dirname(o);return e.startsWith(r+"/")?h.posix.normalize(e):h.posix.normalize(h.posix.join(r,e))}catch{return this.context.logger.warn(`Failed to resolve URL: ${t}`),null}}}export{A as ArazzoEntitiesExtractor};
@@ -1,6 +1,7 @@
1
1
  import type { BundledDefinition } from '../../../../asyncapi-docs/asyncapi-doc-loader';
2
2
  import type { EntityFileSchema } from '@redocly/config';
3
- import { BaseApiEntitiesExtractor, type BaseApiEntitiesExtractorParams } from './base.js';
3
+ import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
4
+ import { BaseApiEntitiesExtractor } from './base.js';
4
5
  type Params = BaseApiEntitiesExtractorParams;
5
6
  export declare class AsyncApiEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
6
7
  #private;
@@ -1,19 +1,10 @@
1
1
  import type { FileInfo, LifecycleContext, ProcessContentActions } from '../../../../../types';
2
2
  import type { CatalogEntitiesService } from '../../../database/catalog-entities-service.js';
3
3
  import type { EntityFileSchema } from '@redocly/config';
4
- import type { ApiDescriptionMetadataSchema } from '@redocly/config';
5
4
  import type { BaseEntitiesExtractor } from '../base';
6
5
  import type { FileType } from '../../../../../persistence/file-hashes/types.js';
7
6
  import type { HashManager } from '../../../utils/hash-manager.js';
8
- type SpecType = Exclude<ApiDescriptionMetadataSchema['specType'], 'jsonschema' | 'avro' | 'zod' | 'protobuf'>;
9
- export type BaseApiEntitiesExtractorParams = {
10
- actions: ProcessContentActions;
11
- context: LifecycleContext;
12
- catalogEntitiesService: CatalogEntitiesService;
13
- fileHashManager: HashManager;
14
- fileType: FileType;
15
- shouldCalculateEntities?: boolean;
16
- };
7
+ import type { BaseApiEntitiesExtractorParams, SpecType } from '../../../types/extractors.js';
17
8
  export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition extends Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'>> implements BaseEntitiesExtractor {
18
9
  #private;
19
10
  protected type: "api-description";
@@ -30,5 +21,4 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
30
21
  protected abstract mapApiDescriptionToEntity(definition: BundledApiDefinition): EntityFileSchema;
31
22
  protected abstract processApiDescription(definition: BundledApiDefinition): Promise<Set<string>>;
32
23
  }
33
- export {};
34
24
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- import{FileHashStatus as a}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as l}from"../../../../../utils/async/promise-map-limit.js";const r=3;class u{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),await l(t,r,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE);return}const s=await this.processApiDescription(e);await this.#i(s,e.realRelativePath),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:a.OUTDATED}]})};#i=async(t,e)=>{t.size!==0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})}}export{u as BaseApiEntitiesExtractor};
1
+ import{FileHashStatus as a}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as r}from"../../../../../utils/async/promise-map-limit.js";import{catalogDataCollector as s}from"../../../utils/catalog-data-collector.js";const o=3;class p{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(t,e){this.specType=t,this.fileType=e.fileType,this.actions=e.actions,this.context=e.context,this.catalogEntitiesService=e.catalogEntitiesService,this.fileHashManager=e.fileHashManager,this.#e=e.shouldCalculateEntities??!1}async extract(){const t=await this.loadApiDescriptions();await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&s.addExtractor(this.specType),await r(t,o,async e=>{try{if(e.isVirtual||!e.hash)return;if(!((await this.fileHashManager.getByPath(e.realRelativePath))?.hash!==e.hash||this.#e||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){s.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE);return}const l=await this.processApiDescription(e);await this.#i(l,e.realRelativePath),s.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,e.realRelativePath,e.hash,a.UP_TO_DATE)}catch(i){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${e.realRelativePath}`),this.context.logger.warn(i)}}),await this.#t()}#t=async()=>{const t=await this.fileHashManager.getAllOutdated(this.fileType);if(!t||t.length===0)return;const e=await this.catalogEntitiesService.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});e&&e.items.length>0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.fileHashManager.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:this.fileType},{field:"status",operator:"equal",value:a.OUTDATED}]})};#i=async(t,e)=>{t.size!==0&&await this.catalogEntitiesService.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})}}export{p as BaseApiEntitiesExtractor};
@@ -1,7 +1,8 @@
1
1
  import type { GraphQLSchema } from 'graphql';
2
2
  import type { EntityFileSchema } from '@redocly/config';
3
3
  import type { FileInfo } from '../../../../../types';
4
- import { BaseApiEntitiesExtractor, type BaseApiEntitiesExtractorParams } from './base.js';
4
+ import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
5
+ import { BaseApiEntitiesExtractor } from './base.js';
5
6
  type GraphqlBundledDefinition = Omit<Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'>, 'hash'> & {
6
7
  hash: string;
7
8
  schema: GraphQLSchema;
@@ -1,3 +1,3 @@
1
- import{buildSchema as v,isObjectType as m,isScalarType as R,isEnumType as I,isInterfaceType as T,isUnionType as d,isInputObjectType as w,getNamedType as y,printType as $}from"graphql";import{removeLeadingSlash as O}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as D}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as u}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as S}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as L}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as F}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{BaseApiEntitiesExtractor as A}from"./base.js";import{resolveEntityVersion as j}from"../../../utils/resolve-entity-version.js";const E=15,b=15,N=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class Q extends A{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of await this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:s,metadata:o}=a.data,r=v(s),l=L(s);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:l,schema:r,content:s,metadata:o})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t){const e=O(t.realRelativePath),a=t.relativePath.replace(/\.(gql|graphql)$/,""),s=this.#s(a.split("/").pop()||"GraphQL Schema"),o=e.replace(/\.(gql|graphql)$/,""),r=f(o.replace(/[\\/]/g,"-")),l=this.#c(t.metadata?.tags),c=t.metadata?.["x-redocly-catalog-key"],i=typeof c=="string"&&c.trim()?f(c.trim()):r,n=j(null,t.realRelativePath),p=n.success?n.version:null;return{type:this.type,key:i,title:s,summary:t.metadata?.description||null,tags:l.concat("graphql"),metadata:{specType:this.specType,descriptionFile:e},version:p}}async processApiDescription(t){const e=new Set,{schema:a}=t;if(!a)return e;const s=this.mapApiDescriptionToEntity(t);return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:s,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),e.add(s.key),await Promise.all([this.#a(t,s.key,s.version,e),this.#y(t,s.key,s.version,e)]),e}#a=async(t,e,a,s)=>{const{schema:o}=t,r=o.getTypeMap(),l=this.#r(o),c=Object.entries(r).filter(([n])=>!n.startsWith("__")&&!N.has(n)&&!l.has(n));if(c.length===0)return;const i=await S(c,b,async([n,p])=>{const h=await this.#l({typeName:n,type:p,description:t,parentKey:e,parentVersion:a});s.add(h),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:h,fileHash:t.hash,sourceVersion:a,targetVersion:a})},this.#t);i.count.failed>0&&this.#t.warn(`Schema processing completed with ${i.count.failed} failures out of ${c.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:c})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&D(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${f(t)}`;#n=t=>m(t)?"object":T(t)?"interface":d(t)?"union":I(t)?"enum":w(t)?"input":R(t)?"scalar":"unknown";#r=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const s=t.getMutationType();s&&e.add(s.name);const o=t.getSubscriptionType();return o&&e.add(o.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const r=a.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"QUERY",rootTypeName:a.name})}const s=t.getMutationType();if(s){const r=s.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"MUTATION",rootTypeName:s.name})}const o=t.getSubscriptionType();if(o){const r=o.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"SUBSCRIBE",rootTypeName:o.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const r of t.args){const l=y(r.type);l&&!l.name.startsWith("__")&&a.push(this.#e(l.name,e))}const s=[],o=y(t.type);return o&&!o.name.startsWith("__")&&s.push(this.#e(o.name,e)),{inputTypes:a,returnTypes:s}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:s,parentVersion:o})=>{const r=this.#e(t,s),l=e.description??null,c=this.#n(e),i={type:"data-schema",key:r,title:t,summary:l,tags:["graphql"],metadata:{specType:this.specType,typeKind:c,sdl:this.#p(e,a.schema)},version:o};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:a.realRelativePath,fileHash:a.hash}),i.key};#p=(t,e)=>{const a=new Set,s=[],o=new Set(["String","ID","Int","Float","Boolean"]),r=i=>{if(!i)return;const n=i.name;if(n.startsWith("__")||o.has(n)||a.has(n))return;const p=e.getType(n);p&&(a.add(n),s.push(p))};for(r(t);s.length>0;){const i=s.pop();if(m(i)){for(const p of i.getInterfaces?.()??[])r(p);const n=i.getFields();for(const p of Object.values(n)){r(y(p.type));for(const h of p.args??[])r(y(h.type))}}else if(T(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}else if(d(i))for(const n of i.getTypes())r(n);else if(w(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}}const l=[t.name,...[...a].filter(i=>i!==t.name)],c=[];for(const i of l){const n=e.getType(i);n&&c.push($(n))}return c.join(`
1
+ import{buildSchema as v,isObjectType as m,isScalarType as R,isEnumType as I,isInterfaceType as T,isUnionType as d,isInputObjectType as w,getNamedType as y,printType as $}from"graphql";import{removeLeadingSlash as O}from"@redocly/theme/core/utils";import{toKebabCase as f}from"../../../../../../utils/string/to-kebab-case.js";import{capitalize as D}from"../../../../../../utils/string/capitalize.js";import{promiseMapLimit as u}from"../../../../../utils/async/promise-map-limit.js";import{promiseMapLimitWithStatus as S}from"../../../../../utils/async/promise-map-limit-with-status.js";import{sha1 as L}from"../../../../../utils/crypto/sha1.js";import{removeMarkdocTags as F}from"../../../../markdown/markdoc/helpers/remove-markdoc-tags.js";import{resolveEntityVersion as A}from"../../../utils/resolve-entity-version.js";import{BaseApiEntitiesExtractor as j}from"./base.js";const E=15,b=15,N=new Set(["String","ID","Int","Float","Boolean","DateTime","Date","Time","URL","URI","JSON","JSONObject","BigInt","BigDecimal"]);class Q extends j{#t;constructor(t){super("graphql",t),this.#t=t.context.logger}async loadApiDescriptions(){const t=[];for(const{relativePath:e}of await this.context.fs.scan(/(\.gql|\.graphql)$/))try{if(e.includes("@l10n")||await this.context.isPathIgnored(e))continue;const a=await this.context.cache.load(e,"graphql-doc");if(!a.data)continue;const{content:s,metadata:o}=a.data,r=v(s),l=L(s);t.push({realRelativePath:e,relativePath:e,isVirtual:!1,hash:l,schema:r,content:s,metadata:o})}catch(a){this.#t.warn(`Failed to load GraphQL schema from ${e}: ${a instanceof Error?a.message:"Unknown error"}`)}return t}mapApiDescriptionToEntity(t){const e=O(t.realRelativePath),a=t.relativePath.replace(/\.(gql|graphql)$/,""),s=this.#s(a.split("/").pop()||"GraphQL Schema"),o=e.replace(/\.(gql|graphql)$/,""),r=f(o.replace(/[\\/]/g,"-")),l=this.#c(t.metadata?.tags),c=t.metadata?.["x-redocly-catalog-key"],i=typeof c=="string"&&c.trim()?f(c.trim()):r,n=A(null,t.realRelativePath),p=n.success?n.version:null;return{type:this.type,key:i,title:s,summary:t.metadata?.description||null,tags:l.concat("graphql"),metadata:{specType:this.specType,descriptionFile:e},version:p}}async processApiDescription(t){const e=new Set,{schema:a}=t;if(!a)return e;const s=this.mapApiDescriptionToEntity(t);return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:s,sourceFile:t.realRelativePath,fileHash:t.hash,isRootEntity:!0}),e.add(s.key),await Promise.all([this.#a(t,s.key,s.version,e),this.#y(t,s.key,s.version,e)]),e}#a=async(t,e,a,s)=>{const{schema:o}=t,r=o.getTypeMap(),l=this.#r(o),c=Object.entries(r).filter(([n])=>!n.startsWith("__")&&!N.has(n)&&!l.has(n));if(c.length===0)return;const i=await S(c,b,async([n,p])=>{const h=await this.#l({typeName:n,type:p,description:t,parentKey:e,parentVersion:a});s.add(h),await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:e,type:"uses",targetKey:h,fileHash:t.hash,sourceVersion:a,targetVersion:a})},this.#t);i.count.failed>0&&this.#t.warn(`Schema processing completed with ${i.count.failed} failures out of ${c.length} types for ${t.realRelativePath}`),await this.#h({description:t,descriptionUniqueKey:e,userTypes:c})};#s=t=>{const e=t.replace(/[^A-Za-z0-9]+/g," ").trim();return e?e.split(" ").map(a=>a&&D(a)).join(" "):"GraphQL Schema"};#e=(t,e)=>`${e}-${f(t)}`;#n=t=>m(t)?"object":T(t)?"interface":d(t)?"union":I(t)?"enum":w(t)?"input":R(t)?"scalar":"unknown";#r=t=>{const e=new Set,a=t.getQueryType();a&&e.add(a.name);const s=t.getMutationType();s&&e.add(s.name);const o=t.getSubscriptionType();return o&&e.add(o.name),e};#i(t){const e=[],a=t.getQueryType();if(a){const r=a.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"QUERY",rootTypeName:a.name})}const s=t.getMutationType();if(s){const r=s.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"MUTATION",rootTypeName:s.name})}const o=t.getSubscriptionType();if(o){const r=o.getFields();for(const[l,c]of Object.entries(r))e.push({fieldName:l,field:c,operationType:"SUBSCRIBE",rootTypeName:o.name})}return e}#o=(t,e)=>{const a=[];if(t.args)for(const r of t.args){const l=y(r.type);l&&!l.name.startsWith("__")&&a.push(this.#e(l.name,e))}const s=[],o=y(t.type);return o&&!o.name.startsWith("__")&&s.push(this.#e(o.name,e)),{inputTypes:a,returnTypes:s}};#c=t=>{if(Array.isArray(t))return t.map(e=>String(e)).map(e=>e.trim()).filter(e=>e.length>0);if(typeof t=="string"){const e=t.trim();return e?[e]:[]}return[]};#l=async({typeName:t,type:e,description:a,parentKey:s,parentVersion:o})=>{const r=this.#e(t,s),l=e.description??null,c=this.#n(e),i={type:"data-schema",key:r,title:t,summary:l,tags:["graphql"],metadata:{specType:this.specType,typeKind:c,sdl:this.#p(e,a.schema)},version:o};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:i,sourceFile:a.realRelativePath,fileHash:a.hash}),i.key};#p=(t,e)=>{const a=new Set,s=[],o=new Set(["String","ID","Int","Float","Boolean"]),r=i=>{if(!i)return;const n=i.name;if(n.startsWith("__")||o.has(n)||a.has(n))return;const p=e.getType(n);p&&(a.add(n),s.push(p))};for(r(t);s.length>0;){const i=s.pop();if(m(i)){for(const p of i.getInterfaces?.()??[])r(p);const n=i.getFields();for(const p of Object.values(n)){r(y(p.type));for(const h of p.args??[])r(y(h.type))}}else if(T(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}else if(d(i))for(const n of i.getTypes())r(n);else if(w(i)){const n=i.getFields();for(const p of Object.values(n))r(y(p.type))}}const l=[t.name,...[...a].filter(i=>i!==t.name)],c=[];for(const i of l){const n=e.getType(i);n&&c.push($(n))}return c.join(`
2
2
 
3
3
  `)};#h=async({description:t,descriptionUniqueKey:e,userTypes:a})=>{const s=a.filter(([,o])=>m(o));s.length!==0&&await u(s,b,async([o,r])=>{const c=r.getInterfaces?.()??[];if(!c.length)return;const i=this.#e(o,e);await u([...c],5,async n=>{const p=this.#e(n.name,e);try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:i,type:"implements",targetKey:p,fileHash:t.hash})}catch(h){this.#t.warn(`Failed to create 'implements' relation ${i} -> ${p}: ${h instanceof Error?h.message:"Unknown error"}`)}})})};#y=async(t,e,a,s)=>{const{schema:o}=t,r=this.#i(o);if(r.length===0)return;const c=(await S(r,E,async({fieldName:i,field:n,operationType:p,rootTypeName:h})=>{const g=await this.#f(i,n,p,h,t,e,a);g&&s.add(g)},this.#t)).count.failed;c>0&&this.#t.warn(`Operation extraction completed with ${c} failures out of ${r.length} operations for ${e}`)};#f=async(t,e,a,s,o,r,l)=>{const{inputTypes:c,returnTypes:i}=this.#o(e,r),n=await this.#m({fieldName:t,field:e,operationType:a,rootTypeName:s,inputTypes:c,returnTypes:i,description:o,descriptionUniqueKey:r,descriptionVersion:l});return await this.#u({apiOperationKey:n,inputTypes:c,returnTypes:i,descriptionUniqueKey:r,description:o,descriptionVersion:l}),n??null};#m=async({fieldName:t,field:e,operationType:a,rootTypeName:s,inputTypes:o,returnTypes:r,description:l,descriptionUniqueKey:c,descriptionVersion:i})=>{const n=t,p=`${c}-${f(`${a.toLowerCase()}-${t}`)}`,h={type:"api-operation",key:p,title:n,summary:e.description?F(e.description):null,tags:["graphql"],metadata:{method:a,path:`${s}.${t}`,payload:o,responses:r},version:i};return await this.catalogEntitiesService.createEntityInLocalDatabase({entity:h,sourceFile:l.realRelativePath,fileHash:l.hash}),p};#u=async({apiOperationKey:t,inputTypes:e,returnTypes:a,descriptionUniqueKey:s,description:o,descriptionVersion:r})=>{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:"partOf",targetKey:s,fileHash:o.hash,sourceVersion:r,targetVersion:r});const l=[...new Set(e)],c=[...new Set(a)],i=[...l.map(n=>({key:n,relationType:"uses"})),...c.map(n=>({key:n,relationType:"returns"}))];await u(i,E,async({key:n,relationType:p})=>{try{await this.catalogEntitiesService.createEntityRelationInLocalDatabase({sourceKey:t,type:p,targetKey:n,fileHash:o.hash,sourceVersion:r,targetVersion:r})}catch(h){this.#t.warn(`Failed to create relation between operation ${t} and type ${n} (${p}): ${h instanceof Error?h.message:"Unknown error"}`)}})}}export{Q as GraphqlEntitiesExtractor};
@@ -1,6 +1,7 @@
1
1
  import type { BundledDefinition } from '../../../../openapi-docs/load-definition';
2
2
  import type { EntityFileSchema } from '@redocly/config';
3
- import { BaseApiEntitiesExtractor, type BaseApiEntitiesExtractorParams } from './base.js';
3
+ import type { BaseApiEntitiesExtractorParams } from '../../../types/extractors.js';
4
+ import { BaseApiEntitiesExtractor } from './base.js';
4
5
  export declare class OpenApiEntitiesExtractor extends BaseApiEntitiesExtractor<BundledDefinition> {
5
6
  #private;
6
7
  constructor(params: BaseApiEntitiesExtractorParams);
@@ -1 +1 @@
1
- import{CATALOG_ENTITIES_FILES_REGEX as l,ENTITY_SCHEMA_EXCLUDED_FOLDERS as E}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as c,FileType as a}from"../../../../persistence/file-hashes/types.js";import{promiseMapLimit as f}from"../../../../utils/async/promise-map-limit.js";import{extractFileContent as u}from"../../entities/extract-entities-content.js";import{resolveEntityVersion as d}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as h}from"../../entities/validate-entity.js";const g=15;class _{#e;#t;#i;#s;#r;constructor({fileHashManager:t,context:e,catalogEntitiesService:i,catalogConfig:r,shouldCalculateEntities:o}){this.#e=t,this.#t=e,this.#i=i,this.#s=r,this.#r=o}async extract(t){try{if(t&&this.#o(t)){await this.#n(t);return}await this.#e.markAllAsOutdated(a.ENTITY_DEFINITION);const i=(await this.#t.fs.scan(l)).filter(({relativePath:r})=>this.#o(r));await f(i,g,async({relativePath:r})=>{await this.#n(r)}),await this.#E()}catch(e){this.#t.logger.error("Error extracting entities.",e)}}#o=t=>!!(t.match(l)&&!E.some(e=>t.includes(e)));#n=async t=>{try{const e=await u(t,this.#t);if(!e){this.#t.logger.warn(`Error extracting content from ${t}.`);return}const i=await this.#e.computeFileHash(e);if(!((await this.#e.getByPath(t))?.hash!==i||this.#r||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE);return}const s=this.#a(e.entities,t);if(!s)return;const n=await this.#c(s,t,i);await this.#l(n,t),await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE)}catch(e){this.#t.logger.warn(`Error processing file "${t}". ${e instanceof Error?e.message:String(e)}.`)}};#a=(t,e)=>{try{return h(t,this.#s)}catch(i){return this.#t.logger.warn(`Error validating entities in "${e}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(t,e,i)=>{const r=new Set;for(const o of t)try{const s=d(o.version,e);if(!s.success){this.#t.logger.warn(`Entity "${o.key}" in file "${e}" has conflicting versions: file version "${s.fileVersion}" differs from folder version "${s.folderVersion}". Entity will not be created.`);continue}const n={...o,version:s.version};await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:e,fileHash:i}),o.key&&r.add(o.key)}catch(s){const n=o.key??"unknown";this.#t.logger.warn(`Error processing entity "${n}" from "${e}". ${s instanceof Error?s.message:String(s)}.`)}return r};#l=async(t,e)=>{t.size!==0&&await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})};#E=async()=>{const t=await this.#e.getAllOutdated(a.ENTITY_DEFINITION);if(!t||t.length===0)return;const e=await this.#i.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});!e||e.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.#e.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:c.OUTDATED}]}))}}export{_ as FsEntitiesExtractor};
1
+ import{CATALOG_ENTITIES_FILES_REGEX as f,ENTITY_SCHEMA_EXCLUDED_FOLDERS as E}from"../../../../constants/plugins/catalog-entities.js";import{FileHashStatus as c,FileType as a}from"../../../../persistence/file-hashes/types.js";import{promiseMapLimit as u}from"../../../../utils/async/promise-map-limit.js";import{extractFileContent as d}from"../../entities/extract-entities-content.js";import{resolveEntityVersion as h}from"../../utils/resolve-entity-version.js";import{parseAndValidateEntities as g}from"../../entities/validate-entity.js";import{catalogDataCollector as l}from"../../utils/catalog-data-collector.js";const m=15;class D{#e;#t;#i;#r;#s;constructor({fileHashManager:t,context:e,catalogEntitiesService:i,catalogConfig:s,shouldCalculateEntities:o}){this.#e=t,this.#t=e,this.#i=i,this.#r=s,this.#s=o}async extract(t){try{if(t&&this.#o(t)){await this.#n(t);return}await this.#e.markAllAsOutdated(a.ENTITY_DEFINITION);const i=(await this.#t.fs.scan(f)).filter(({relativePath:s})=>this.#o(s));i.length&&l.addExtractor("fs"),await u(i,m,async({relativePath:s})=>{await this.#n(s)}),await this.#f()}catch(e){this.#t.logger.error("Error extracting entities.",e)}}#o=t=>!!(t.match(f)&&!E.some(e=>t.includes(e)));#n=async t=>{try{const e=await d(t,this.#t);if(!e){this.#t.logger.warn(`Error extracting content from ${t}.`);return}const i=await this.#e.computeFileHash(e);if(!((await this.#e.getByPath(t))?.hash!==i||this.#s||process.env.FORCE_CATALOG_CACHE_REVALIDATE==="true")){l.increaseSkippedFilesCount(),await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE);return}const r=this.#a(e.entities,t);if(!r)return;const n=await this.#c(r,t,i);await this.#l(n,t),l.increaseProcessedFilesCount(),await this.#e.upsert(a.ENTITY_DEFINITION,t,i,c.UP_TO_DATE)}catch(e){this.#t.logger.warn(`Error processing file "${t}". ${e instanceof Error?e.message:String(e)}.`)}};#a=(t,e)=>{try{return g(t,this.#r)}catch(i){return this.#t.logger.warn(`Error validating entities in "${e}". ${i instanceof Error?i.message:String(i)}.`),null}};#c=async(t,e,i)=>{const s=new Set;for(const o of t)try{const r=h(o.version,e);if(!r.success){this.#t.logger.warn(`Entity "${o.key}" in file "${e}" has conflicting versions: file version "${r.fileVersion}" differs from folder version "${r.folderVersion}". Entity will not be created.`);continue}const n={...o,version:r.version};await this.#i.createEntityInLocalDatabase({entity:n,sourceFile:e,fileHash:i}),o.key&&s.add(o.key)}catch(r){const n=o.key??"unknown";this.#t.logger.warn(`Error processing entity "${n}" from "${e}". ${r instanceof Error?r.message:String(r)}.`)}return s};#l=async(t,e)=>{t.size!==0&&await this.#i.deleteEntitiesInLocalDatabase({op:"AND",conditions:[{field:"key",operator:"in",value:Array.from(t),modifier:"not"},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e}]})};#f=async()=>{const t=await this.#e.getAllOutdated(a.ENTITY_DEFINITION);if(!t||t.length===0)return;const e=await this.#i.getEntities({limit:200,filter:{op:"AND",conditions:[{field:"source_file",operator:"in",value:t.map(({filePath:i})=>i)},{field:"is_current",operator:"equal",value:!0}]}});!e||e.items.length===0||(await this.#i.deleteEntitiesInLocalDatabase({field:"key",operator:"in",value:e.items.map(({key:i})=>i)}),await this.#e.deleteFileHashes({op:"AND",conditions:[{field:"file_type",operator:"equal",value:a.ENTITY_DEFINITION},{field:"status",operator:"equal",value:c.OUTDATED}]}))}}export{D as FsEntitiesExtractor};
@@ -1 +1 @@
1
- import{FileType as n}from"../../persistence/file-hashes/types.js";import{telemetryTraceStep as O}from"../../../cli/telemetry/helpers/trace-step.js";import{CATALOG_BASE_SLUG as l,CATALOG_FILTERS_CACHE_NAMESPACE as D,ENTITIES_MAP_GLOBAL_DATA_KEY as P}from"../../constants/plugins/catalog-entities.js";import{CacheService as v}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as m}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as y}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as h}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as L}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as N}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as w}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as R}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as b}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as G}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as x}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const H="catalog-entity-template",M="catalog-entity";let g=!0;async function F(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(e,t){await O("build.plugin.catalog_entities",async E=>{if(process.env.NEW_CATALOG_ENABLED!=="true")return;const f=await t.getConfig(),a=y(f.entitiesCatalog);if(E?.setAttribute("config",JSON.stringify(a)),!a.show)return;const{logger:o}=t,u=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",i=g&&u,r=await w.getInstance({baseDbDir:e.serverOutDir,removeExisting:i,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),A=await N.getInstance({baseDbDir:e.serverOutDir}),s=new G(A),T=[new b({fileHashManager:s,context:t,catalogEntitiesService:r,catalogConfig:a,shouldCalculateEntities:i}),new x({actions:e,context:t,catalogEntitiesService:r,fileHashManager:s,fileType:n.OPENAPI_DESCRIPTION,shouldCalculateEntities:i}),new h({actions:e,context:t,catalogEntitiesService:r,fileHashManager:s,fileType:n.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:i}),new L({actions:e,context:t,catalogEntitiesService:r,fileHashManager:s,fileType:n.GRAPHQL_DESCRIPTION,shouldCalculateEntities:i}),new R({actions:e,context:t,catalogEntitiesService:r,fileHashManager:s,fileType:n.ARAZZO_DESCRIPTION,shouldCalculateEntities:i})];o.info("Starting entities extractors...");const C=o.startTiming();await r.transaction(async()=>{await Promise.all(T.map(async p=>p.extract()))});const S=r.getEntitySources();e.setGlobalData({[P]:S}),await(await v.getInstance({baseDbDir:e.serverOutDir})).deleteByNamespace(D),o.infoTime(C,"Entities extractors finished");const _=e.registerServerPropsGetter(M,m("../get-server-props.js")),d=e.createTemplate(H,m("../template/index.js"));e.addRoute({duplicateInAllLocales:!0,slug:l,fsPath:"",templateId:d,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[_],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:a}})});const[c]=Object.entries(a.catalogs??{}).find(([p,I])=>!I?.hide)||[];c&&e.addRedirect(l,{type:302,to:`${l}/${c}`}),o.info("Catalog Entities plugin finished"),g=!1})}}}var ee=F;export{F as catalogEntitiesPlugin,ee as default};
1
+ import{FileType as c}from"../../persistence/file-hashes/types.js";import{telemetryTraceStep as _}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as P}from"./utils/catalog-data-collector.js";import{CATALOG_BASE_SLUG as p,CATALOG_FILTERS_CACHE_NAMESPACE as I,ENTITIES_MAP_GLOBAL_DATA_KEY as v}from"../../constants/plugins/catalog-entities.js";import{CacheService as h}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as E}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as N}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as b}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as L}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as w}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as R}from"./database/catalog-entities-service.js";import{ArazzoEntitiesExtractor as G}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as x}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as F}from"./utils/hash-manager.js";import{OpenApiEntitiesExtractor as B}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const H="catalog-entity-template",M="catalog-entity";let u=!0;async function Y(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(t,i){await _("build.plugin.catalog_entities",async r=>{if(process.env.NEW_CATALOG_ENABLED!=="true")return;const f=await i.getConfig(),s=N(f.entitiesCatalog);if(r?.setAttribute("config",JSON.stringify(s)),!s.show)return;const{logger:l}=i,A=process.env.NODE_ENV==="development"||process.env.REDOCLY_LOCAL_DEV==="true",a=u&&A,e=await R.getInstance({baseDbDir:t.serverOutDir,removeExisting:a,runOnlyLocalDatabase:!0,runWithPragmaWalWriteOptimization:!0}),C=await w.getInstance({baseDbDir:t.serverOutDir}),o=new F(C),T=[new x({fileHashManager:o,context:i,catalogEntitiesService:e,catalogConfig:s,shouldCalculateEntities:a}),new B({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.OPENAPI_DESCRIPTION,shouldCalculateEntities:a}),new b({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:a}),new L({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.GRAPHQL_DESCRIPTION,shouldCalculateEntities:a}),new G({actions:t,context:i,catalogEntitiesService:e,fileHashManager:o,fileType:c.ARAZZO_DESCRIPTION,shouldCalculateEntities:a})];l.info("Starting entities extractors...");const y=l.startTiming();await e.transaction(async()=>{await Promise.all(T.map(async m=>m.extract()))});const d=e.getEntitySources();t.setGlobalData({[v]:d}),await(await h.getInstance({baseDbDir:t.serverOutDir})).deleteByNamespace(I),l.infoTime(y,"Entities extractors finished");const S=t.registerServerPropsGetter(M,E("../get-server-props.js")),D=t.createTemplate(H,E("../template/index.js"));t.addRoute({duplicateInAllLocales:!0,slug:p,fsPath:"",templateId:D,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[S],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:s}})});const[g]=Object.entries(s.catalogs??{}).find(([m,O])=>!O?.hide)||[];g&&t.addRedirect(p,{type:302,to:`${p}/${g}`});const n=await P.getCatalogEntitiesData(e);r?.setAttribute("totalEntities",n.totalEntitiesCount),r?.setAttribute("entitiesCountByType",JSON.stringify(n.countOfEntitiesByType)),r?.setAttribute("totalFilesSkippedByHash",n.totalFilesSkippedByHash),r?.setAttribute("totalProcessedFiles",n.totalProcessedFiles),r?.setAttribute("extractors",n.extractors),l.info("Catalog Entities plugin finished"),u=!1})}}}var rt=Y;export{Y as catalogEntitiesPlugin,rt as default};
@@ -0,0 +1,16 @@
1
+ import type { ApiDescriptionMetadataSchema } from '@redocly/config';
2
+ import type { ProcessContentActions } from '../../../types/plugins/common';
3
+ import type { LifecycleContext } from '../../../types/plugins/common';
4
+ import type { CatalogEntitiesService } from '../database/catalog-entities-service.js';
5
+ import type { FileType } from '../../../persistence/file-hashes/types.js';
6
+ import type { HashManager } from '../utils/hash-manager.js';
7
+ export type SpecType = Exclude<ApiDescriptionMetadataSchema['specType'], 'jsonschema' | 'avro' | 'zod' | 'protobuf'>;
8
+ export type BaseApiEntitiesExtractorParams = {
9
+ actions: ProcessContentActions;
10
+ context: LifecycleContext;
11
+ catalogEntitiesService: CatalogEntitiesService;
12
+ fileHashManager: HashManager;
13
+ fileType: FileType;
14
+ shouldCalculateEntities?: boolean;
15
+ };
16
+ //# sourceMappingURL=extractors.d.ts.map
@@ -0,0 +1,20 @@
1
+ import type { SpecType } from '../types/extractors';
2
+ import type { CatalogEntitiesService } from '../database/catalog-entities-service';
3
+ type Extractor = SpecType | 'fs';
4
+ type CountOfEntitiesByType = Record<string, number>;
5
+ export declare class CatalogDataCollector {
6
+ #private;
7
+ addExtractor(extractor: Extractor): void;
8
+ increaseSkippedFilesCount(): void;
9
+ increaseProcessedFilesCount(): void;
10
+ getCatalogEntitiesData(catalogEntitiesService: CatalogEntitiesService): Promise<{
11
+ totalEntitiesCount: number | "error";
12
+ countOfEntitiesByType: "error" | CountOfEntitiesByType;
13
+ extractors: Extractor[];
14
+ totalFilesSkippedByHash: number;
15
+ totalProcessedFiles: number;
16
+ }>;
17
+ }
18
+ export declare const catalogDataCollector: CatalogDataCollector;
19
+ export {};
20
+ //# sourceMappingURL=catalog-data-collector.d.ts.map
@@ -0,0 +1 @@
1
+ const i="error";class a{#t=new Set;#e;#s;#i=0;#o=0;addExtractor(t){this.#t.add(t)}increaseSkippedFilesCount(){this.#i++}increaseProcessedFilesCount(){this.#o++}async getCatalogEntitiesData(t){this.#e=this.#n(t),this.#s=this.#a(t);const[s,e]=await Promise.allSettled([this.#e,this.#s]);return{totalEntitiesCount:s.status==="fulfilled"?s.value:i,countOfEntitiesByType:e.status==="fulfilled"?e.value:i,extractors:Array.from(this.#t),totalFilesSkippedByHash:this.#i,totalProcessedFiles:this.#o}}async#n(t){return(await t.getEntities({})).page.total}async#a(t){return(await t.getEntitiesCountByTypes()).reduce((e,{type:o,count:n})=>(e[o]=n,e),{})}}const l=new a;export{a as CatalogDataCollector,l as catalogDataCollector};
@@ -0,0 +1,2 @@
1
+ export declare function runScorecardsWorker(baseDbDir: string): Promise<void>;
2
+ //# sourceMappingURL=run-scorecards-worker.d.ts.map
@@ -0,0 +1 @@
1
+ import{SCORECARDS_WORKER_KEY as n,scorecardsWorker as i}from"../../../workers/scorecards-worker-pool.js";import{logger as r}from"../../../tools/notifiers/logger.js";const c=5;async function t(s,e){try{const o=await i.exec(n,[{baseDbDir:s,pollingIntervalMs:parseInt(process.env.SCORECARDS_POLLING_INTERVAL_MS||"3000",10)}]);return o.success?r.info(`${o.message}`):r.error(`Scorecards Worker error (attempt ${e}/${c}):`,o.error),Promise.resolve()}catch(o){r.error(`Scorecards Worker execution failed (attempt ${e}/${c}):`,o)}return e<c?(r.info(`Retrying Scorecards Worker (attempt ${e+1}/${c})...`),t(s,e+1)):(r.error(`All ${c} attempts failed. Scorecards Worker could not be started.`),Promise.resolve())}async function l(s){return r.info("Starting continuous Scorecards Worker..."),t(s,1)}export{l as runScorecardsWorker};
@@ -0,0 +1,14 @@
1
+ export type ScorecardsWorkerParams = {
2
+ baseDbDir: string;
3
+ pollingIntervalMs?: number;
4
+ };
5
+ export type ScorecardsWorkerResponse = {
6
+ success: true;
7
+ message: string;
8
+ } | {
9
+ success: false;
10
+ message: string;
11
+ error: string;
12
+ };
13
+ export declare function startScorecardsWorker(params: ScorecardsWorkerParams): Promise<ScorecardsWorkerResponse>;
14
+ //# sourceMappingURL=scorecards.d.ts.map
@@ -0,0 +1 @@
1
+ import{logger as o}from"../../../tools/notifiers/logger.js";import{loadEnvVariables as l}from"../../../utils/envs/load-env-variables.js";import{CatalogEntitiesService as d}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";const u=3e3;async function y(s){try{const{baseDbDir:r,pollingIntervalMs:a=u}=s;l(r),o.verbose(`Initializing Scorecards Worker: polling interval ${a}ms (${a/1e3}s)`);const t=await d.getInstance({baseDbDir:r});return g(t,a),{success:!0,message:"Scorecards Worker started successfully"}}catch(r){const a=r instanceof Error?r.message:String(r);return o.error("Failed to start Scorecards Worker:",r),{success:!1,message:"Failed to start Scorecards Worker",error:a}}}async function g(s,r){let a=0,t=null;return t=setInterval(n,r),new Promise(()=>{});async function c(e){return e&&(await s.updateEntityScorecardsStatus(e.id,"CALCULATING"),await new Promise(i=>{setTimeout(async()=>{i()},1)}),await s.updateEntityScorecardsStatusIfCalculating(e.id,"UP_TO_DATE")?o.verbose(`Catalog Entity (${e.key}) scorecard evaluation completed successfully`):(await s.updateEntityScorecardsStatus(e.id,"OUTDATED"),o.verbose(`Catalog Entity (${e.key}) was updated during calculation, scorecard evaluation in not applicable anymore`))),Promise.resolve()}async function n(){try{a++;const e=await s.getOutdatedEntity();if(!e)return t||(o.verbose(`\u{1F50D} Resuming normal polling interval ${r}ms (${r/1e3}s)`),t=setInterval(n,r)),Promise.resolve();o.verbose(`\u{1F50D} Poll #${a} in Scorecards Worker: found Catalog Entity (${e.key}) for scorecard evaluation`),t&&(clearInterval(t),t=null,o.verbose(`\u{1F50D} Stopping normal polling while processing Catalog Entity (${e.key}) for scorecard evaluation`)),await c(e),await n()}catch(e){o.error("Error during poll in Scorecards Worker:",e),t||(t=setInterval(n,r))}}}export{y as startScorecardsWorker};
@@ -0,0 +1 @@
1
+ ALTER TABLE `entities` ADD `scorecards_status` text;