@redocly/realm 0.136.0-next.1 → 0.136.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 (112) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/cli/eject/ejectComponent.d.ts +1 -1
  3. package/dist/cli/eject/ejectTheme.d.ts +1 -1
  4. package/dist/cli/eject/themeOperations.d.ts +2 -2
  5. package/dist/client/TestProvider.d.ts +1 -1
  6. package/dist/client/app/ConditionalLink.d.ts +1 -1
  7. package/dist/client/app/hooks/catalog/useCatalogFilter.d.ts +1 -1
  8. package/dist/client/app/hooks/catalog/useCatalogViewMode.js +1 -1
  9. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.d.ts +1 -1
  10. package/dist/client/app/hooks/catalog/useFetchCatalogEntities.js +1 -1
  11. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.d.ts +2 -2
  12. package/dist/client/app/hooks/catalog/useFetchCatalogEntitiesRelations.js +1 -1
  13. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.d.ts +1 -1
  14. package/dist/client/app/hooks/catalog/useSearchTracker.d.ts +2 -5
  15. package/dist/client/app/hooks/catalog/useSearchTracker.js +1 -1
  16. package/dist/client/app/hooks/codeHighlight/useCodeHighlight.d.ts +1 -6
  17. package/dist/client/app/pages/DevLogin/DevLoginForm.d.ts +1 -1
  18. package/dist/client/app/useGlobalData.d.ts +1 -1
  19. package/dist/client/app/utils/loadAndNavigate.d.ts +1 -1
  20. package/dist/client/providers/page-data/hooks.d.ts +2 -2
  21. package/dist/client/providers/post-message/use-post-message.d.ts +1 -1
  22. package/dist/markdoc/helpers/get-operation/get-operation.d.ts +1 -1
  23. package/dist/markdoc/tags/index.d.ts +48 -2
  24. package/dist/server/api-routes/helpers/read-stream-with-size-limit.d.ts +1 -1
  25. package/dist/server/api-routes/run-api-routes-worker.d.ts +1 -1
  26. package/dist/server/api-routes/run-api-routes-worker.js +1 -1
  27. package/dist/server/config/env-config.d.ts +2 -0
  28. package/dist/server/config/env-schema.d.ts +5 -0
  29. package/dist/server/config/env-schemas/feature-flags.d.ts +4 -0
  30. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  31. package/dist/server/persistence/cache/mappers/create-cache-db-record.d.ts +1 -1
  32. package/dist/server/persistence/file-hashes/mappers/create-file-hash-db-record.d.ts +1 -1
  33. package/dist/server/persistence/kv/mappers/create-kv-db-record.d.ts +1 -1
  34. package/dist/server/plugins/catalog-entities/database/catalog-entities-diff-publisher.d.ts +1 -1
  35. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.d.ts +4 -2
  36. package/dist/server/plugins/catalog-entities/database/catalog-entities-revisions-pruner.js +23 -3
  37. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +5 -5
  38. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-attributes-db-record.d.ts +1 -1
  39. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-db-record.d.ts +1 -1
  40. package/dist/server/plugins/catalog-entities/database/mappers/create-entity-relation-db-record-from-file-schema.d.ts +1 -1
  41. package/dist/server/plugins/catalog-entities/database/remote-publish-lock-service.d.ts +3 -3
  42. package/dist/server/plugins/catalog-entities/database/repositories/bffEntities/bff-entities-read-repository.d.ts +2 -2
  43. package/dist/server/plugins/catalog-entities/database/repositories/common/filters-repository.d.ts +1 -1
  44. package/dist/server/plugins/catalog-entities/database/repositories/common/revision-repository.d.ts +1 -1
  45. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-read-repository.d.ts +1 -1
  46. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.d.ts +2 -2
  47. package/dist/server/plugins/catalog-entities/database/repositories/entities/entities-write-repository.js +1 -1
  48. package/dist/server/plugins/catalog-entities/database/repositories/entityAttributes/entity-attributes-write-repository.d.ts +1 -1
  49. package/dist/server/plugins/catalog-entities/database/repositories/relations/relations-read-repository.d.ts +1 -1
  50. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.d.ts +5 -2
  51. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  52. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.d.ts +1 -1
  53. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  54. package/dist/server/plugins/catalog-entities/utils/get-not-accessible-catalog-resources.d.ts +1 -1
  55. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.d.ts +1 -1
  56. package/dist/server/plugins/dev-onboarding/index.d.ts +1 -1
  57. package/dist/server/plugins/dev-onboarding/template/components/RevokeAPIKey.d.ts +1 -1
  58. package/dist/server/plugins/dev-onboarding/template/components/RollAPIKey.d.ts +1 -1
  59. package/dist/server/plugins/graphql-docs/search/ai/utils.d.ts +1 -1
  60. package/dist/server/plugins/markdown/markdoc/markdoc-options.d.ts +9 -9
  61. package/dist/server/plugins/markdown/markdoc/plugins/utils.d.ts +5 -0
  62. package/dist/server/plugins/markdown/markdoc/plugins/utils.js +1 -1
  63. package/dist/server/plugins/markdown/runtime-transform.js +1 -1
  64. package/dist/server/plugins/markdown/utils/resolve-markdown-template.d.ts +1 -1
  65. package/dist/server/plugins/mcp/auth/auth-handlers.d.ts +2 -0
  66. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  67. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  68. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  69. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.d.ts +2 -0
  70. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/constants.js +1 -0
  71. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
  72. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
  73. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +1 -1
  74. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  75. package/dist/server/plugins/mcp/docs-mcp/utils.d.ts +2 -2
  76. package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.d.ts +1 -1
  77. package/dist/server/plugins/mcp/servers/docs-server.d.ts +1 -1
  78. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +2 -2
  79. package/dist/server/plugins/scorecard-classic/compute-scorecard.d.ts +1 -1
  80. package/dist/server/plugins/scorecard-classic/index.d.ts +1 -1
  81. package/dist/server/plugins/scorecard-classic/template/components.d.ts +1 -1
  82. package/dist/server/plugins/scorecard-classic/template/useData.d.ts +1 -1
  83. package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.d.ts +1 -1
  84. package/dist/server/plugins/search/engines/search-engine.d.ts +1 -1
  85. package/dist/server/plugins/search/llmstxt/index.d.ts +1 -1
  86. package/dist/server/plugins/sidebars/index.d.ts +1 -1
  87. package/dist/server/providers/database/database-path-generator.d.ts +2 -2
  88. package/dist/server/providers/database/utils/storage-limit-validator.d.ts +1 -1
  89. package/dist/server/sandbox/sandbox.js +2 -2
  90. package/dist/server/ssr/server-side-props/get-default-static-props.d.ts +1 -1
  91. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.d.ts +1 -1
  92. package/dist/server/ssr/template.d.ts +1 -1
  93. package/dist/server/store.js +1 -1
  94. package/dist/server/utils/sandbox-context.d.ts +18 -0
  95. package/dist/server/utils/sandbox-context.js +1 -0
  96. package/dist/server/web-server/auth.d.ts +1 -1
  97. package/dist/server/web-server/middleware/catalogAuthMiddleware.d.ts +1 -1
  98. package/dist/server/web-server/routes/auth.js +1 -1
  99. package/dist/server/web-server/routes/catalog/helpers/has-access-to-entity.d.ts +1 -1
  100. package/dist/server/web-server/routes/catalog/helpers/upsert-pages-stats.d.ts +1 -1
  101. package/dist/server/web-server/routes/feedback.d.ts +1 -1
  102. package/dist/server/web-server/routes/helpers/process-redirects.d.ts +1 -1
  103. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.d.ts +5 -4
  104. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  105. package/dist/server/web-server/routes/mcp-routes/mcp-routes.js +1 -1
  106. package/dist/server/web-server/routes/mcp-routes/utils/build-agent-card.d.ts +1 -1
  107. package/dist/server/web-server/utils/prepare-list-response.d.ts +1 -1
  108. package/dist/server/workers/api-routes-worker-pool.js +1 -1
  109. package/dist/server/workers/mcp-tool-worker-pool.js +1 -1
  110. package/dist/server/workers/worker-pool.d.ts +1 -0
  111. package/dist/server/workers/worker-pool.js +1 -1
  112. package/package.json +6 -6
@@ -10,6 +10,6 @@ type CreateEntityRelationDbRecordFromFileSchemaParams = {
10
10
  organizationId: string;
11
11
  projectId: string;
12
12
  };
13
- export declare function createEntityRelationDbRecordFromFileSchema({ relation, sourceFile, fileHash, sourceKey, sourceVersion, sourceRevision, organizationId, projectId }: CreateEntityRelationDbRecordFromFileSchemaParams): DatabaseEntityRelationDto;
13
+ export declare function createEntityRelationDbRecordFromFileSchema({ relation, sourceFile, fileHash, sourceKey, sourceVersion, sourceRevision, organizationId, projectId, }: CreateEntityRelationDbRecordFromFileSchemaParams): DatabaseEntityRelationDto;
14
14
  export {};
15
15
  //# sourceMappingURL=create-entity-relation-db-record-from-file-schema.d.ts.map
@@ -3,17 +3,17 @@ export declare const INTERNAL_CATALOG_PUBLISH_CACHE_NAMESPACE = "catalog-publish
3
3
  export declare const INTERNAL_CATALOG_PUBLISH_KEY_PREFIX = "catalog-entities::publisher";
4
4
  export declare class RemotePublishLockService {
5
5
  #private;
6
- static getInternalCacheValue({ remoteConnection, key }: {
6
+ static getInternalCacheValue({ remoteConnection, key, }: {
7
7
  remoteConnection: DatabaseConnection;
8
8
  key: string;
9
9
  }): Promise<string | null>;
10
- static upsertInternalCacheValue({ remoteConnection, key, value, ttl }: {
10
+ static upsertInternalCacheValue({ remoteConnection, key, value, ttl, }: {
11
11
  remoteConnection: DatabaseConnection;
12
12
  key: string;
13
13
  value: string;
14
14
  ttl?: number | null;
15
15
  }): Promise<void>;
16
- static runUnderRemotePublishLock<T>({ runId, remoteConnection, run }: {
16
+ static runUnderRemotePublishLock<T>({ runId, remoteConnection, run, }: {
17
17
  runId: string;
18
18
  remoteConnection: DatabaseConnection;
19
19
  run: () => Promise<T>;
@@ -5,13 +5,13 @@ import type { ListResult } from '../types.js';
5
5
  export declare class BffEntitiesReadRepository {
6
6
  #private;
7
7
  constructor(db: DatabaseClient);
8
- getEntitiesWithRelations({ paginationParams, rbacTeams, excludedEntities, excludedTypes }: {
8
+ getEntitiesWithRelations({ paginationParams, rbacTeams, excludedEntities, excludedTypes, }: {
9
9
  paginationParams: PaginationParams;
10
10
  rbacTeams?: string[];
11
11
  excludedEntities?: string[];
12
12
  excludedTypes?: string[];
13
13
  }): Promise<ListResult<BffCatalogEntity>>;
14
- getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities }: {
14
+ getEntityWithRelationsByKey({ entityKey, filter, rbacTeams, excludedTypes, excludedEntities, }: {
15
15
  entityKey: string;
16
16
  filter?: {
17
17
  revision?: string | null;
@@ -3,6 +3,6 @@ import type { CatalogFiltersParams, FilterOption } from '../types.js';
3
3
  export declare class FiltersRepository {
4
4
  #private;
5
5
  constructor(db: DatabaseClient);
6
- getCatalogFilters({ entitiesTypes, emptyFilters, rbacTeams, excludedTypes, excludedEntities }: CatalogFiltersParams): Promise<Record<string, FilterOption[]>>;
6
+ getCatalogFilters({ entitiesTypes, emptyFilters, rbacTeams, excludedTypes, excludedEntities, }: CatalogFiltersParams): Promise<Record<string, FilterOption[]>>;
7
7
  }
8
8
  //# sourceMappingURL=filters-repository.d.ts.map
@@ -3,7 +3,7 @@ import type { EntityRevisionSummary } from '../../../schemas/read-model-schemas.
3
3
  export declare class RevisionRepository {
4
4
  #private;
5
5
  constructor(db: DatabaseClient);
6
- getCurrentRevisionInfo({ key, version, revision }: {
6
+ getCurrentRevisionInfo({ key, version, revision, }: {
7
7
  key: string;
8
8
  version: string | null;
9
9
  revision: string | null;
@@ -7,7 +7,7 @@ import type { GetEntityByIdParams } from '../../../types/params';
7
7
  export declare class EntitiesReadRepository {
8
8
  #private;
9
9
  constructor(db: DatabaseClient);
10
- getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
10
+ getEntities({ paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
11
11
  paginationParams: PaginationParams;
12
12
  rbacTeams?: string[];
13
13
  excludedTypes?: string[];
@@ -7,10 +7,10 @@ import type { ScorecardsStatus } from '../../../entities/types';
7
7
  export declare class EntitiesWriteRepository {
8
8
  #private;
9
9
  constructor(db: DatabaseClient, organizationId: string, projectId: string);
10
- createEntity({ entity, source, fileHash, sourceFile, isRootEntity, isDeleted, rbacTeams, errorOnSkip, revision }: CreateEntityParams): Promise<EntityReadModelSchema | null>;
10
+ createEntity({ entity, source, fileHash, sourceFile, isRootEntity, isDeleted, rbacTeams, errorOnSkip, revision, }: CreateEntityParams): Promise<EntityReadModelSchema | null>;
11
11
  updateEntity(incomingEntity: Partial<EntityDtoSchema>, entityToBeUpdated: EntityReadModelSchema): Promise<EntityReadModelSchema | null>;
12
12
  setEntitiesAsOutdated(filter: Filter): Promise<void>;
13
- softDeleteEntitiesWithRelations({ filter, revision, fileHash }: {
13
+ softDeleteEntitiesWithRelations({ filter, revision, fileHash, }: {
14
14
  filter: Filter;
15
15
  revision: string;
16
16
  fileHash: string;
@@ -1 +1 @@
1
- import{and as v,eq as c,isNull as E,or as T,sql as N}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as I}from"@redocly/theme/core/constants";import{sha1 as V}from"../../../../../utils/crypto/sha1.js";import{envConfig as F}from"../../../../../config/env-config.js";import{entitiesTable as i}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{convertFilterToWhereCondition as K}from"../../../../../providers/database/pagination/filter.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{RevisionRepository as x}from"../common/revision-repository.js";import{VersionRepository as z}from"../common/version-repository.js";import{EntityAttributesWriteRepository as H}from"../entityAttributes/entity-attributes-write-repository.js";import{createEntityDbRecord as O}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as k}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromFileSchema as P}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{createEntityRelationDbRecordFromDto as j}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{EntitiesReadRepository as G}from"./entities-read-repository.js";import{RelationsReadRepository as M}from"../relations/relations-read-repository.js";import{RelationsWriteRepository as $}from"../relations/relations-write-repository.js";const m=15;class ce{#e;#t;#n;#o;#i;#s;#a;#u;#r;constructor(e,s,r){this.#e=e,this.#i=s,this.#s=r,this.#t=new x(e),this.#n=new z(e),this.#o=new H(e),this.#a=new G(e),this.#u=new M(e),this.#r=new $(e,s,r)}async createEntity({entity:e,source:s,fileHash:r,sourceFile:o,isRootEntity:t,isDeleted:n,rbacTeams:l,errorOnSkip:d=!1,revision:h}){const{relations:u=[],...f}=e,y=V(JSON.stringify(f)),R=e.version??I,C=h??new Date().toISOString(),W=await this.#t.shouldSkipRevisionCreation(e.key,R,y,t,n);if(Array.isArray(l)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:l,organizationId:this.#i,projectId:this.#s}),W){if(d)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:g,hasCurrentRevision:L}=await this.#t.getCurrentRevisionInfo({key:e.key,version:R,revision:C}),w=O({entity:{...e,revision:C,hash:y,isCurrent:g,isDefaultVersion:g,isDeleted:n,version:R},organizationId:this.#i,projectId:this.#s,source:s,sourceFile:o??null,fileHash:r??null}),{key:D,..._}=w;if(g&&L&&(await this.#t.markAllRevisionsAsNotCurrent(D),await this.#n.markAllVersionsAsNotDefault(D)),F.isDevelopMode&&!F.REDOCLY_INTERNAL_DEV)return await this.#l(w,u);const A=await this.#e.client.insert(i).values(w).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:_}).returning();return A.length?(u&&await this.#r.createEntityRelations(u.map(S=>({...S,sourceKey:e.key,targetKey:S.key}))),k(A[0])):null}async updateEntity(e,s){const{shouldSetNewCurrentRevision:r,hasCurrentRevision:o}=await this.#t.getCurrentRevisionInfo({key:s.key,version:e.version??s.version??I,revision:s.revision});r&&o&&(await this.#t.markAllRevisionsAsNotCurrent(s.key),await this.#n.markAllVersionsAsNotDefault(s.key));const t=O({entity:{...s,...e,hash:V(JSON.stringify({...s,...e})),isCurrent:r,isDefaultVersion:r,createdAt:s.createdAt??void 0},organizationId:this.#i,projectId:this.#s,source:"remote",sourceFile:null,fileHash:null}),{key:n,source:l,scorecardsStatus:d,...h}=t,u=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...h,scorecardsStatus:N`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return u.length?k(u[0]):null}async setEntitiesAsOutdated(e){const s=K(e);await this.#e.client.update(i).set({scorecardsStatus:"OUTDATED"}).where(s)}async#l(e,s){const{key:r,source:o,version:t,...n}=e,h=await this.#e.client.select({id:i.id}).from(i).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(n).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:n}).returning(),u=s?.map(f=>{const y=P({relation:f,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#i,projectId:this.#s});return this.#e.client.insert(a).values(y).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:y}).run()})??[];return await p(u,m,async f=>f),k(h[0])}async softDeleteEntitiesWithRelations({filter:e,revision:s,fileHash:r}){const t={op:"AND",conditions:[e,{field:"is_deleted",operator:"equal",value:!1}]};for(;;){const n=await this.#a.getEntities({paginationParams:{filter:t,limit:500}});if(n.items.length===0)break;const l=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(l,s)}}async deleteEntity(e){return await this.#r.deleteEntityRelationsOnEntityRemoval(e),await this.#e.client.delete(i).where(c(i.id,e.id)),await this.#t.ensureDefaultAndCurrentRevisionForKey(e.key),e.id}async deleteEntities(e){const s=K(e);if(!s)return!1;const r=await this.#e.client.delete(i).where(s).returning({key:i.key,source:i.source,isCurrent:i.isCurrent,isDefaultVersion:i.isDefaultVersion,version:i.version});if(r.length===0)return!0;const o=r.reduce((t,n)=>((n.isCurrent||n.isDefaultVersion)&&t.add(n.key),t),new Set);if(o.size===0)return!0;await p(Array.from(o),m,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(T(v(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[E(a.sourceVersion)]),v(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[E(a.targetVersion)])));return!0}async updateEntityScorecardsStatus(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(c(i.id,e)).returning()).length>0}async updateEntityScorecardsStatusIfCalculating(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(N`${i.id} = ${e} AND ${i.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}async#c({entities:e,revision:s,fileHash:r}){return(await p(e,m,async t=>{const n={type:t.type,key:t.key,title:t.title,summary:t.summary??void 0,tags:t.tags??void 0,metadata:t.metadata??void 0,git:t.git??void 0,contact:t.contact??void 0,links:t.links??void 0,version:t.version??void 0};return this.createEntity({entity:n,sourceFile:t.sourceFile??"",fileHash:r,isDeleted:!0,errorOnSkip:!1,source:t.source,revision:s})})).filter(t=>t!==null)}async#d(e,s){if(e.length===0)return!0;const r=await p(e,m,async o=>(await this.#u.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const l=n.direction,d=n.sourceToTargetRelation,h=n.targetKey,u=l==="outgoing"?o.key:h,f=l==="outgoing"?h:o.key,y=l==="outgoing"?d:d.startsWith("reverse:")?d.slice(8):d;return!y||!u||!f?null:j({type:y,sourceKey:u,targetKey:f,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await p(r.flat(),m,async o=>this.#r.upsertEntityRelation(o)),!0}}export{ce as EntitiesWriteRepository};
1
+ import{and as v,eq as c,isNull as E,or as x,sql as I}from"drizzle-orm";import{VERSION_NOT_SPECIFIED as V}from"@redocly/theme/core/constants";import{sha1 as F}from"../../../../../utils/crypto/sha1.js";import{envConfig as K}from"../../../../../config/env-config.js";import{entitiesTable as i}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-table.js";import{convertFilterToWhereCondition as O}from"../../../../../providers/database/pagination/filter.js";import{entitiesRelationsTable as a}from"../../../../../providers/database/databases/sqlite-db/schemas/entities-relations-table.js";import{promiseMapLimit as p}from"../../../../../utils/async/promise-map-limit.js";import{RevisionRepository as z}from"../common/revision-repository.js";import{VersionRepository as H}from"../common/version-repository.js";import{EntityAttributesWriteRepository as P}from"../entityAttributes/entity-attributes-write-repository.js";import{createEntityDbRecord as W}from"../../mappers/create-entity-db-record.js";import{createEntityReadModel as k}from"../../mappers/create-entity-read-model.js";import{createEntityRelationDbRecordFromFileSchema as j}from"../../mappers/create-entity-relation-db-record-from-file-schema.js";import{createEntityRelationDbRecordFromDto as G}from"../../mappers/create-entity-relation-db-record-from-dto.js";import{EntitiesReadRepository as M}from"./entities-read-repository.js";import{RelationsReadRepository as U}from"../relations/relations-read-repository.js";import{RelationsWriteRepository as $}from"../relations/relations-write-repository.js";const m=15;class de{#e;#t;#n;#o;#i;#s;#a;#l;#r;constructor(e,s,r){this.#e=e,this.#i=s,this.#s=r,this.#t=new z(e),this.#n=new H(e),this.#o=new P(e),this.#a=new M(e),this.#l=new U(e),this.#r=new $(e,s,r)}async createEntity({entity:e,source:s,fileHash:r,sourceFile:o,isRootEntity:t,isDeleted:n,rbacTeams:u,errorOnSkip:d=!1,revision:h}){const{relations:l=[],...f}=e,y=F(JSON.stringify(f)),g=e.version??V,C=h??new Date().toISOString(),L=await this.#t.shouldSkipRevisionCreation(e.key,g,y,t,n);Array.isArray(u)&&await this.#o.upsertEntityAttributes({entityKey:e.key,rbacTeams:u,organizationId:this.#i,projectId:this.#s});const D=K.isDevelopMode&&!K.REDOCLY_INTERNAL_DEV;if(l?.length&&!D&&await this.#r.createEntityRelations(l.map(N=>({...N,sourceKey:e.key,targetKey:N.key,sourceFile:o??null,fileHash:r??null}))),L){if(d)throw new Error("Entity validation failed: entity already exists");return null}const{shouldSetNewCurrentRevision:R,hasCurrentRevision:_}=await this.#t.getCurrentRevisionInfo({key:e.key,version:g,revision:C}),w=W({entity:{...e,revision:C,hash:y,isCurrent:R,isDefaultVersion:R,isDeleted:n,version:g},organizationId:this.#i,projectId:this.#s,source:s,sourceFile:o??null,fileHash:r??null}),{key:A,...T}=w;if(R&&_&&(await this.#t.markAllRevisionsAsNotCurrent(A),await this.#n.markAllVersionsAsNotDefault(A)),D)return await this.#u(w,l);const S=await this.#e.client.insert(i).values(w).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:T}).returning();return S.length?k(S[0]):null}async updateEntity(e,s){const{shouldSetNewCurrentRevision:r,hasCurrentRevision:o}=await this.#t.getCurrentRevisionInfo({key:s.key,version:e.version??s.version??V,revision:s.revision});r&&o&&(await this.#t.markAllRevisionsAsNotCurrent(s.key),await this.#n.markAllVersionsAsNotDefault(s.key));const t=W({entity:{...s,...e,hash:F(JSON.stringify({...s,...e})),isCurrent:r,isDefaultVersion:r,createdAt:s.createdAt??void 0},organizationId:this.#i,projectId:this.#s,source:"remote",sourceFile:null,fileHash:null}),{key:n,source:u,scorecardsStatus:d,...h}=t,l=await this.#e.client.insert(i).values(t).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:{...h,scorecardsStatus:I`CASE WHEN ${i.scorecardsStatus} = 'CALCULATING' THEN 'CANCELLED' ELSE 'OUTDATED' END`}}).returning();return l.length?k(l[0]):null}async setEntitiesAsOutdated(e){const s=O(e);await this.#e.client.update(i).set({scorecardsStatus:"OUTDATED"}).where(s)}async#u(e,s){const{key:r,source:o,version:t,...n}=e,h=await this.#e.client.select({id:i.id}).from(i).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).limit(1).get()!=null?await this.#e.client.update(i).set(n).where(v(c(i.key,r),t?c(i.version,t):E(i.version))).returning():await this.#e.client.insert(i).values(e).onConflictDoUpdate({target:[i.key,i.source,i.revision,i.version],set:n}).returning(),l=s?.map(f=>{const y=j({relation:f,sourceFile:e.sourceFile??"",fileHash:e.fileHash??"",sourceKey:e.key,sourceVersion:e.version??null,sourceRevision:e.revision??null,organizationId:this.#i,projectId:this.#s});return this.#e.client.insert(a).values(y).onConflictDoUpdate({target:[a.sourceKey,a.targetKey,a.sourceVersion,a.targetVersion,a.sourceRevision,a.targetRevision,a.sourceToTargetRelation],set:y}).run()})??[];return await p(l,m,async f=>f),k(h[0])}async softDeleteEntitiesWithRelations({filter:e,revision:s,fileHash:r}){const t={op:"AND",conditions:[e,{field:"is_deleted",operator:"equal",value:!1}]};for(;;){const n=await this.#a.getEntities({paginationParams:{filter:t,limit:500}});if(n.items.length===0)break;const u=await this.#c({entities:n.items,revision:s,fileHash:r});await this.#d(u,s)}}async deleteEntity(e){return await this.#r.deleteEntityRelationsOnEntityRemoval(e),await this.#e.client.delete(i).where(c(i.id,e.id)),await this.#t.ensureDefaultAndCurrentRevisionForKey(e.key),e.id}async deleteEntities(e){const s=O(e);if(!s)return!1;const r=await this.#e.client.delete(i).where(s).returning({key:i.key,source:i.source,isCurrent:i.isCurrent,isDefaultVersion:i.isDefaultVersion,version:i.version});if(r.length===0)return!0;const o=r.reduce((t,n)=>((n.isCurrent||n.isDefaultVersion)&&t.add(n.key),t),new Set);if(o.size===0)return!0;await p(Array.from(o),m,async t=>this.#t.ensureDefaultAndCurrentRevisionForKey(t));for(const t of r)await this.#e.client.delete(a).where(x(v(c(a.sourceKey,t.key),...t.version?[c(a.sourceVersion,t.version)]:[E(a.sourceVersion)]),v(c(a.targetKey,t.key),...t.version?[c(a.targetVersion,t.version)]:[E(a.targetVersion)])));return!0}async updateEntityScorecardsStatus(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(c(i.id,e)).returning()).length>0}async updateEntityScorecardsStatusIfCalculating(e,s){return(await this.#e.client.update(i).set({scorecardsStatus:s}).where(I`${i.id} = ${e} AND ${i.scorecardsStatus} = 'CALCULATING'`).returning()).length>0}async#c({entities:e,revision:s,fileHash:r}){return(await p(e,m,async t=>{const n={type:t.type,key:t.key,title:t.title,summary:t.summary??void 0,tags:t.tags??void 0,metadata:t.metadata??void 0,git:t.git??void 0,contact:t.contact??void 0,links:t.links??void 0,version:t.version??void 0};return this.createEntity({entity:n,sourceFile:t.sourceFile??"",fileHash:r,isDeleted:!0,errorOnSkip:!1,source:t.source,revision:s})})).filter(t=>t!==null)}async#d(e,s){if(e.length===0)return!0;const r=await p(e,m,async o=>(await this.#l.getRelationsForEntity(o.key,o.version,s)).map(n=>{if(!n)return null;const u=n.direction,d=n.sourceToTargetRelation,h=n.targetKey,l=u==="outgoing"?o.key:h,f=u==="outgoing"?h:o.key,y=u==="outgoing"?d:d.startsWith("reverse:")?d.slice(8):d;return!y||!l||!f?null:G({type:y,sourceKey:l,targetKey:f,sourceVersion:o.version,targetVersion:o.version,sourceRevision:s,targetRevision:s,isDeleted:!0},this.#i,this.#s)}).filter(n=>n!==null));return await p(r.flat(),m,async o=>this.#r.upsertEntityRelation(o)),!0}}export{de as EntitiesWriteRepository};
@@ -2,7 +2,7 @@ import type { DatabaseClient } from '../../../../../providers/database/client.js
2
2
  export declare class EntityAttributesWriteRepository {
3
3
  #private;
4
4
  constructor(db: DatabaseClient);
5
- upsertEntityAttributes({ entityKey, rbacTeams, organizationId, projectId }: {
5
+ upsertEntityAttributes({ entityKey, rbacTeams, organizationId, projectId, }: {
6
6
  entityKey: string;
7
7
  rbacTeams: string[];
8
8
  organizationId: string;
@@ -13,7 +13,7 @@ export declare class RelationsReadRepository {
13
13
  direction: 'outgoing' | 'incoming';
14
14
  priority: number;
15
15
  }[]>;
16
- getRelatedEntities({ key, paginationParams, rbacTeams, excludedTypes, excludedEntities }: {
16
+ getRelatedEntities({ key, paginationParams, rbacTeams, excludedTypes, excludedEntities, }: {
17
17
  key: string;
18
18
  paginationParams: PaginationParams;
19
19
  rbacTeams?: string[];
@@ -5,7 +5,9 @@ import type { FileType } from '../../../../../persistence/file-hashes/types.js';
5
5
  import type { HashManager } from '../../../utils/hash-manager.js';
6
6
  import type { BaseApiEntitiesExtractorParams, SpecType } from '../../../types/extractors.js';
7
7
  import type { EntityDtoSchema } from '../../../schemas/dto-schemas.js';
8
- export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition extends Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'>> implements BaseEntitiesExtractor {
8
+ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition extends Pick<FileInfo, 'realRelativePath' | 'relativePath' | 'isVirtual' | 'hash'> & {
9
+ definition?: unknown;
10
+ }> implements BaseEntitiesExtractor {
9
11
  #private;
10
12
  protected type: 'api-description';
11
13
  protected specType: SpecType;
@@ -16,6 +18,7 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
16
18
  protected fileHashManager: HashManager;
17
19
  protected entitySources: Record<string, string>;
18
20
  constructor(specType: SpecType, params: BaseApiEntitiesExtractorParams);
21
+ protected getDescriptionHash(description: BundledApiDefinition): string | undefined;
19
22
  extract(): Promise<void>;
20
23
  protected validateEntityRelationFileSchema(relation: unknown): void;
21
24
  protected getRbacTeamsForDefinition(relativePath: string): string[];
@@ -26,7 +29,7 @@ export declare abstract class BaseApiEntitiesExtractor<BundledApiDefinition exte
26
29
  * @param customKey - Optional custom key from x-redocly-catalog-key
27
30
  * @param extensionPattern - Optional regex to strip file extension (default: any extension)
28
31
  */
29
- protected resolveEntityKey({ realRelativePath, customKey, extensionPattern }: {
32
+ protected resolveEntityKey({ realRelativePath, customKey, extensionPattern, }: {
30
33
  realRelativePath: string;
31
34
  customKey?: string | null;
32
35
  extensionPattern?: RegExp;
@@ -1 +1 @@
1
- import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as F}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as S}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as D}from"../../../utils/ajv-validator.js";const H=15,C=200,O=500;class z{type="api-description";specType;fileType;actions;context;catalogEntitiesService;fileHashManager;entitySources={};#e;constructor(i,e){this.specType=i,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 i=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),i.length&&p.addExtractor(this.specType);const a=this.#s(i),t={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},o=[],r=new Set;await w(Array.from(a.values()),H,async c=>{for(const{description:s,version:l}of c)try{const n=s.hash;if(!n)continue;r.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),E=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:E});if(!(f!==null)){t.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&t[f]++,f==="fileHashMismatch"&&h&&o.length<3&&o.push({path:s.realRelativePath,stored:h.hash,incoming:n});const d=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(s.realRelativePath);await this.#a(d);const y=new Date().toISOString();await this.processApiDescription(s,y,l,d),(m||E||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#r(d,s.realRelativePath,y,n),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.OUTDATED),p.markFileHashPendingConfirmation({fileType:this.fileType,filePath:s.realRelativePath,hash:n})}catch(n){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${s.realRelativePath}`),this.context.logger.warn(n)}}),await this.#o(r)}#i({fileHashChanged:i,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return i?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async i=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(i).map(e=>e.split(":")[0])}),i.clear())};#t=async i=>{let e=0,a=0;for(;;){const t=await this.catalogEntitiesService.getEntities({paginationParams:{limit:O,filter:i}});if(!t||t.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:t.items.map(({id:o})=>o)}),e+=t.items.length,a+=1}return{total:e,pages:a}};#s(i){const e=new Map;for(const a of i)if(!(a.isVirtual||!a.hash))try{const t=this.#n(a),o=this.mapApiDescriptionToEntity(a,t),r=e.get(o.key)??[];r.push({description:a,version:t}),e.set(o.key,r)}catch(t){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(t)}return e}#o=async i=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!i.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const t=a.map(({filePath:l})=>l),{total:o,pages:r}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:t},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:t});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${t.length} currentRevisionsDeleted=${o} currentPages=${r} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${t.slice(0,3).join(", ")}${t.length>3?`, +${t.length-3} more`:""}`)};#r=async(i,e,a,t)=>{if(i.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const o=Array.from(i).map(r=>{const[c,s]=r.split(":");return{key:c,version:s}});for(let r=0;r<o.length;r+=C){const c=o.slice(r,r+C),s=Array.from(new Set(c.map(({key:n})=>n))),l=c.map(({key:n,version:h})=>({op:A.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:h}]}));await this.catalogEntitiesService.softDeleteEntitiesWithRelations({revision:a,fileHash:t,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:s},{op:A.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e},{field:"is_current",operator:"equal",value:!0}]}})}};#n(i){const e=i.document?.info?.version??i.definition?.info?.version??null,a=S(e,i.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(i){D(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(i)}getRbacTeamsForDefinition(i){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(i);return F(a||{fsPath:i},e||{})}resolveEntityKey({realRelativePath:i,customKey:e,extensionPattern:a}){const t=this.#l(i,a);return typeof e=="string"&&e.trim()?R(e.trim()):t}#l(i,e){let t=_(i);for(;/^@[^/]+\//.test(t);)t=t.replace(/^@[^/]+\//,"");t=t.replace(/\/@[^/]+/g,"");const o=e?t.replace(e,""):t.replace(/\.[^.]+$/,"");return R(o.replace(/[\\/]/g,"-"))}}export{z as BaseApiEntitiesExtractor};
1
+ import{entityRelationFileSchema as P}from"@redocly/config";import{removeLeadingSlash as _}from"@redocly/theme/core/utils";import{sha1 as S}from"../../../../../utils/crypto/sha1.js";import{toKebabCase as R}from"../../../../../../utils/string/to-kebab-case.js";import{FileHashStatus as g}from"../../../../../persistence/file-hashes/types.js";import{promiseMapLimit as w}from"../../../../../utils/async/promise-map-limit.js";import{OPERATORS as A}from"../../../../../providers/database/pagination/constants.js";import{VERSION_NOT_SPECIFIED as T}from"@redocly/theme/core/constants";import{getRbacTeamsListForResource as D}from"../../../../../utils/rbac.js";import{envConfig as u}from"../../../../../config/env-config.js";import{resolveEntityVersion as F}from"../../../utils/resolve-entity-version.js";import{catalogDataCollector as p}from"../../../utils/catalog-data-collector.js";import{createValidator as H}from"../../../utils/ajv-validator.js";const O=15,C=200,k=500;class Y{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}getDescriptionHash(t){return t.definition===void 0?t.hash:S(JSON.stringify(t.definition))}async extract(){const t=await this.loadApiDescriptions(),e=await this.fileHashManager.getStatusSnapshot(this.fileType);await this.fileHashManager.markAllAsOutdated(this.fileType),t.length&&p.addExtractor(this.specType);const a=this.#s(t),i={skipped:0,fileHashMissing:0,fileHashMismatch:0,shouldCalculateFlag:0,forceRevalidateFlag:0,previouslyUnconfirmed:0},o=[],r=new Set;await w(Array.from(a.values()),O,async c=>{for(const{description:s,version:l}of c)try{const n=this.getDescriptionHash(s);if(!n)continue;r.add(s.realRelativePath);const h=await this.fileHashManager.getByPath(s.realRelativePath),m=h?.hash!==n,v=e.get(s.realRelativePath),y=v!==void 0&&v!==g.UP_TO_DATE,f=this.#i({fileHashChanged:m,hasExistingHashRecord:!!h,previouslyUnconfirmed:y});if(!(f!==null)){i.skipped++,p.increaseSkippedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.UP_TO_DATE);continue}f&&i[f]++,f==="fileHashMismatch"&&h&&o.length<3&&o.push({path:s.realRelativePath,stored:h.hash,incoming:n});const d=await this.catalogEntitiesService.getEntityKeysAndVersionsBySourceFile(s.realRelativePath);await this.#a(d);const E=new Date().toISOString();await this.processApiDescription(s,E,l,d),(m||y||u.FORCE_CATALOG_CACHE_REVALIDATE)&&p.markSourceFileAsChanged(s.realRelativePath),await this.#r(d,s.realRelativePath,E,n),p.increaseProcessedFilesCount(),await this.fileHashManager.upsert(this.fileType,s.realRelativePath,n,g.OUTDATED),p.markFileHashPendingConfirmation({fileType:this.fileType,filePath:s.realRelativePath,hash:n})}catch(n){this.context.logger.warn(`Error extracting entities from ${this.specType} description: ${s.realRelativePath}`),this.context.logger.warn(n)}}),await this.#o(r)}#i({fileHashChanged:t,hasExistingHashRecord:e,previouslyUnconfirmed:a}){return t?e?"fileHashMismatch":"fileHashMissing":a?"previouslyUnconfirmed":this.#e?"shouldCalculateFlag":u.FORCE_CATALOG_CACHE_REVALIDATE?"forceRevalidateFlag":null}#a=async t=>{u.FORCE_CATALOG_CACHE_REVALIDATE&&(await this.catalogEntitiesService.deleteEntities({field:"key",operator:"in",value:Array.from(t).map(e=>e.split(":")[0])}),t.clear())};#t=async t=>{let e=0,a=0;for(;;){const i=await this.catalogEntitiesService.getEntities({paginationParams:{limit:k,filter:t}});if(!i||i.items.length===0)break;await this.catalogEntitiesService.deleteEntities({field:"id",operator:"in",value:i.items.map(({id:o})=>o)}),e+=i.items.length,a+=1}return{total:e,pages:a}};#s(t){const e=new Map;for(const a of t)if(!(a.isVirtual||!a.hash))try{const i=this.#n(a),o=this.mapApiDescriptionToEntity(a,i),r=e.get(o.key)??[];r.push({description:a,version:i}),e.set(o.key,r)}catch(i){this.context.logger.warn(`Error resolving entity key for ${this.specType} description (skipping): ${a.realRelativePath}`),this.context.logger.warn(i)}return e}#o=async t=>{const e=await this.fileHashManager.getAllOutdated(this.fileType);if(!e||e.length===0)return;const a=e.filter(({filePath:l})=>!t.has(l));if(a.length===0)return;a.forEach(({filePath:l})=>{p.markSourceFileAsRemoved(l)});const i=a.map(({filePath:l})=>l),{total:o,pages:r}=await this.#t({op:"AND",conditions:[{field:"source_file",operator:"in",value:i},{field:"is_current",operator:"equal",value:!0}]}),{total:c,pages:s}=await this.#t({field:"source_file",operator:"in",value:i});this.context.logger.info(`[${this.specType}] removed-files cleanup: files=${i.length} currentRevisionsDeleted=${o} currentPages=${r} orphanRevisionsDeleted=${c} orphanPages=${s} removedFiles=${i.slice(0,3).join(", ")}${i.length>3?`, +${i.length-3} more`:""}`)};#r=async(t,e,a,i)=>{if(t.size===0||u.FORCE_CATALOG_CACHE_REVALIDATE)return;const o=Array.from(t).map(r=>{const[c,s]=r.split(":");return{key:c,version:s}});for(let r=0;r<o.length;r+=C){const c=o.slice(r,r+C),s=Array.from(new Set(c.map(({key:n})=>n))),l=c.map(({key:n,version:h})=>({op:A.AND,conditions:[{field:"key",operator:"equal",value:n},{field:"version",operator:"equal",value:h}]}));await this.catalogEntitiesService.softDeleteEntitiesWithRelations({revision:a,fileHash:i,filter:{op:"AND",conditions:[{field:"key",operator:"in",value:s},{op:A.OR,conditions:l},{field:"source",operator:"equal",value:"file"},{field:"source_file",operator:"equal",value:e},{field:"is_current",operator:"equal",value:!0}]}})}};#n(t){const e=t.document?.info?.version??t.definition?.info?.version??null,a=F(e,t.realRelativePath);return a.success?a.version??T:T}validateEntityRelationFileSchema(t){H(P,{errorPrefix:"Entity relation validation failed:",dataVar:"relation"})(t)}getRbacTeamsForDefinition(t){const e=this.actions.getConfig().access?.rbac,a=this.actions.getRouteByFsPath(t);return D(a||{fsPath:t},e||{})}resolveEntityKey({realRelativePath:t,customKey:e,extensionPattern:a}){const i=this.#l(t,a);return typeof e=="string"&&e.trim()?R(e.trim()):i}#l(t,e){let i=_(t);for(;/^@[^/]+\//.test(i);)i=i.replace(/^@[^/]+\//,"");i=i.replace(/\/@[^/]+/g,"");const o=e?i.replace(e,""):i.replace(/\.[^.]+$/,"");return R(o.replace(/[\\/]/g,"-"))}}export{Y as BaseApiEntitiesExtractor};
@@ -4,7 +4,7 @@ import type { CatalogEntitiesService } from '../../database/catalog-entities-ser
4
4
  import type { EntitiesCatalogConfig } from '@redocly/config';
5
5
  export declare class FsEntitiesExtractor {
6
6
  #private;
7
- constructor({ fileHashManager, context, catalogEntitiesService, catalogConfig, shouldCalculateEntities }: {
7
+ constructor({ fileHashManager, context, catalogEntitiesService, catalogConfig, shouldCalculateEntities, }: {
8
8
  fileHashManager: HashManager;
9
9
  context: LifecycleContext;
10
10
  catalogEntitiesService: CatalogEntitiesService;
@@ -1 +1 @@
1
- import{FileHashStatus as v,FileType as h}from"../../persistence/file-hashes/types.js";import{envConfig as C}from"../../config/env-config.js";import{CATALOG_BASE_SLUG as S}from"../../../constants/catalog-entities.js";import{telemetryTraceStep as k}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as f}from"./utils/catalog-data-collector.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as B,ENTITIES_MAP_GLOBAL_DATA_KEY as $}from"../../constants/plugins/catalog-entities.js";import{CacheService as z}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as O}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as _}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as Y}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as U}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as j}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as q}from"./database/catalog-entities-service.js";import{CatalogEntitiesPublisher as V}from"./database/catalog-entities-publisher.js";import{CatalogEntitiesRevisionsPruner as I}from"./database/catalog-entities-revisions-pruner.js";import{DEFAULT_MAX_ENTITY_REVISIONS as W}from"./database/consts.js";import{DatabaseConnectionFactory as J}from"../../providers/database/database-connection-factory.js";import{ArazzoEntitiesExtractor as X}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as Z}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as K}from"./utils/hash-manager.js";import{RbacConfigHashCache as Q}from"./utils/rbac-config-hash-cache.js";import{OpenApiEntitiesExtractor as ee}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const te="catalog-entity-template",ie="catalog-entity";let w=!0;async function ae(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(e,t){const s=await t.getConfig(),r=_(s.entitiesCatalog);if(!r.show)return;const{logger:n}=t,a=e.registerServerPropsGetter(ie,O("../get-server-props.js")),g=e.createTemplate(te,O("../template/index.js"));e.addRoute({duplicateInAllLocales:!0,slug:S,fsPath:"",templateId:g,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[a],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([P,m])=>!m?.hide)||[];l&&e.addRedirect(S,{type:302,to:`${S}/${l}`},{trackOriginalSource:!1}),n.info("Catalog Entities plugin finished")},async afterRoutesCreated(e,t){await k("build.plugin.catalog_entities",async s=>{const r=await t.getConfig(),n=_(r.entitiesCatalog);if(s?.setAttribute("config",JSON.stringify(n)),!n.show)return;const{logger:a}=t;f.resetForRun();const g=w&&C.isDevelopMode,l=await z.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),P=new Q(l),{rbacConfigChanged:m}=await P.syncAndDetectChange(r.access?.rbac??null),c=g||m,o=await q.getInstance({baseDbDir:e.serverOutDir,removeExisting:g,databaseType:"local",runWithPragmaWalWriteOptimization:!0}),T=await j.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),u=new K(T),F=[new Z({fileHashManager:u,context:t,catalogEntitiesService:o,catalogConfig:n,shouldCalculateEntities:c}),new ee({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.OPENAPI_DESCRIPTION,shouldCalculateEntities:c}),new Y({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:c}),new U({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.GRAPHQL_DESCRIPTION,shouldCalculateEntities:c}),new X({actions:e,context:t,catalogEntitiesService:o,fileHashManager:u,fileType:h.ARAZZO_DESCRIPTION,shouldCalculateEntities:c})];a.info("Starting entities extractors...");const R=a.startTiming();await o.transaction(async()=>{await Promise.all(F.map(async i=>i.extract()))});const N=o.getEntitySources();e.setGlobalData({[$]:N}),await l.deleteByNamespace(B),a.infoTime(R,"Entities extractors finished");const b=C.CATALOG_MAX_REVISIONS??W,d=await J.create({baseDbDir:e.serverOutDir,databaseType:"local"}),H=!C.isDevelopMode&&C.isProductionEnv;let E=[];if(H&&d&&b>0){const i=await I.pruneLocalRevisions({localConnection:d,maxRevisions:b});if(i.prunedEntities>0||i.prunedRelations>0){a.info(`Pruned entity revision history: entities=${i.prunedEntities} relations=${i.prunedRelations} files=${i.affectedSourceFiles.length} (keeping ${b} revisions per entity)`),E=i.affectedSourceFiles;for(const D of E)f.markSourceFileAsChanged(D)}}const{changedSourceFiles:L,removedSourceFiles:A}=f.getPublishDelta(),x=a.startTiming(),y=await V.publishFromLocalToRemote(m?{baseDbDir:e.serverOutDir}:{baseDbDir:e.serverOutDir,changedSourceFiles:L,removedSourceFiles:A});if(y.published&&a.infoTime(x,"Entities published to the database"),y.shouldFinalizeFileHashes){A.length&&await T.deleteFileHashes({op:"AND",conditions:[{field:"status",operator:"equal",value:v.OUTDATED},{field:"file_path",operator:"in",value:A}]});const i=f.getFileHashConfirmations();for(const{fileType:D,filePath:G,hash:M}of i)await T.upsertFileHash({fileType:D,filePath:G,hash:M,status:v.UP_TO_DATE});y.published&&E.length&&d&&await I.confirmPrunedFiles({localConnection:d,sourceFiles:E})}else a.warn("Skipped file_hashes finalization because remote catalog publish connection is unavailable; next build will retry.");const p=await f.getCatalogEntitiesData(o);s?.setAttribute("totalEntities",p.totalEntitiesCount),s?.setAttribute("entitiesCountByType",JSON.stringify(p.countOfEntitiesByType)),s?.setAttribute("totalFilesSkippedByHash",p.totalFilesSkippedByHash),s?.setAttribute("totalProcessedFiles",p.totalProcessedFiles),s?.setAttribute("extractors",p.extractors),w=!1})}}}var ve=ae;export{ae as catalogEntitiesPlugin,ve as default};
1
+ import{FileHashStatus as v,FileType as h}from"../../persistence/file-hashes/types.js";import{envConfig as C}from"../../config/env-config.js";import{CATALOG_BASE_SLUG as S}from"../../../constants/catalog-entities.js";import{telemetryTraceStep as $}from"../../../cli/telemetry/helpers/trace-step.js";import{catalogDataCollector as f}from"./utils/catalog-data-collector.js";import{CATALOG_FILTERS_CACHE_NAMESPACE as k,ENTITIES_MAP_GLOBAL_DATA_KEY as B}from"../../constants/plugins/catalog-entities.js";import{CacheService as z}from"../../persistence/cache/services/cache-service.js";import{getTemplatePath as R}from"./utils/get-template-path.js";import{getCompleteCatalogConfig as O}from"./get-complete-catalog-config.js";import{AsyncApiEntitiesExtractor as Y}from"./extensions/extractors/api-description/asyncapi-entities-extractor.js";import{GraphqlEntitiesExtractor as U}from"./extensions/extractors/api-description/graphql-entities-extractor.js";import{FileHashesService as j}from"../../persistence/file-hashes/services/file-hashes-service.js";import{CatalogEntitiesService as q}from"./database/catalog-entities-service.js";import{CatalogEntitiesPublisher as V}from"./database/catalog-entities-publisher.js";import{CatalogEntitiesRevisionsPruner as _}from"./database/catalog-entities-revisions-pruner.js";import{DEFAULT_MAX_ENTITY_REVISIONS as W}from"./database/consts.js";import{DatabaseConnectionFactory as J}from"../../providers/database/database-connection-factory.js";import{ArazzoEntitiesExtractor as X}from"./extensions/extractors/api-description/arazzo-entities-extractor.js";import{FsEntitiesExtractor as Z}from"./extensions/extractors/fs-entities-extractor.js";import{HashManager as K}from"./utils/hash-manager.js";import{RbacConfigHashCache as Q}from"./utils/rbac-config-hash-cache.js";import{OpenApiEntitiesExtractor as ee}from"./extensions/extractors/api-description/openapi-entities-extractor.js";const te="catalog-entity-template",ie="catalog-entity";let I=!0;async function ae(){return{id:"CatalogEntities",requiredEntitlements:["catalog"],async processContent(e,i){const s=await i.getConfig(),r=O(s.entitiesCatalog);if(!r.show)return;const{logger:n}=i,a=e.registerServerPropsGetter(ie,R("../get-server-props.js")),g=e.createTemplate(te,R("../template/index.js"));e.addRoute({duplicateInAllLocales:!0,slug:S,fsPath:"",templateId:g,excludeFromSidebar:!0,hasClientRoutes:!0,serverPropsGetterIds:[a],getNavText:()=>Promise.resolve("Catalog"),getStaticData:async()=>({props:{catalogConfig:r}})});const[l]=Object.entries(r.catalogs??{}).find(([P,m])=>!m?.hide)||[];l&&e.addRedirect(S,{type:302,to:`${S}/${l}`},{trackOriginalSource:!1}),n.info("Catalog Entities plugin finished")},async afterRoutesCreated(e,i){await $("build.plugin.catalog_entities",async s=>{const r=await i.getConfig(),n=O(r.entitiesCatalog);if(s?.setAttribute("config",JSON.stringify(n)),!n.show)return;const{logger:a}=i;f.resetForRun();const g=I&&C.isDevelopMode,l=await z.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),P=new Q(l),{rbacConfigChanged:m}=await P.syncAndDetectChange(r.access?.rbac??null),c=g||m,o=await q.getInstance({baseDbDir:e.serverOutDir,removeExisting:g,databaseType:"local",runWithPragmaWalWriteOptimization:!0}),T=await j.getInstance({baseDbDir:e.serverOutDir,databaseType:"local"}),u=new K(T),w=[new Z({fileHashManager:u,context:i,catalogEntitiesService:o,catalogConfig:n,shouldCalculateEntities:c}),new ee({actions:e,context:i,catalogEntitiesService:o,fileHashManager:u,fileType:h.OPENAPI_DESCRIPTION,shouldCalculateEntities:c}),new Y({actions:e,context:i,catalogEntitiesService:o,fileHashManager:u,fileType:h.ASYNCAPI_DESCRIPTION,shouldCalculateEntities:c}),new U({actions:e,context:i,catalogEntitiesService:o,fileHashManager:u,fileType:h.GRAPHQL_DESCRIPTION,shouldCalculateEntities:c}),new X({actions:e,context:i,catalogEntitiesService:o,fileHashManager:u,fileType:h.ARAZZO_DESCRIPTION,shouldCalculateEntities:c})];a.info("Starting entities extractors...");const F=a.startTiming();await o.transaction(async()=>{await Promise.all(w.map(async t=>t.extract()))});const H=o.getEntitySources();e.setGlobalData({[B]:H}),await l.deleteByNamespace(k),a.infoTime(F,"Entities extractors finished");const y=C.CATALOG_MAX_REVISIONS??W,d=await J.create({baseDbDir:e.serverOutDir,databaseType:"local"}),N=!C.isDevelopMode&&C.isProductionEnv;let E=[];if(N&&d&&y>0){const t=await _.pruneLocalRevisions({localConnection:d,maxRevisions:y});if(t.prunedEntities>0||t.prunedRelations>0||t.legacyRelationsHealed>0||t.legacyRelationsDeleted>0){a.info(`Pruned entity revision history: entities=${t.prunedEntities} relations=${t.prunedRelations} legacyHealed=${t.legacyRelationsHealed} legacyDeleted=${t.legacyRelationsDeleted} files=${t.affectedSourceFiles.length} (keeping ${y} revisions per entity)`),E=t.affectedSourceFiles;for(const D of E)f.markSourceFileAsChanged(D)}}const{changedSourceFiles:L,removedSourceFiles:b}=f.getPublishDelta(),x=a.startTiming(),A=await V.publishFromLocalToRemote(m?{baseDbDir:e.serverOutDir}:{baseDbDir:e.serverOutDir,changedSourceFiles:L,removedSourceFiles:b});if(A.published&&a.infoTime(x,"Entities published to the database"),A.shouldFinalizeFileHashes){b.length&&await T.deleteFileHashes({op:"AND",conditions:[{field:"status",operator:"equal",value:v.OUTDATED},{field:"file_path",operator:"in",value:b}]});const t=f.getFileHashConfirmations();for(const{fileType:D,filePath:G,hash:M}of t)await T.upsertFileHash({fileType:D,filePath:G,hash:M,status:v.UP_TO_DATE});A.published&&E.length&&d&&await _.confirmPrunedFiles({localConnection:d,sourceFiles:E})}else a.warn("Skipped file_hashes finalization because remote catalog publish connection is unavailable; next build will retry.");const p=await f.getCatalogEntitiesData(o);s?.setAttribute("totalEntities",p.totalEntitiesCount),s?.setAttribute("entitiesCountByType",JSON.stringify(p.countOfEntitiesByType)),s?.setAttribute("totalFilesSkippedByHash",p.totalFilesSkippedByHash),s?.setAttribute("totalProcessedFiles",p.totalProcessedFiles),s?.setAttribute("extractors",p.extractors),I=!1})}}}var ve=ae;export{ae as catalogEntitiesPlugin,ve as default};
@@ -1,5 +1,5 @@
1
1
  import type { RedoclyConfig } from '@redocly/config';
2
- export declare function getNotAccessibleCatalogResources({ rbacConfig, currentRbacTeams, accessLevel }: {
2
+ export declare function getNotAccessibleCatalogResources({ rbacConfig, currentRbacTeams, accessLevel, }: {
3
3
  rbacConfig: RedoclyConfig['rbac'];
4
4
  currentRbacTeams: string[];
5
5
  accessLevel?: 'READ' | 'WRITE';
@@ -4,7 +4,7 @@ import type { Logger } from '../../../tools/notifiers/logger.js';
4
4
  export declare class OpenapiComponentContentExtractor {
5
5
  #private;
6
6
  constructor(logger: Logger);
7
- extract({ component, definition, openapiOperation, visitedRefs }: {
7
+ extract({ component, definition, openapiOperation, visitedRefs, }: {
8
8
  component: OpenAPIResponse | OpenAPIRequestBody;
9
9
  definition: BundledDefinition;
10
10
  openapiOperation: OpenAPIOperation;
@@ -1,3 +1,3 @@
1
1
  import type { LifecyclePluginInstance, PluginOptions } from '../../types';
2
- export declare function apiKeyMgmtPlugin({ contentDir: _ }: PluginOptions): Promise<LifecyclePluginInstance>;
2
+ export declare function apiKeyMgmtPlugin({ contentDir: _, }: PluginOptions): Promise<LifecyclePluginInstance>;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { Credential } from '../../api/types';
3
- export default function RevokeAPIKey({ apiKey: { expiresAt, clientId, clientSecret, id: apiKeyId } }: {
3
+ export default function RevokeAPIKey({ apiKey: { expiresAt, clientId, clientSecret, id: apiKeyId }, }: {
4
4
  apiKey: Credential;
5
5
  }): React.JSX.Element;
6
6
  export declare const ButtonsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { Credential } from '../../api/types';
3
- export default function RollAPIKey({ apiKey: { expiresAt, clientId, clientSecret, id: apiKeyId } }: {
3
+ export default function RollAPIKey({ apiKey: { expiresAt, clientId, clientSecret, id: apiKeyId }, }: {
4
4
  apiKey: Credential;
5
5
  }): React.JSX.Element;
6
6
  export declare const ButtonsContainer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
@@ -8,7 +8,7 @@ type GetSearchDocumentParams = {
8
8
  items?: Set<string>;
9
9
  };
10
10
  type GetSearchDocumentReturnType = GraphQLSearchDocument | (GraphQLSearchDocument | undefined)[] | undefined;
11
- export declare function getSearchDocument({ label, groupName, store, isTypeGroup, items }: GetSearchDocumentParams): GetSearchDocumentReturnType;
11
+ export declare function getSearchDocument({ label, groupName, store, isTypeGroup, items, }: GetSearchDocumentParams): GetSearchDocumentReturnType;
12
12
  export declare function convertDocumentToMarkdown(document: GraphQLSearchDocument, baseLevel?: number): string;
13
13
  export {};
14
14
  //# sourceMappingURL=utils.d.ts.map
@@ -24,7 +24,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
24
24
  };
25
25
  }>>): import("@markdoc/markdoc").MaybePromise<import("@markdoc/markdoc").RenderableTreeNodes>;
26
26
  validate?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
27
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
27
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
28
28
  tags: Record<string, import("@markdoc/markdoc").Schema>;
29
29
  variables: Record<string, any>;
30
30
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -45,7 +45,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
45
45
  selfClosing?: boolean;
46
46
  inline?: boolean;
47
47
  transform?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
48
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
48
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
49
49
  tags: Record<string, import("@markdoc/markdoc").Schema>;
50
50
  variables: Record<string, any>;
51
51
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -57,7 +57,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
57
57
  };
58
58
  }>>): import("@markdoc/markdoc").MaybePromise<import("@markdoc/markdoc").RenderableTreeNodes>;
59
59
  validate?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
60
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
60
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
61
61
  tags: Record<string, import("@markdoc/markdoc").Schema>;
62
62
  variables: Record<string, any>;
63
63
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -78,7 +78,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
78
78
  selfClosing?: boolean;
79
79
  inline?: boolean;
80
80
  transform?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
81
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
81
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
82
82
  tags: Record<string, import("@markdoc/markdoc").Schema>;
83
83
  variables: Record<string, any>;
84
84
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -90,7 +90,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
90
90
  };
91
91
  }>>): import("@markdoc/markdoc").MaybePromise<import("@markdoc/markdoc").RenderableTreeNodes>;
92
92
  validate?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
93
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
93
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
94
94
  tags: Record<string, import("@markdoc/markdoc").Schema>;
95
95
  variables: Record<string, any>;
96
96
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -110,7 +110,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
110
110
  selfClosing?: boolean;
111
111
  inline?: boolean;
112
112
  transform?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
113
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
113
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
114
114
  tags: Record<string, import("@markdoc/markdoc").Schema>;
115
115
  variables: Record<string, any>;
116
116
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -122,7 +122,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
122
122
  };
123
123
  }>>): import("@markdoc/markdoc").MaybePromise<import("@markdoc/markdoc").RenderableTreeNodes>;
124
124
  validate?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
125
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
125
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
126
126
  tags: Record<string, import("@markdoc/markdoc").Schema>;
127
127
  variables: Record<string, any>;
128
128
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -144,7 +144,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
144
144
  selfClosing?: boolean;
145
145
  inline?: boolean;
146
146
  transform?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
147
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
147
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
148
148
  tags: Record<string, import("@markdoc/markdoc").Schema>;
149
149
  variables: Record<string, any>;
150
150
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -156,7 +156,7 @@ export declare function getMarkdocOptions(serverOutDir?: string, _templateId?: s
156
156
  };
157
157
  }>>): import("@markdoc/markdoc").MaybePromise<import("@markdoc/markdoc").RenderableTreeNodes>;
158
158
  validate?(node: import("@markdoc/markdoc").Node, config: Readonly<Partial<{
159
- nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial</*elided*/ any>, string>>>;
159
+ nodes: Partial<Record<import("@markdoc/markdoc").NodeType, import("@markdoc/markdoc").Schema<Partial<any>, string>>>;
160
160
  tags: Record<string, import("@markdoc/markdoc").Schema>;
161
161
  variables: Record<string, any>;
162
162
  functions: Record<string, import("@markdoc/markdoc").ConfigFunction>;
@@ -4,6 +4,11 @@ export declare function getHeadingData(node: Tag | Node): {
4
4
  id: any;
5
5
  depth: any;
6
6
  } | undefined;
7
+ export declare function getNumberedItemHeadingData(node: Tag | Node): {
8
+ value: string;
9
+ id: any;
10
+ depth: any;
11
+ } | undefined;
7
12
  export declare function extractFirstHeading(ast: Node): undefined | string;
8
13
  export declare const EXIT: unique symbol;
9
14
  /**
@@ -1 +1 @@
1
- import{isNode as l}from"../../../../../markdoc/helpers/guards/is-node.js";import{isStringNode as s}from"../../../../../markdoc/helpers/guards/is-string-node.js";import{getNodeAttribute as c}from"../../../../../markdoc/helpers/get-node-attribute.js";import{getInnerText as a}from"../../../../../markdoc/helpers/get-inner-text.js";function p(t){const r=c(t,"level");if(r)return{value:a(t.children),id:c(t,"id"),depth:r}}function h(t){let r;return f(t,i=>{if(l(i)&&i.type==="heading")return r=p(i)?.value,o}),r}const o=Symbol("Exit visitor");function f(t,r){if(!t)return;const i=r(t);if(i===o)return i;for(const e of t.children){if(!e||s(e))continue;const n=f(e,r);if(n===o)return n}const u=t.slots||{};for(const e of Object.values(u)){if(!e||s(e))continue;const n=f(e,r);if(n===o)return n}}export{o as EXIT,h as extractFirstHeading,p as getHeadingData,f as visit};
1
+ import{isNode as l}from"../../../../../markdoc/helpers/guards/is-node.js";import{isStringNode as f}from"../../../../../markdoc/helpers/guards/is-string-node.js";import{getNodeAttribute as o}from"../../../../../markdoc/helpers/get-node-attribute.js";import{getInnerText as a}from"../../../../../markdoc/helpers/get-inner-text.js";function d(t){const e=o(t,"level");if(e)return{value:a(t.children),id:o(t,"id"),depth:e}}function x(t){const e=o(t,"headlineLevel"),r=o(t,"anchorId"),s=o(t,"headline");if(!(!e||!r||!Array.isArray(s)))return{value:a(s),id:r,depth:e}}function v(t){let e;return u(t,r=>{if(l(r)&&r.type==="heading")return e=d(r)?.value,c}),e}const c=Symbol("Exit visitor");function u(t,e){if(!t)return;const r=e(t);if(r===c)return r;for(const i of t.children){if(!i||f(i))continue;const n=u(i,e);if(n===c)return n}const s=t.slots||{};for(const i of Object.values(s)){if(!i||f(i))continue;const n=u(i,e);if(n===c)return n}}export{c as EXIT,v as extractFirstHeading,d as getHeadingData,x as getNumberedItemHeadingData,u as visit};
@@ -1 +1 @@
1
- import u from"@markdoc/markdoc";import{isTag as b}from"../../../markdoc/helpers/guards/is-tag.js";import{slugger as l}from"../../utils/index.js";import{getMarkdocOptions as f}from"./markdoc/markdoc-options.js";import{visit as h,getHeadingData as k}from"./markdoc/plugins/utils.js";import{renderDiagramsWithVariants as v}from"./markdoc/plugins/render-diagrams.js";import{deepStringify as y}from"./markdoc/utils/deep-stringify.js";import{stringifyTagChildrenObjects as D}from"./utils/stringify-tag-children-objects.js";async function _(d,a,p){const g=await f(p),i=[],t=[],s=y(a.variables?.pageProps),{headers:H,...c}=a.variables||{};l.reset();const o=u.transform(d,{...g,...a,variables:{...c,pageProps:s}});let m=0;h(o,r=>{if(b(r)){switch(r.name){case"Heading":r.attributes.__idx=m,m++;const n=k(r);n&&i.push(n);break;case"Diagram":t.push({tag:r,input:{type:r.attributes.diagramType,source:r.attributes.diagramSource}});break}D(r)}});const e=await v(t.map(r=>r.input));for(let r=0;r<t.length;r++)t[r].tag.attributes.diagramError=e[r].error,t[r].tag.attributes.diagramHtml=e[r].light,t[r].tag.attributes.diagramHtmlDark=e[r].dark;return{headings:i,renderableAst:o,pageProps:s}}export{_ as transformMdAst};
1
+ import b from"@markdoc/markdoc";import{isTag as f}from"../../../markdoc/helpers/guards/is-tag.js";import{slugger as l}from"../../utils/index.js";import{getMarkdocOptions as h}from"./markdoc/markdoc-options.js";import{visit as k,getHeadingData as D,getNumberedItemHeadingData as H}from"./markdoc/plugins/utils.js";import{renderDiagramsWithVariants as v}from"./markdoc/plugins/render-diagrams.js";import{deepStringify as y}from"./markdoc/utils/deep-stringify.js";import{stringifyTagChildrenObjects as T}from"./utils/stringify-tag-children-objects.js";async function _(p,t,g){const u=await h(g),e=[],a=[],s=y(t.variables?.pageProps),{headers:w,...c}=t.variables||{};l.reset();const o=b.transform(p,{...u,...t,variables:{...c,pageProps:s}});let m=0;k(o,r=>{if(f(r)){switch(r.name){case"Heading":r.attributes.__idx=m,m++;const n=D(r);n&&e.push(n);break;case"NumberedItem":const d=H(r);d&&e.push(d);break;case"Diagram":a.push({tag:r,input:{type:r.attributes.diagramType,source:r.attributes.diagramSource}});break}T(r)}});const i=await v(a.map(r=>r.input));for(let r=0;r<a.length;r++)a[r].tag.attributes.diagramError=i[r].error,a[r].tag.attributes.diagramHtml=i[r].light,a[r].tag.attributes.diagramHtmlDark=i[r].dark;return{headings:e,renderableAst:o,pageProps:s}}export{_ as transformMdAst};
@@ -9,5 +9,5 @@ export type ResolveMarkdownTemplateParams = {
9
9
  markdown?: MarkdownConfig;
10
10
  contentDir: string;
11
11
  };
12
- export declare function resolveMarkdownTemplate({ realRelativePath, frontmatter, markdown, contentDir }: ResolveMarkdownTemplateParams): ResolvedMarkdownTemplate | null;
12
+ export declare function resolveMarkdownTemplate({ realRelativePath, frontmatter, markdown, contentDir, }: ResolveMarkdownTemplateParams): ResolvedMarkdownTemplate | null;
13
13
  //# sourceMappingURL=resolve-markdown-template.d.ts.map
@@ -1,5 +1,7 @@
1
1
  import type { ApiFunctionsContext, ApiFunctionsUser } from '@redocly/config';
2
+ import type { Store } from '../../../store.js';
2
3
  export declare function shouldHandleMcpAuth(requiresLogin: boolean, rbacConfig?: Record<string, unknown>): boolean;
4
+ export declare function isMcpContentProtected(store: Store): boolean;
3
5
  export declare function handleMcpAuth(request: Request, context: ApiFunctionsContext): Promise<{
4
6
  isAuthenticated: boolean;
5
7
  isTokenValid?: boolean;
@@ -1 +1 @@
1
- import{extractTokenFromAuthHeader as u}from"../../../plugins/mcp/utils/jwt.js";import{getUserParamsFromCookies as d}from"../../../web-server/auth.js";import{ServerRoutes as l}from"../../../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as i,RBAC_ALL_OTHER_TEAMS as a}from"../../../../constants/common.js";import{withPathPrefix as h}from"@redocly/theme/core/utils";function c(e){return!e||typeof e!="object"||Object.keys(e).length===0?!1:!(e[i]&&e[i]!=="none"||e[a]&&e[a]!=="none")}function R(e,t){if(!t||Object.keys(t).length===0)return e;const r=t.content;if(r&&Object.keys(r).length>0&&Object.values(r).some(c))return!0;const o=t.teamFoldersBaseRoles;return c(o)?!0:e}async function O(e,t){const r=e.headers.get("Authorization");if(!r)return{isAuthenticated:!1};const o=u(r),s=t?.config?.ssoDirect||{},n=o?await d(s,{authorization:o}):{};return o&&n&&n.isAuthenticated?{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:n.teams||[],email:n.email||"",claims:n,isAuthenticated:!0,idpAccessToken:n.idpAccessToken||void 0,idpId:n.idpId||void 0},accessToken:o}:{isAuthenticated:!1,isTokenValid:!1}}function _(e){return e=e.replace(/^http:\/\//,"https://"),new Response(JSON.stringify({error:"unauthorized",message:"Authentication required"}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":`Bearer resource_metadata="${e}${l.MCP_OAUTH_PROTECTED_RESOURCE}${h("/mcp")}"`,"Access-Control-Allow-Origin":"*"}})}function g(){return new Response(JSON.stringify({error:"invalid_token",message:"Invalid or expired token"}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":'Bearer error="invalid_token", error_description="Invalid or expired token"',"Access-Control-Allow-Origin":"*"}})}export{g as constructInvalidTokenResponse,_ as constructUnauthorizedResponse,O as handleMcpAuth,R as shouldHandleMcpAuth};
1
+ import{extractTokenFromAuthHeader as u}from"../../../plugins/mcp/utils/jwt.js";import{getUserParamsFromCookies as d}from"../../../web-server/auth.js";import{ServerRoutes as l}from"../../../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as i,RBAC_ALL_OTHER_TEAMS as a}from"../../../../constants/common.js";import{withPathPrefix as h}from"@redocly/theme/core/utils";function c(e){return!e||typeof e!="object"||Object.keys(e).length===0?!1:!(e[i]&&e[i]!=="none"||e[a]&&e[a]!=="none")}function f(e,t){if(!t||Object.keys(t).length===0)return e;const r=t.content;if(r&&Object.keys(r).length>0&&Object.values(r).some(c))return!0;const o=t.teamFoldersBaseRoles;return c(o)?!0:e}function O(e){const t=e.getConfig().access;return f(!!t?.requiresLogin,t?.rbac||{})}async function _(e,t){const r=e.headers.get("Authorization");if(!r)return{isAuthenticated:!1};const o=u(r),s=t?.config?.ssoDirect||{},n=o?await d(s,{authorization:o}):{};return o&&n&&n.isAuthenticated?{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:n.teams||[],email:n.email||"",claims:n,isAuthenticated:!0,idpAccessToken:n.idpAccessToken||void 0,idpId:n.idpId||void 0},accessToken:o}:{isAuthenticated:!1,isTokenValid:!1}}function g(e){return e=e.replace(/^http:\/\//,"https://"),new Response(JSON.stringify({error:"unauthorized",message:"Authentication required"}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":`Bearer resource_metadata="${e}${l.MCP_OAUTH_PROTECTED_RESOURCE}${h("/mcp")}"`,"Access-Control-Allow-Origin":"*"}})}function x(){return new Response(JSON.stringify({error:"invalid_token",message:"Invalid or expired token"}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":'Bearer error="invalid_token", error_description="Invalid or expired token"',"Access-Control-Allow-Origin":"*"}})}export{x as constructInvalidTokenResponse,g as constructUnauthorizedResponse,_ as handleMcpAuth,O as isMcpContentProtected,f as shouldHandleMcpAuth};
@@ -1,4 +1,4 @@
1
- const t="Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).";function o(e){return["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The only extra globals are `tools` and `fetch` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs (every tool name is listed in the `describe-tools` input schema / description).","2. Call `describe-tools` with those names to get their exact TypeScript signatures. NEVER call `execute` with guessed method names, parameter names, or enum values.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs.","",...e?["Example - list the Billing API endpoints and call one of them:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const ep = endpoints.find((e) => e.method === 'POST' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: items[0].name, path: ep.path, method: ep.method });","const url = (info.servers?.[0]?.url ?? '') + ep.path;","try {"," const res = await fetch(url, { method: 'POST', body: JSON.stringify({ /* fields from info */ }) });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"]:["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: items[0].name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"]].join(`
1
+ const t="Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).";function o(e){return["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The only extra globals are `tools` and `fetch` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs (every tool name is listed in the `describe-tools` input schema / description).","2. Call `describe-tools` with those names to get their exact TypeScript signatures - inputs AND result shapes. NEVER call `execute` with guessed method names, parameter names, enum values, or result field names: read fields off the declared return types, not from assumptions.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs.","",...e?["Example - list the Billing API endpoints and call one of them:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const ep = endpoints.find((e) => e.method === 'POST' && e.path.includes('invoices'));","const info = await tools.getEndpointInfo({ name: items[0].name, path: ep.path, method: ep.method });","const url = (info.servers?.[0]?.url ?? '') + ep.path;","try {"," const res = await fetch(url, { method: 'POST', body: JSON.stringify({ /* fields from info */ }) });"," return res.ok ? await res.json() : { status: res.status, error: await res.text() };","} catch (error) {"," return { error: error instanceof Error ? error.message : String(error), endpointId: info };","}","```"]:["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const { endpoints } = await tools.getEndpoints({ name: items[0].name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: items[0].name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"]].join(`
2
2
  `)}const s=["Get the exact TypeScript signatures of the sandbox tools available to `execute`.","Analyze the user request first, then pass `tools` with only the tool names the request needs (every name is listed in this input schema / description); omit `tools` only when you cannot tell which tools apply.","Always call this before your first `execute` and never guess signatures. Request every tool the task may need in ONE call instead of calling this repeatedly."].join(`
3
3
  `);function n(e){return["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through two tools:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with only the tool names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",e?"The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs.":""].join(`
4
4
  `)}const i="Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.";export{s as DESCRIBE_TOOLS_DESCRIPTION,t as EXECUTE_ARGS_NOTE,i as USAGE_NOTES,n as buildCodeModeInstructions,o as buildExecuteDescription};
@@ -1 +1 @@
1
- import{shouldHandleMcpAuth as m}from"../auth/auth-handlers.js";import{GRAPHQL_TYPE_KINDS as o}from"./tools/graphql/types.js";const p=["GET","POST","PUT","DELETE","PATCH","OPTIONS","HEAD","TRACE"],t={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},d={codemodeType:"OpenApiDocument"},h={codemodeType:"OpenApiOperation & { path: string; method: string }"},y={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},g={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p,...p.map(e=>e.toLowerCase())],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},f={type:"object",required:[],additionalProperties:!1,properties:{}};function q(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:y,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:r}}},...n}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:t,description:t,security:s}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:g,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:h,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:l,security:s}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:d}}},P(e.products,e.locales)];return m(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:f,annotations:{title:"Who Am I",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.hasGraphqlApis&&i.push(...L()),i}const b={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},S={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:"Optional: return only a single category of schema members",enum:[...o],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},H={type:"object",required:["name","type"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},v={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function L(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:b,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t}}},...n}}},{name:"get-graphql-type-list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (member-name substring, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema.',schema:S,annotations:{title:"Get GraphQL Type List",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:{type:"string"},items:{type:"array",items:{type:"object",properties:{kind:{type:"string",enum:o},name:{type:"string"},description:t,type:{type:"string"},args:{type:"string"}}}},...n}}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.",schema:H,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:v,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function P(e,i){const c=e&&e.length>0,u=i&&i.length>0;return{name:"search",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...c?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...u?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:i,nullable:!0}}:{}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{q as getDefaultToolSchemas};
1
+ import{shouldHandleMcpAuth as m}from"../auth/auth-handlers.js";import{GRAPHQL_TYPE_KINDS as o}from"./tools/graphql/types.js";import{OPERATION_METHODS as p}from"./tools/openapi/constants.js";const t={type:"string",nullable:!0},n={limit:{type:"number"},total:{type:"number"},page:{type:"number"},totalPages:{type:"number"}},r={codemodeType:"OpenApiServer[]"},s={codemodeType:"OpenApiSecurityRequirement[]"},l={codemodeType:"Record<string, OpenApiSecurityScheme>"},d={codemodeType:"OpenApiDocument"},h={codemodeType:"OpenApiOperation & { path: string; method: string }"},y={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300,nullable:!0}}},a={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},g={type:"object",required:["name","path","method"],additionalProperties:!1,properties:{name:{type:"string",description:"API name",minLength:1},path:{type:"string",description:"Endpoint path (e.g. /api/v1/users)",minLength:1},method:{type:"string",description:"HTTP method (GET, POST, PUT, DELETE, etc.)",enum:[...p.map(e=>e.toUpperCase()),...p],minLength:1},version:{type:"string",description:"API version (required when multiple APIs share the same name but differ by version)",nullable:!0}}},f={type:"object",required:[],additionalProperties:!1,properties:{}};function T(e){const i=[{name:"list-apis",description:"Lists available APIs with their context and purpose",schema:y,annotations:{title:"List APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t,version:t,servers:r}}},...n}}},{name:"get-endpoints",description:"Get all endpoints for a specific API",schema:a,annotations:{title:"Get Endpoints",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoints:{type:"array",items:{type:"object",properties:{path:{type:"string"},method:{type:"string"},summary:t,description:t,security:s}}}}}},{name:"get-endpoint-info",description:"Get comprehensive information about specific endpoint including parameters, security, and examples",schema:g,annotations:{title:"Get Endpoint Info",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},servers:r,endpoint:h,globalSecurity:s,securitySchemes:l}}},{name:"get-security-schemes",description:"Get the security schemes for a specific API",schema:a,annotations:{title:"Get Security Schemes",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:t,version:t,securitySchemes:l,security:s}}},{name:"get-full-api-description",description:"Get the complete OpenAPI description",schema:a,annotations:{title:"Get Full API Description",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{api:{type:"string"},version:{type:"string"},definition:d}}},P(e.products,e.locales)];return m(e.requiresLogin,e.rbac)&&i.push({name:"whoami",description:"Get information about the currently authenticated user",schema:f,annotations:{title:"Who Am I",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{email:{type:"string"},name:{type:"string"},subject:{type:"string"},clientId:{type:"string"},scope:{type:"string"},issuedAt:{type:"string"},expiresAt:{type:"string"}}}}),e.hasGraphqlApis&&i.push(...L()),i}const b={type:"object",required:[],additionalProperties:!1,properties:{filter:{type:"string",description:"GraphQL schema name (or part of it)",minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},S={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},kind:{type:"string",description:"Optional: return only a single category of schema members",enum:[...o],nullable:!0},filter:{type:"string",description:'Optional: only members whose name contains this substring (e.g. "book")',minLength:1,nullable:!0},referencesType:{type:"string",description:'Optional: only members that reference this type directly or transitively (via return, field, argument, union-member or input-field types). Finds cross-cutting members that never name it \u2014 e.g. referencesType "Book" surfaces a search query returning a union that includes Book.',minLength:1,nullable:!0},page:{type:"number",description:"Page number",minimum:1,default:1,nullable:!0},limit:{type:"number",description:"Number of results per page. Default is 300",minimum:1,default:300,nullable:!0}}},v={type:"object",required:["name","type"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1},type:{type:"string",description:"Name of the type, operation, or directive",minLength:1},includeReferencedTypes:{type:"boolean",description:"Also include the SDL of every type referenced transitively. Gives the whole subgraph at once, but can be large for highly-connected types.",default:!1,nullable:!0}}},H={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"GraphQL schema name",minLength:1}}};function L(){return[{name:"list-graphql-apis",description:"Lists available GraphQL schemas with their context and purpose",schema:b,annotations:{title:"List GraphQL APIs",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{items:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:t}}},...n}}},{name:"get-graphql-type-list",description:'List all operations and types in a GraphQL schema as a flat, paginated list. Each item is tagged with its kind (query, object, enum, \u2026) and carries a one-line description; operations also include their return type and argument signature \u2014 use it to decide which members to fetch in detail. Narrow the result with `kind` (one category), `filter` (member-name substring, e.g. "book"), or `referencesType` (only members that use a given type, directly or transitively) to explore a domain cheaply instead of pulling the full schema.',schema:S,annotations:{title:"Get GraphQL Type List",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"object",properties:{name:{type:"string"},items:{type:"array",items:{type:"object",properties:{kind:{type:"string",enum:o},name:{type:"string"},description:t,type:{type:"string"},args:{type:"string"}}}},...n}}},{name:"get-graphql-type",description:"Get the SDL for a single GraphQL type, operation (query/mutation/subscription field), or directive. Set includeReferencedTypes to also pull in every type it references transitively \u2014 the full structural subgraph in one call, ideal for complete exploration of an entity (e.g. Book and all the types it touches). That traversal only follows what the target depends on; to go the other direction and find the members that use a type, call get-graphql-type-list with `referencesType`.",schema:v,annotations:{title:"Get GraphQL Type",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}},{name:"get-graphql-schema",description:"Get the complete GraphQL schema as SDL \u2014 the whole type graph in one call. Returns everything, so it can be very large and token-expensive for big schemas; prefer get-graphql-type-list (filter/paginate) plus targeted get-graphql-type calls, and reach for this only for small schemas or when you truly need the full SDL.",schema:H,annotations:{title:"Get GraphQL Schema",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},outputSchema:{type:"string"}}]}function P(e,i){const c=e&&e.length>0,u=i&&i.length>0;return{name:"search",description:"Search across the documentation to fetch relevant content for a given query",schema:{type:"object",required:["query"],additionalProperties:!1,properties:{query:{type:"string",description:"Search query. Should be a single word or that phrase that is presented in a documentation.",minLength:1},...c?{product:{type:"string",description:"Optional product name to filter search results by specific product.",enum:e,nullable:!0}}:{},...u?{locale:{type:"string",description:"Optional locale code to filter search results by documentation language (e.g. 'en', 'ja'). Use the locale matching the language of the user's request. Defaults to the project's default locale.",enum:i,nullable:!0}}:{}}},annotations:{title:"Search Documentation",readOnlyHint:!0,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},outputSchema:{type:"string"}}}export{T as getDefaultToolSchemas};
@@ -0,0 +1,2 @@
1
+ export declare const OPERATION_METHODS: readonly ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace', 'query', 'x-query'];
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ const e=["get","put","post","delete","options","head","patch","trace","query","x-query"];export{e as OPERATION_METHODS};
@@ -1 +1 @@
1
- import{resolveParameters as h,resolveRequestBody as v,resolveResponses as x}from"../../utils.js";import{isMcpEndpoint as E}from"./utils.js";import{loadApiDescription as g}from"./load-api-description.js";import{checkEndpointAndDeleteXMcp as P}from"../../../utils/xmcp-utils.js";const S=async(s,i)=>{const{name:p,path:o,method:n,version:a}=s;let t;try{t=await g(p,i,a)}catch(y){return{content:[{type:"text",text:y.message}],isError:!0}}const c=o.startsWith("/")?o:`/${o}`,{title:d=""}=t.info||{},r=t.paths?.[c],m=n.toLowerCase();if(!r)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const e=r[m];if(!E(e)||!P(e,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const u=r?.parameters||[],l=e.parameters||[],f={...e,parameters:h({pathParams:u,opParams:l,definition:t}),requestBody:v(e.requestBody,t),responses:x(e.responses,t)};return{content:[{type:"text",text:JSON.stringify({api:d,version:t.info?.version||"",servers:t.servers||[],endpoint:{path:o,method:n.toUpperCase(),...f},globalSecurity:t.security||[],securitySchemes:t.components?.securitySchemes||[]},null,2)}]}};var M={"get-endpoint-info":S};export{M as default};
1
+ import{resolveParameters as h,resolveRequestBody as v,resolveResponses as x}from"../../utils.js";import{isMcpEndpoint as E}from"./utils.js";import{loadApiDescription as g}from"./load-api-description.js";import{checkEndpointAndDeleteXMcp as P}from"../../../utils/xmcp-utils.js";const S=async(s,i)=>{const{name:p,path:o,method:n,version:a}=s;let t;try{t=await g(p,i,a)}catch(y){return{content:[{type:"text",text:y.message}],isError:!0}}const c=o.startsWith("/")?o:`/${o}`,{title:d=""}=t.info||{},r=t.paths?.[c],m=n.toLowerCase();if(!r)return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const e=r[m];if(!E(e)||!P(e,"docs"))return{content:[{type:"text",text:"Endpoint not found"}],isError:!0};const u=r?.parameters||[],l=e.parameters||[],f={...e,parameters:h({pathParams:u,opParams:l,definition:t}),requestBody:v(e.requestBody,t),responses:x(e.responses,t)};return{content:[{type:"text",text:JSON.stringify({api:d,version:t.info?.version||"",servers:t.servers||[],endpoint:{path:o,method:n.toUpperCase(),...f},globalSecurity:t.security||[],securitySchemes:t.components?.securitySchemes||{}},null,2)}]}};var M={"get-endpoint-info":S};export{M as default};
@@ -1 +1 @@
1
- import{loadApiDescription as c}from"./load-api-description.js";const o=async(t,r)=>{const{name:s,version:i}=t;let e;try{e=await c(s,r,i)}catch(n){return{content:[{type:"text",text:n.message}],isError:!0}}return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||[],security:e.security||[]},null,2)}]}};var y={"get-security-schemes":o};export{y as default};
1
+ import{loadApiDescription as c}from"./load-api-description.js";const o=async(t,r)=>{const{name:s,version:i}=t;let e;try{e=await c(s,r,i)}catch(n){return{content:[{type:"text",text:n.message}],isError:!0}}return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||{},security:e.security||[]},null,2)}]}};var y={"get-security-schemes":o};export{y as default};