@redocly/revel 0.130.0-next.3 → 0.130.0-next.5

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 (86) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/prepare/copy-env-files.js +1 -1
  4. package/dist/client/app/hooks/useTelemetry.d.ts +2 -2
  5. package/dist/client/app/telemetry/index.d.ts +11 -1
  6. package/dist/client/app/telemetry/index.js +1 -1
  7. package/dist/constants/common.d.ts +1 -0
  8. package/dist/constants/common.js +1 -1
  9. package/dist/server/api-routes/execute-api-route.js +1 -1
  10. package/dist/server/constants/plugins/catalog-entities.d.ts +1 -0
  11. package/dist/server/constants/plugins/catalog-entities.js +1 -1
  12. package/dist/server/esbuild/esbuild.js +3 -3
  13. package/dist/server/node-bundle-entry.js +1 -1
  14. package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +1 -0
  15. package/dist/server/persistence/kv/repositories/kv-remote-repository.js +2 -1
  16. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +4 -4
  17. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +2 -2
  18. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  19. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  20. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  21. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  22. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.d.ts +54 -0
  23. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +1 -0
  24. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +9 -8
  25. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
  26. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.d.ts +9 -8
  27. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
  28. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.d.ts +9 -8
  29. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
  30. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.d.ts +9 -8
  31. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
  32. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +7 -13
  33. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  34. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +9 -6
  35. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.js +1 -1
  36. package/dist/server/plugins/mcp/docs-mcp/tools/search.d.ts +9 -2
  37. package/dist/server/plugins/mcp/docs-mcp/tools/search.js +1 -1
  38. package/dist/server/plugins/mcp/docs-mcp/tools/utils.d.ts +2 -1
  39. package/dist/server/plugins/mcp/docs-mcp/tools/utils.js +6 -6
  40. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.d.ts +9 -2
  41. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.js +1 -1
  42. package/dist/server/plugins/mcp/handlers/handle-mcp-request.d.ts +5 -0
  43. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -0
  44. package/dist/server/plugins/mcp/handlers/mcp-request-handler.d.ts +0 -1
  45. package/dist/server/plugins/mcp/handlers/mcp-request-handler.js +1 -1
  46. package/dist/server/plugins/mcp/types.d.ts +40 -0
  47. package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +3 -0
  48. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -0
  49. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.d.ts +12 -0
  50. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.js +1 -0
  51. package/dist/server/plugins/scorecards/database/scorecards-config-service.d.ts +11 -0
  52. package/dist/server/plugins/scorecards/database/scorecards-config-service.js +1 -0
  53. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.d.ts +2 -1
  54. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.js +1 -1
  55. package/dist/server/plugins/scorecards/workers/scorecards.d.ts +2 -0
  56. package/dist/server/plugins/scorecards/workers/scorecards.js +1 -1
  57. package/dist/server/plugins/sso/index.js +1 -1
  58. package/dist/server/providers/database/base-repository.d.ts +1 -0
  59. package/dist/server/providers/database/base-repository.js +1 -1
  60. package/dist/server/providers/database/database-connection-factory.js +1 -1
  61. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.d.ts +24 -18
  62. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.js +1 -1
  63. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.js +1 -1
  64. package/dist/server/store.d.ts +3 -1
  65. package/dist/server/store.js +1 -1
  66. package/dist/server/types/plugins/common.d.ts +3 -1
  67. package/dist/server/utils/envs/load-env-variables.d.ts +1 -1
  68. package/dist/server/utils/envs/load-env-variables.js +1 -1
  69. package/dist/server/utils/envs/sanitize-branch-name.d.ts +6 -0
  70. package/dist/server/utils/envs/sanitize-branch-name.js +1 -0
  71. package/dist/server/utils/lifecycle-hooks.js +1 -1
  72. package/dist/server/utils/time/with-timestamp.d.ts +42 -10
  73. package/dist/server/utils/time/with-timestamp.js +1 -1
  74. package/dist/server/web-server/dev-server.js +1 -1
  75. package/dist/server/web-server/handle-api-route-request.js +1 -1
  76. package/dist/server/workers/mcp-tool-worker-pool.d.ts +4 -0
  77. package/dist/server/workers/mcp-tool-worker-pool.js +1 -0
  78. package/dist/server/workers/mcp-tool-worker.d.ts +2 -0
  79. package/dist/server/workers/mcp-tool-worker.js +1 -0
  80. package/dist/server/workers/types.d.ts +6 -0
  81. package/dist/utils/env/is-local-development.js +1 -1
  82. package/package.json +7 -7
  83. package/dist/server/plugins/mcp/workers/run-api-routes-worker.d.ts +0 -5
  84. package/dist/server/plugins/mcp/workers/run-api-routes-worker.js +0 -1
  85. package/dist/server/workers/mcp-worker-pool.d.ts +0 -4
  86. package/dist/server/workers/mcp-worker-pool.js +0 -1
@@ -1 +1 @@
1
- import{findApiDescriptionByName as f}from"../utils.js";import{getApiDescriptionFromFs as d,getEndpointsFromPaths as l}from"./utils.js";import{telemetry as i}from"../../../../telemetry/index.js";const n="get-endpoints",m={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function u({server:s,apiDescriptionsMap:p,outdir:c,accessInfo:a}){s.tool(n,"Get all endpoints for a specific API",m,async({name:o})=>{try{const t=f(p,o);if(!t)return{content:[{type:"text",text:`No API found matching "${o}".`}]};const e=await d({relativePath:t?.relativePath||"",outdir:c,accessInfo:a});if(!e)return{content:[{type:"text",text:`Spec not found from the file system with "${o}".`}]};const r=l(e);return r.length===0?{content:[{type:"text",text:"No endpoints found"}]}:(i.sendMcpToolCalledMessage({server_type:"docs",tool:n}),{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",servers:e.servers||[],endpoints:r},null,2)}]})}catch(t){throw i.sendMcpErrorMessage({server_type:"docs",tool:n,message:t?.message||"",stack:t?.stack||""}),t}})}export{u as registerGetEndpointsTools};
1
+ import{DocsMcpTool as r}from"./docs-mcp-tool.js";import{getEndpointsFromPaths as p}from"./utils.js";const c={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class u extends r{name="get-endpoints";description="Get all endpoints for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(c)}async executeAction(o,i){const{name:s}=o,e=await this.getApiDefinition(s,i);if(!e.success)return e.response;const{definition:t}=e,n=p(t);return n.length===0?{content:[{type:"text",text:"No endpoints found"}]}:{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",servers:t.servers||[],endpoints:n},null,2)}]}}}export{u as GetEndpointsTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetFullApiDescriptionTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetFullApiDescriptionTool extends DocsMcpTool<'get-full-api-description'> {
4
+ readonly name = "get-full-api-description";
5
+ readonly description = "Get the complete OpenAPI description";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-full-api-description'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-full-api-description.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as a}from"../utils.js";import{telemetry as r}from"../../../../telemetry/index.js";import{getApiDescriptionFromFs as l}from"./utils.js";const i="get-full-api-description",f={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function g({server:n,apiDescriptionsMap:s,outdir:p,accessInfo:c}){n.tool(i,"Get the complete OpenAPI description",f,async({name:o})=>{try{const t=a(s,o);if(!t)return{content:[{type:"text",text:`No API found matching "${o}".`}]};const e=await l({relativePath:t?.relativePath||"",outdir:p,accessInfo:c});return e?(r.sendMcpToolCalledMessage({server_type:"docs",tool:i}),{content:[{type:"text",text:JSON.stringify({api:e.info?.title||"",version:e.info?.version||"",definition:e},null,2)}]}):{content:[{type:"text",text:`Spec not found from the file system with "${o}".`}]}}catch(t){throw r.sendMcpErrorMessage({server_type:"docs",tool:i,message:t?.message||"",stack:t?.stack||""}),t}})}export{g as registerGetFullApiDescriptionTools};
1
+ import{DocsMcpTool as r}from"./docs-mcp-tool.js";const s={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class a extends r{name="get-full-api-description";description="Get the complete OpenAPI description";requiredContext=["outdir","accessInfo"];constructor(){super(s)}async executeAction(i,n){const{name:o}=i,e=await this.getApiDefinition(o,n);if(!e.success)return e.response;const{definition:t}=e;return{content:[{type:"text",text:JSON.stringify({api:t.info?.title||"",version:t.info?.version||"",definition:t},null,2)}]}}}export{a as GetFullApiDescriptionTool};
@@ -1,9 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerGetSecuritySchemesTools({ server, apiDescriptionsMap, outdir, accessInfo, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- outdir: string;
7
- accessInfo: AccessInfo;
8
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class GetSecuritySchemesTool extends DocsMcpTool<'get-security-schemes'> {
4
+ readonly name = "get-security-schemes";
5
+ readonly description = "Get the security schemes for a specific API";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['get-security-schemes'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
9
10
  //# sourceMappingURL=get-security-schemes.d.ts.map
@@ -1 +1 @@
1
- import{findApiDescriptionByName as a}from"../utils";import{telemetry as i}from"../../../../telemetry/index.js";import{getApiDescriptionFromFs as m}from"./utils.js";const o="get-security-schemes",y={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};function h({server:s,apiDescriptionsMap:n,outdir:c,accessInfo:p}){s.tool(o,"Get the security schemes for a specific API",y,async({name:r})=>{try{const e=a(n,r);if(!e)return{content:[{type:"text",text:`No API found matching "${r}".`}]};const t=await m({relativePath:e?.relativePath||"",outdir:c,accessInfo:p});return t?(i.sendMcpToolCalledMessage({server_type:"docs",tool:o}),{content:[{type:"text",text:JSON.stringify({name:t.info?.title,version:t.info?.version,securitySchemes:t.components?.securitySchemes||[],security:t.security||[]},null,2)}]}):{content:[{type:"text",text:`Spec not found from the file system with "${r}".`}]}}catch(e){throw i.sendMcpErrorMessage({server_type:"docs",tool:o,message:e?.message||"",stack:e?.stack||""}),e}})}export{h as registerGetSecuritySchemesTools};
1
+ import{DocsMcpTool as o}from"./docs-mcp-tool.js";const r={type:"object",required:["name"],additionalProperties:!1,properties:{name:{type:"string",description:"API name (or part of it)",minLength:1}}};class p extends o{name="get-security-schemes";description="Get the security schemes for a specific API";requiredContext=["outdir","accessInfo"];constructor(){super(r)}async executeAction(s,i){const{name:n}=s,t=await this.getApiDefinition(n,i);if(!t.success)return t.response;const{definition:e}=t;return{content:[{type:"text",text:JSON.stringify({name:e.info?.title,version:e.info?.version,securitySchemes:e.components?.securitySchemes||[],security:e.security||[]},null,2)}]}}}export{p as GetSecuritySchemesTool};
@@ -1,14 +1,8 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { AccessInfo, ApiDescriptionInfo } from '../../types.js';
3
- /**
4
- * Registers all tools with the MCP server
5
- */
6
- export declare function registerDocsTools({ server, baseUrl, outdir, apiDescriptionsMap, headers, accessInfo, }: {
7
- server: McpServer;
8
- baseUrl: string;
9
- outdir: string;
10
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
11
- accessInfo: AccessInfo;
12
- headers?: Record<string, string | string[] | undefined>;
13
- }): void;
1
+ import type { ToolArgsMap } from '../../types.js';
2
+ import type { DocsMcpTool, DocsMcpToolRegistrationOptions } from './docs-mcp-tool.js';
3
+ export declare const docsTools: DocsMcpTool<keyof ToolArgsMap>[];
4
+ export declare function registerDocsTools(options: DocsMcpToolRegistrationOptions): void;
5
+ export declare function getDocsTool<T extends keyof ToolArgsMap>(name: T): DocsMcpTool<T> | undefined;
6
+ export { DocsMcpTool } from './docs-mcp-tool.js';
7
+ export type { DocsMcpToolRegistrationOptions } from './docs-mcp-tool.js';
14
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- import{registerListApisTools as g}from"./list-apis.js";import{registerGetEndpointsTools as T}from"./get-endpoints.js";import{registerGetEndpointTools as e}from"./get-endpoint-info.js";import{registerGetSecuritySchemesTools as f}from"./get-security-schemes.js";import{registerGetFullApiDescriptionTools as h}from"./get-full-api-description.js";import{registerSearchTool as A}from"./search.js";import{registerWhoAmITool as G}from"./whoami.js";import{shouldHandleMcpAuth as p}from"../../auth/auth-handlers.js";function F({server:o,baseUrl:l,outdir:m,apiDescriptionsMap:r,headers:i,accessInfo:t}){p(t.requiresLogin,t.rbac)&&G(o,i),g({server:o,apiDescriptionsMap:r}),T({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),e({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),f({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),h({server:o,apiDescriptionsMap:r,outdir:m,accessInfo:t}),A(o,l,m,i)}export{F as registerDocsTools};
1
+ import{GetEndpointInfoTool as t}from"./get-endpoint-info.js";import{GetEndpointsTool as n}from"./get-endpoints.js";import{GetFullApiDescriptionTool as i}from"./get-full-api-description.js";import{GetSecuritySchemesTool as m}from"./get-security-schemes.js";import{ListApisTool as s}from"./list-apis.js";import{SearchTool as c}from"./search.js";import{WhoAmITool as p}from"./whoami.js";import{shouldHandleMcpAuth as f}from"../../auth/auth-handlers.js";const e=[new s,new n,new t,new m,new i,new c,new p],l=e.reduce((o,r)=>(o[r.name]=r,o),{});function A(o){e.forEach(r=>{r.name==="whoami"&&!f(o.accessInfo.requiresLogin,o.accessInfo.rbac)||r.register(o)})}function D(o){return l[o]}import{DocsMcpTool as E}from"./docs-mcp-tool.js";export{E as DocsMcpTool,e as docsTools,D as getDocsTool,A as registerDocsTools};
@@ -1,7 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- import type { ApiDescriptionInfo } from '../../types.js';
3
- export declare function registerListApisTools({ server, apiDescriptionsMap, }: {
4
- server: McpServer;
5
- apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
6
- }): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class ListApisTool extends DocsMcpTool<'list-apis'> {
4
+ readonly name = "list-apis";
5
+ readonly description = "Lists available APIs with their context and purpose";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['list-apis'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
7
10
  //# sourceMappingURL=list-apis.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as a}from"../../../../telemetry/index.js";import{filterApiDescriptionsByName as g}from"../utils.js";const r="list-apis",f={type:"object",additionalProperties:!1,required:[],properties:{filter:{type:"string",description:"API name (or part of it)",minLength:1},page:{type:"number",description:"Page number",minimum:1,default:1},limit:{type:"number",description:"Number of APIs per page. Default is 300",minimum:1,default:300}}};function b({server:p,apiDescriptionsMap:c}){p.tool(r,"Lists available APIs with their context and purpose",f,async({filter:o,page:i=1,limit:t=300})=>{let e=Object.values(c);o&&(e=g(e,o));const n=(i-1)*t,l=n+t,m=Math.ceil(e.length/t),d=e.length;e=e.slice(n,l);try{return e.length===0?{content:[{type:"text",text:"No APIs available"}]}:(a.sendMcpToolCalledMessage({server_type:"docs",tool:r}),{content:[{type:"text",text:JSON.stringify({items:e.map(({relativePath:s,...u})=>u),limit:t,total:d,page:i,totalPages:m})}]})}catch(s){throw a.sendMcpErrorMessage({server_type:"docs",tool:r,message:s?.message||"",stack:s?.stack||""}),s}})}export{b as registerListApisTools};
1
+ import{filterApiDescriptionsByName as u}from"../utils.js";import{DocsMcpTool as m}from"./docs-mcp-tool.js";const d={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}}};class y extends m{name="list-apis";description="Lists available APIs with their context and purpose";requiredContext=[];constructor(){super(d)}async executeAction(s,o){const{filter:i,page:n=1,limit:e=300}=s;let t=Object.values(o.apiDescriptionsMap);i&&(t=u(t,i));const r=(n-1)*e,a=r+e,l=Math.ceil(t.length/e),p=t.length;return t=t.slice(r,a),t.length===0?{content:[{type:"text",text:"No APIs available"}]}:{content:[{type:"text",text:JSON.stringify({items:t.map(({relativePath:b,...c})=>c),limit:e,total:p,page:n,totalPages:l})}]}}}export{y as ListApisTool};
@@ -1,3 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- export declare function registerSearchTool(server: McpServer, baseUrl: string, outdir: string, headers?: Record<string, string | string[] | undefined>): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class SearchTool extends DocsMcpTool<'search'> {
4
+ readonly name = "search";
5
+ readonly description = "Search across the documentation to fetch relevant content for a given query";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(args: ToolArgsMap['search'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
3
10
  //# sourceMappingURL=search.d.ts.map
@@ -1 +1 @@
1
- import{withPathPrefix as u}from"@redocly/theme/core/utils";import{ServerRoutes as m}from"../../../../../constants/common.js";import{telemetry as s}from"../../../../telemetry/index.js";import{processDocuments as y}from"./utils.js";const o="search",f={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}}};function k(n,a,c,i){n.tool(o,"Search across the documentation to fetch relevant content for a given query",f,async({query:p})=>{try{const e=JSON.stringify({query:p}),h=`${a}${u(m.SEARCH)}`.replace("http","https"),d=`authorization=${String(i?.authorization).replace(/^Bearer /,"")}`,t=await fetch(h,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",Cookie:d},body:e});if(!t.ok)throw new Error(`Search request failed with status ${t.status}`);const l=await t.json(),r=y(l.documents||{},c);return s.sendMcpToolCalledMessage({server_type:"docs",tool:o}),{content:[{type:"text",text:r.trim().length?r:"No results found."}]}}catch(e){throw s.sendMcpErrorMessage({server_type:"docs",tool:o,message:e?.message||"",stack:e?.stack||""}),e}})}export{k as registerSearchTool};
1
+ import{withPathPrefix as d}from"@redocly/theme/core/utils";import{ServerRoutes as p}from"../../../../../constants/common.js";import{DocsMcpTool as l}from"./docs-mcp-tool.js";import{processDocuments as m}from"./utils.js";const f={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}}};class g extends l{name="search";description="Search across the documentation to fetch relevant content for a given query";requiredContext=["baseUrl","outdir","headers"];constructor(){super(f)}async executeAction(a,e){const{query:i}=a;if(!e.baseUrl||!e.outdir)throw new Error("Missing required context: baseUrl and outdir");const c=JSON.stringify({query:i});let t=`${e.baseUrl}${d(p.SEARCH)}`;t.startsWith("http://")&&(t=t.replace(/^http:\/\//,"https://"));const o=e.headers?.authorization,s=o?`authorization=${String(o).replace(/^Bearer /,"")}`:"",r=await fetch(t,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...s?{Cookie:s}:{}},body:c});if(!r.ok){const u=await r.text().catch(()=>"Unable to read error response");throw new Error(`Search request failed with status ${r.status}: ${u}`)}const h=await r.json(),n=m(h.documents||{},e.outdir);return{content:[{type:"text",text:n.trim().length?n:"No results found."}]}}}export{g as SearchTool};
@@ -1,6 +1,7 @@
1
1
  import type { OpenAPIDefinition, OpenAPIOperation } from '@redocly/openapi-docs';
2
2
  import type { SearchItemData } from '@redocly/theme/core/types';
3
- import type { AccessInfo } from '../../types';
3
+ import type { AccessInfo, McpEndpoint } from '../../types';
4
+ export declare function isMcpEndpoint(value: unknown): value is McpEndpoint;
4
5
  type EndpointInfo = Pick<OpenAPIOperation, 'summary' | 'description' | 'security'> & {
5
6
  method: string;
6
7
  path: string;
@@ -1,11 +1,11 @@
1
- import y from"node:fs";import u from"node:path";import{existsSync as A}from"node:fs";import{readFile as O}from"node:fs/promises";import{replaceFileExtension as g}from"../../../../plugins/openapi-docs/store-definition-bundles";import{PUBLIC_API_DEFINITIONS_FOLDER as j}from"../../../../constants/common";import{filterDataByAccessDeep as F}from"../../../../utils/rbac";import{checkEndpointAndDeleteXMcp as D}from"../../utils/xmcp-utils.js";import{MAX_DOCUMENTS_PER_CATEGORY as C}from"../../constants.js";function T(i){const{paths:o={}}=i,s=[];for(const[c,n]of Object.entries(o)){const a=!D(n,"docs");for(const[f,t]of Object.entries(n))a||!D(t,"docs")||s.push({path:c,method:f.toUpperCase(),summary:t.summary,description:t.description,security:t.security})}return s}function M(i,o){return Object.entries(i).map(([c,n])=>{if(!n||n.length===0)return"";const a=n.slice(0,C).map(f=>{const{document:t,highlight:m}=f,d=m?.title||(Array.isArray(t.title)?t.title[0]:t.title);let r=`Document: ${t.title}`;r+=`### [${d}](${t.url})
1
+ import y from"node:fs";import u from"node:path";import{existsSync as j}from"node:fs";import{readFile as A}from"node:fs/promises";import{replaceFileExtension as O}from"../../../../plugins/openapi-docs/store-definition-bundles";import{PUBLIC_API_DEFINITIONS_FOLDER as b}from"../../../../constants/common";import{filterDataByAccessDeep as g}from"../../../../utils/rbac";import{checkEndpointAndDeleteXMcp as E}from"../../utils/xmcp-utils.js";import{MAX_DOCUMENTS_PER_CATEGORY as F}from"../../constants.js";function N(e){return typeof e=="object"&&e!==null&&"responses"in e&&typeof e.responses=="object"}function T(e){const{paths:i={}}=e,s=[];for(const[c,r]of Object.entries(i)){const p=!E(r,"docs");for(const[a,t]of Object.entries(r))p||!E(t,"docs")||s.push({path:c,method:a.toUpperCase(),summary:t.summary,description:t.description,security:t.security})}return s}function R(e,i){return Object.entries(e).map(([c,r])=>{if(!r||r.length===0)return"";const p=r.slice(0,F).map(a=>{const{document:t,highlight:m}=a,d=m?.title||(Array.isArray(t.title)?t.title[0]:t.title);let o=`Document: ${t.title}`;o+=`### [${d}](${t.url})
2
2
 
3
- `;let p;if(t.url)try{let e=t.url.startsWith("/")?t.url.slice(1):t.url;const l=e.indexOf("#");l!==-1&&(e=e.substring(0,l));const h=u.extname(e);h&&(e=e.slice(0,-h.length));let E=e+".md";const x=u.join(o,E);y.existsSync(x)&&(p=y.readFileSync(x,"utf8"))}catch{}return p||(p=m?.text||(Array.isArray(t.text)?t.text[0]:t.text)),r+=p,t.facets&&(r+=`
3
+ `;let f;if(t.url)try{let n=t.url.startsWith("/")?t.url.slice(1):t.url;const l=n.indexOf("#");l!==-1&&(n=n.substring(0,l));const h=u.extname(n);h&&(n=n.slice(0,-h.length));let D=n+".md";const x=u.join(i,D);y.existsSync(x)&&(f=y.readFileSync(x,"utf8"))}catch{}return f||(f=m?.text||(Array.isArray(t.text)?t.text[0]:t.text)),o+=f,t.facets&&(o+=`
4
4
 
5
5
  **Categories:**
6
- `,Object.entries(t.facets).forEach(([e,l])=>{r+=`- ${e}: ${l}
7
- `})),r});return`## ${c}
6
+ `,Object.entries(t.facets).forEach(([n,l])=>{o+=`- ${n}: ${l}
7
+ `})),o});return`## ${c}
8
8
 
9
- ${a}`}).join(`
9
+ ${p}`}).join(`
10
10
 
11
- `).trim()}async function R({relativePath:i,outdir:o,accessInfo:{isAuthenticated:s,email:c,teams:n,rbac:a={},requiresLogin:f=!1}}){const t=u.join(o||"",j,g(i,".json"));if(!A(t))return;const d=await O(t,"utf-8"),r=JSON.parse(d);return F(r,{isAuthenticated:s,email:c,teams:n},a,f)}export{R as getApiDescriptionFromFs,T as getEndpointsFromPaths,M as processDocuments};
11
+ `).trim()}async function U({relativePath:e,outdir:i,accessInfo:{isAuthenticated:s,email:c,teams:r,rbac:p={},requiresLogin:a=!1}}){const t=u.join(i||"",b,O(e,".json"));if(!j(t))return;const d=await A(t,"utf-8"),o=JSON.parse(d);return g(o,{isAuthenticated:s,email:c,teams:r},p,a)}export{U as getApiDescriptionFromFs,T as getEndpointsFromPaths,N as isMcpEndpoint,R as processDocuments};
@@ -1,3 +1,10 @@
1
- import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
2
- export declare function registerWhoAmITool(server: McpServer, headers?: Record<string, string | string[] | undefined>): void;
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse, ToolArgsMap } from '../../types.js';
2
+ import { DocsMcpTool, type ContextKey } from './docs-mcp-tool.js';
3
+ export declare class WhoAmITool extends DocsMcpTool<'whoami'> {
4
+ readonly name = "whoami";
5
+ readonly description = "Get information about the currently authenticated user";
6
+ readonly requiredContext: readonly ContextKey[];
7
+ constructor();
8
+ protected executeAction(_args: ToolArgsMap['whoami'], context: McpToolWorkerParams['context']): Promise<McpToolWorkerResponse>;
9
+ }
3
10
  //# sourceMappingURL=whoami.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as r}from"../../../../telemetry/index";import{getUserInfoFromHeaders as s}from"../../utils/jwt";const t="whoami";function c(o,n){o.tool(t,"Get information about the currently authenticated user",()=>{try{const e=s(n||{});return r.sendMcpToolCalledMessage({server_type:"docs",tool:t}),e?{content:[{type:"text",text:JSON.stringify({email:e.email,name:e.name,subject:e.sub,clientId:e.client_id,scope:e.scope,issuedAt:e.iat?new Date(e.iat*1e3).toISOString():void 0,expiresAt:e.exp?new Date(e.exp*1e3).toISOString():void 0})}],isError:!1}:{content:[{type:"text",text:JSON.stringify({error:"Not authenticated",message:"No valid authentication token found. Please authenticate first."})}],isError:!0}}catch(e){return r.sendMcpErrorMessage({server_type:"docs",tool:t,message:e?.message||"Failed to get user info",stack:e?.stack||""}),{content:[{type:"text",text:JSON.stringify({error:"Failed to get user info",details:e instanceof Error?e.message:String(e)})}],isError:!0}}})}export{c as registerWhoAmITool};
1
+ import{getUserInfoFromHeaders as r}from"../../utils/jwt.js";import{DocsMcpTool as o}from"./docs-mcp-tool.js";const n={type:"object",required:[],additionalProperties:!1,properties:{}};class u extends o{name="whoami";description="Get information about the currently authenticated user";requiredContext=["headers"];constructor(){super(n)}async executeAction(s,t){const e=r(t.headers||{});return e?{content:[{type:"text",text:JSON.stringify({email:e.email,name:e.name,subject:e.sub,clientId:e.client_id,scope:e.scope,issuedAt:e.iat?new Date(e.iat*1e3).toISOString():void 0,expiresAt:e.exp?new Date(e.exp*1e3).toISOString():void 0})}],isError:!1}:{content:[{type:"text",text:JSON.stringify({error:"Not authenticated",message:"No valid authentication token found. Please authenticate first."})}],isError:!0}}}export{u as WhoAmITool};
@@ -0,0 +1,5 @@
1
+ import type { Context } from 'hono';
2
+ import type { ApiRoute } from '../../../types';
3
+ import type { Store } from '../../../store.js';
4
+ export declare function handleMcpRequest(route: ApiRoute, ctx: Context, store: Store): Promise<Response>;
5
+ //# sourceMappingURL=handle-mcp-request.d.ts.map
@@ -0,0 +1 @@
1
+ import{withPathPrefix as m}from"@redocly/theme/core/utils";import{importApiRoutesHandler as d}from"../../../api-routes/import-api-routes-handlers.js";import{enhanceContext as f}from"../../../api-routes/helpers/enhance-context.js";import{telemetry as h}from"../../../telemetry/index.js";import{KvService as A}from"../../../persistence/kv/services/kv-service.js";async function v(n,a,t){const e=a.get("auth"),i=await t.resolveRouteStaticData(n)||{},r=m(n.slug),{requestHandlers:o}=await d(t.serverOutDir),c=o[n.requestHandlerId],p=(await c()).default,u=async()=>await A.getInstance({baseDbDir:t.serverOutDir,sqldRemoteDatabaseUrl:process.env.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),l=f({honoCtx:a,ctx:{user:{teams:e.teams,email:e.claims.email,claims:e.claims,idpAccessToken:e.idpAccessToken,idpId:e.claims.idpId,isAuthenticated:e.isAuthenticated},config:t.config},telemetry:h,getKv:u}),s=await p(a.req.raw,l,{...i,props:{...i.props,routeSlug:r,outdir:t.outdir}});return s instanceof Response?s:typeof s=="string"?new Response(s,{headers:{"Content-Type":"text/plain"}}):new Response(JSON.stringify(s),{headers:{"Content-Type":"application/json"}})}export{v as handleMcpRequest};
@@ -3,7 +3,6 @@ import type { McpServerInstance, McpServerType } from '../types.js';
3
3
  export type McpRequestHandlerDependencies = {
4
4
  createServerInstance: (context: ApiFunctionsContext, staticData: PageStaticData, headers: Record<string, string | string[] | undefined>, request: Request) => Promise<McpServerInstance>;
5
5
  serverType: McpServerType;
6
- connectionTimeoutMs?: number;
7
6
  };
8
7
  /**
9
8
  * Creates a standardized MCP request handler
@@ -1 +1 @@
1
- import{toFetchResponse as i,toReqRes as E}from"fetch-to-node";import{logger as d}from"../../../tools/notifiers/logger.js";import{DEFAULT_CONNECTION_TIMEOUT_MS as w}from"../constants.js";import{createMethodNotAllowedError as R,withErrorHandling as y}from"./errors.js";function N(u){const{createServerInstance:l,serverType:p,connectionTimeoutMs:m=w}=u;return async(r,h,f)=>{let e,n;const c=async()=>{try{n&&(clearTimeout(n),n=void 0),e&&(await e.cleanup(),e=void 0)}catch(a){d.error("Error during mcp server cleanup:",a)}};return y(async()=>{const a={};r.headers.forEach((o,T)=>{a[T]=o}),e=await l(h,f,a,r);const{req:s,res:t}=E(r);switch(n=setTimeout(()=>{c()},m),t.on("close",()=>{c().catch(o=>{d.error("Error during response close cleanup:",o)})}),r.method){case"GET":return await e.transport.handleRequest(s,t),i(t);case"POST":const o=await r.json();return await e.transport.handleRequest(s,t,o),i(t);default:return R()}},p,c)}}export{N as createMcpRequestHandler};
1
+ import{toFetchResponse as p,toReqRes as h}from"fetch-to-node";import{createMethodNotAllowedError as w,withErrorHandling as y}from"./errors.js";function m(s){const{createServerInstance:a,serverType:c}=s;return async(e,d,i)=>{let r;return y(async()=>{const n={};e.headers.forEach((t,l)=>{n[l]=t});const{req:u,res:o}=h(e);switch(e.method){case"GET":return new Response(JSON.stringify({error:"Method Not Allowed",message:`In order to use this MCP server, you need register it in your MCP Client (VS Code, Cursor, Claude Code, etc.) using that URL: ${e.url}`}),{status:405,headers:{"Content-Type":"application/json"}});case"POST":{r=await a(d,i,n,e);const t=await e.json();return await r.transport.handleRequest(u,o,t),p(o)}default:return w()}},c,async()=>{r&&(await r.cleanup(),r=void 0)})}}export{m as createMcpRequestHandler};
@@ -1,6 +1,7 @@
1
1
  import type { OpenAPIPath } from '@redocly/openapi-docs/src/types';
2
2
  import type { McpServer } from '@redocly/mcp-typescript-sdk/server/mcp.js';
3
3
  import type { StreamableHTTPServerTransport } from '@redocly/mcp-typescript-sdk/server/streamableHttp.js';
4
+ import type { CallToolResult } from '@redocly/mcp-typescript-sdk/types.js';
4
5
  import type { OpenAPIServer } from '@redocly/openapi-docs/lib/types/open-api.js';
5
6
  import type { McpErrorCodes, McpServerType } from './constants';
6
7
  import type { RbacConfig, PageStaticData } from '@redocly/config';
@@ -70,5 +71,44 @@ export type McpUserInfo = {
70
71
  exp?: number;
71
72
  [key: string]: any;
72
73
  };
74
+ export type ToolArgsMap = {
75
+ 'list-apis': {
76
+ filter?: string;
77
+ page?: number;
78
+ limit?: number;
79
+ };
80
+ 'get-endpoints': {
81
+ name: string;
82
+ };
83
+ 'get-endpoint-info': {
84
+ name: string;
85
+ path: string;
86
+ method: string;
87
+ };
88
+ 'get-security-schemes': {
89
+ name: string;
90
+ };
91
+ 'get-full-api-description': {
92
+ name: string;
93
+ };
94
+ search: {
95
+ query: string;
96
+ };
97
+ whoami: Record<string, never>;
98
+ };
99
+ export type McpToolWorkerParams = {
100
+ [K in keyof ToolArgsMap]: {
101
+ toolName: K;
102
+ args: ToolArgsMap[K];
103
+ context: {
104
+ apiDescriptionsMap: Record<string, ApiDescriptionInfo>;
105
+ outdir?: string;
106
+ accessInfo?: AccessInfo;
107
+ baseUrl?: string;
108
+ headers?: Record<string, string | string[] | undefined>;
109
+ };
110
+ };
111
+ }[keyof ToolArgsMap];
112
+ export type McpToolWorkerResponse = CallToolResult;
73
113
  export {};
74
114
  //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,3 @@
1
+ import type { McpToolWorkerParams, McpToolWorkerResponse } from '../types.js';
2
+ export declare function executeMcpTool(params: McpToolWorkerParams): Promise<McpToolWorkerResponse>;
3
+ //# sourceMappingURL=execute-mcp-tool.d.ts.map
@@ -0,0 +1 @@
1
+ import{getDocsTool as c}from"../docs-mcp/tools/index.js";async function l(e){const{toolName:o,args:n,context:r}=e,t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);return await t.execute(n,r)}export{l as executeMcpTool};
@@ -0,0 +1,12 @@
1
+ import type { DatabaseClient } from '../../../../../providers/database/client.js';
2
+ import type { DatabaseScorecardsConfig, DatabaseScorecardsConfigDto } from '../../../../../providers/database/databases/main-sqlite/schemas/scorecards-config-table.js';
3
+ export declare class ScorecardsConfigLocalRepository {
4
+ #private;
5
+ constructor(db: DatabaseClient);
6
+ findActiveConfigByKey(key: string): Promise<DatabaseScorecardsConfig | null>;
7
+ findAllActiveConfigs(): Promise<DatabaseScorecardsConfig[]>;
8
+ insertConfig(config: DatabaseScorecardsConfigDto): Promise<DatabaseScorecardsConfig>;
9
+ updateConfigById(id: string, updates: Partial<Omit<DatabaseScorecardsConfigDto, 'id' | 'createdAt'>>): Promise<DatabaseScorecardsConfig>;
10
+ archiveConfigById(id: string, archivedAt: string): Promise<DatabaseScorecardsConfig>;
11
+ }
12
+ //# sourceMappingURL=scorecards-config-local-repository.d.ts.map
@@ -0,0 +1 @@
1
+ import{and as o,eq as n,isNull as s}from"drizzle-orm";import{scorecardsConfigTable as r}from"../../../../../providers/database/databases/main-sqlite/schemas/scorecards-config-table.js";class d{#e;constructor(e){this.#e=e}async findActiveConfigByKey(e){return(await this.#e.client.select().from(r).where(o(n(r.key,e),s(r.archivedAt))).limit(1))[0]??null}async findAllActiveConfigs(){return await this.#e.client.select().from(r).where(s(r.archivedAt))}async insertConfig(e){const t=await this.#e.client.insert(r).values(e).returning();if(!t[0])throw new Error(`Failed to insert scorecard config with key: ${e.key}`);return t[0]}async updateConfigById(e,t){const i=await this.#e.client.update(r).set(t).where(n(r.id,e)).returning();if(!i[0])throw new Error(`Failed to update scorecard config with id: ${e}`);return i[0]}async archiveConfigById(e,t){const i=await this.#e.client.update(r).set({archivedAt:t}).where(n(r.id,e)).returning();if(!i[0])throw new Error(`Failed to archive scorecard config with id: ${e}`);return i[0]}}export{d as ScorecardsConfigLocalRepository};
@@ -0,0 +1,11 @@
1
+ import type { ScorecardsConfig } from '@redocly/config';
2
+ import type { ServiceInstanceOptions } from '../../../providers/database/types.js';
3
+ import { DatabaseConnectionFactory } from '../../../providers/database/database-connection-factory.js';
4
+ import { BaseRepository } from '../../../providers/database/base-repository.js';
5
+ export declare class ScorecardsConfigService extends BaseRepository {
6
+ #private;
7
+ constructor(dbConnection: Awaited<ReturnType<typeof DatabaseConnectionFactory.create>>);
8
+ static getInstance(options: ServiceInstanceOptions): Promise<ScorecardsConfigService>;
9
+ syncConfigs(scorecardsConfig: ScorecardsConfig): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=scorecards-config-service.d.ts.map
@@ -0,0 +1 @@
1
+ import{ulid as f}from"ulid";import{logger as n}from"../../../tools/notifiers/logger.js";import{DatabaseConnectionFactory as g}from"../../../providers/database/database-connection-factory.js";import{BaseRepository as l}from"../../../providers/database/base-repository.js";import{shaHex as d}from"../../../utils/crypto/sha-hex.js";import{hasOptionsChanged as h}from"../../../plugins/catalog-entities/utils/has-options-changed.js";import{slug as m}from"../../../utils/slugger.js";import{withTimestamp as c}from"../../../utils/time/with-timestamp.js";import{ScorecardsConfigLocalRepository as y}from"./repositories/local/scorecards-config-local-repository.js";class r extends l{static#t;static#i;#e;constructor(e){if(!e)throw new Error("Database connection is required for ScorecardsConfigService");super(e),this.#e=new y(this.databaseClient)}static async getInstance(e){const i=h(r.#i,e);if(!r.#t||i){const s=await g.create("main-local",e);if(!s)throw new Error("Failed to create db connection for scorecards config service");r.#t=new r(s),r.#i=e}return r.#t}async syncConfigs(e){if(!Array.isArray(e)||e.length===0){n.verbose("No scorecard configs to sync");return}n.verbose(`Starting scorecard config sync for ${e.length} config(s)`);const i=new Set;for(const s of e)try{const t=s.key;if(!/^[a-z0-9-]+$/i.test(t)){n.error(`Skipping invalid scorecard config item: key "${t}" does not match kebab-case format (letters, numbers, and dashes only)`,{scorecard:s});continue}i.add(t);const o=this.#s(s),a=await this.#e.findActiveConfigByKey(t);if(a){if(a.configHash===o){n.verbose(`Config "${t}" unchanged, skipping update`);continue}n.verbose(`Updating config "${t}"`),await this.#r(a.id,s,o)}else n.verbose(`Inserting new config "${t}"`),await this.#n(t,s,o)}catch(t){n.error("Error processing scorecard config item:",{error:t.message??t,scorecard:s})}await this.#o(i),n.verbose("Scorecard config sync completed")}#s(e){const i=JSON.stringify({entities:e.entities,levels:e.levels});return d(i)}async#n(e,i,s){await this.#e.insertConfig(c({id:`sc_${f()}`,key:e,slug:m(e),name:i.name,description:i.description??null,entitiesFilter:JSON.stringify(i.entities),levels:JSON.stringify(i.levels),configHash:s,archivedAt:null}))}async#r(e,i,s){const t=c({entitiesFilter:JSON.stringify(i.entities),levels:JSON.stringify(i.levels),configHash:s,archivedAt:null},{fields:["updatedAt"]});await this.#e.updateConfigById(e,t)}async#o(e){const i=await this.#e.findAllActiveConfigs(),s=new Date().toISOString();for(const t of i)if(!e.has(t.key)){n.verbose(`Archiving removed config "${t.key}"`);try{await this.#e.archiveConfigById(t.id,s)}catch(o){n.error(`Error archiving config item "${t.key}":`,o.message??o)}}}}export{r as ScorecardsConfigService};
@@ -1,2 +1,3 @@
1
- export declare function runScorecardsWorker(baseDbDir: string): Promise<void>;
1
+ import type { ScorecardsConfig } from '@redocly/config';
2
+ export declare function runScorecardsWorker(baseDbDir: string, scorecardsConfig: ScorecardsConfig): Promise<void>;
2
3
  //# sourceMappingURL=run-scorecards-worker.d.ts.map
@@ -1 +1 @@
1
- import{SCORECARDS_WORKER_KEY as n,scorecardsWorker as i}from"../../../workers/scorecards-worker-pool.js";import{logger as r}from"../../../tools/notifiers/logger.js";const c=5;async function t(s,e){try{const o=await i.exec(n,[{baseDbDir:s,pollingIntervalMs:parseInt(process.env.SCORECARDS_POLLING_INTERVAL_MS||"3000",10)}]);return o.success?r.info(`${o.message}`):r.error(`Scorecards Worker error (attempt ${e}/${c}):`,o.error),Promise.resolve()}catch(o){r.error(`Scorecards Worker execution failed (attempt ${e}/${c}):`,o)}return e<c?(r.info(`Retrying Scorecards Worker (attempt ${e+1}/${c})...`),t(s,e+1)):(r.error(`All ${c} attempts failed. Scorecards Worker could not be started.`),Promise.resolve())}async function l(s){return r.info("Starting continuous Scorecards Worker..."),t(s,1)}export{l as runScorecardsWorker};
1
+ import{SCORECARDS_WORKER_KEY as i,scorecardsWorker as m}from"../../../workers/scorecards-worker-pool.js";import{logger as r}from"../../../tools/notifiers/logger.js";const o=5;async function n(c){const{baseDbDir:s,scorecardsConfig:a,attempt:e}=c;try{const t=await m.exec(i,[{baseDbDir:s,scorecardsConfig:a,pollingIntervalMs:parseInt(process.env.SCORECARDS_POLLING_INTERVAL_MS||"3000",10)}]);return t.success?r.info(`${t.message}`):r.error(`Scorecards Worker error (attempt ${e}/${o}):`,t.error),Promise.resolve()}catch(t){r.error(`Scorecards Worker execution failed (attempt ${e}/${o}):`,t)}return e<o?(r.info(`Retrying Scorecards Worker (attempt ${e+1}/${o})...`),n({baseDbDir:s,scorecardsConfig:a,attempt:e+1})):(r.error(`All ${o} attempts failed. Scorecards Worker could not be started.`),Promise.resolve())}async function p(c,s){return r.info("Starting continuous Scorecards Worker..."),n({baseDbDir:c,scorecardsConfig:s,attempt:1})}export{p as runScorecardsWorker};
@@ -1,5 +1,7 @@
1
+ import type { ScorecardsConfig } from '@redocly/config';
1
2
  export type ScorecardsWorkerParams = {
2
3
  baseDbDir: string;
4
+ scorecardsConfig: ScorecardsConfig;
3
5
  pollingIntervalMs?: number;
4
6
  };
5
7
  export type ScorecardsWorkerResponse = {
@@ -1 +1 @@
1
- import{logger as o}from"../../../tools/notifiers/logger.js";import{loadEnvVariables as l}from"../../../utils/envs/load-env-variables.js";import{CatalogEntitiesService as d}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";const u=3e3;async function y(s){try{const{baseDbDir:r,pollingIntervalMs:a=u}=s;l(r),o.verbose(`Initializing Scorecards Worker: polling interval ${a}ms (${a/1e3}s)`);const t=await d.getInstance({baseDbDir:r});return g(t,a),{success:!0,message:"Scorecards Worker started successfully"}}catch(r){const a=r instanceof Error?r.message:String(r);return o.error("Failed to start Scorecards Worker:",r),{success:!1,message:"Failed to start Scorecards Worker",error:a}}}async function g(s,r){let a=0,t=null;return t=setInterval(n,r),new Promise(()=>{});async function c(e){return e&&(await s.updateEntityScorecardsStatus(e.id,"CALCULATING"),await new Promise(i=>{setTimeout(async()=>{i()},1)}),await s.updateEntityScorecardsStatusIfCalculating(e.id,"UP_TO_DATE")?o.verbose(`Catalog Entity (${e.key}) scorecard evaluation completed successfully`):(await s.updateEntityScorecardsStatus(e.id,"OUTDATED"),o.verbose(`Catalog Entity (${e.key}) was updated during calculation, scorecard evaluation in not applicable anymore`))),Promise.resolve()}async function n(){try{a++;const e=await s.getOutdatedEntity();if(!e)return t||(o.verbose(`\u{1F50D} Resuming normal polling interval ${r}ms (${r/1e3}s)`),t=setInterval(n,r)),Promise.resolve();o.verbose(`\u{1F50D} Poll #${a} in Scorecards Worker: found Catalog Entity (${e.key}) for scorecard evaluation`),t&&(clearInterval(t),t=null,o.verbose(`\u{1F50D} Stopping normal polling while processing Catalog Entity (${e.key}) for scorecard evaluation`)),await c(e),await n()}catch(e){o.error("Error during poll in Scorecards Worker:",e),t||(t=setInterval(n,r))}}}export{y as startScorecardsWorker};
1
+ import{logger as a}from"../../../tools/notifiers/logger.js";import{loadEnvVariables as l}from"../../../utils/envs/load-env-variables.js";import{CatalogEntitiesService as d}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";import{ScorecardsConfigService as u}from"../../../plugins/scorecards/database/scorecards-config-service.js";const g=3e3;async function E(s){try{const{baseDbDir:r,scorecardsConfig:c,pollingIntervalMs:o=g}=s;await l(r),a.verbose(`Initializing Scorecards Worker: polling interval ${o}ms (${o/1e3}s)`);const n=await d.getInstance({baseDbDir:r});try{await(await u.getInstance({baseDbDir:r})).syncConfigs(c),a.verbose("Scorecard configuration sync completed successfully")}catch(t){a.error("Failed to sync scorecard configurations:",t.message??t)}return f(n,o),{success:!0,message:"Scorecards Worker started successfully"}}catch(r){const c=r instanceof Error?r.message:String(r);return a.error("Failed to start Scorecards Worker:",r),{success:!1,message:"Failed to start Scorecards Worker",error:c}}}async function f(s,r){let c=0,o=null;return o=setInterval(t,r),new Promise(()=>{});async function n(e){return e&&(await s.updateEntityScorecardsStatus(e.id,"CALCULATING"),await new Promise(i=>{setTimeout(async()=>{i()},1)}),await s.updateEntityScorecardsStatusIfCalculating(e.id,"UP_TO_DATE")?a.verbose(`Catalog Entity (${e.key}) scorecard evaluation completed successfully`):(await s.updateEntityScorecardsStatus(e.id,"OUTDATED"),a.verbose(`Catalog Entity (${e.key}) was updated during calculation, scorecard evaluation in not applicable anymore`))),Promise.resolve()}async function t(){try{c++;const e=await s.getOutdatedEntity();if(!e)return o||(a.verbose(`\u{1F50D} Resuming normal polling interval ${r}ms (${r/1e3}s)`),o=setInterval(t,r)),Promise.resolve();a.verbose(`\u{1F50D} Poll #${c} in Scorecards Worker: found Catalog Entity (${e.key}) for scorecard evaluation`),o&&(clearInterval(o),o=null,a.verbose(`\u{1F50D} Stopping normal polling while processing Catalog Entity (${e.key}) for scorecard evaluation`)),await n(e),await t()}catch(e){a.error("Error during poll in Scorecards Worker:",e),o||(o=setInterval(t,r))}}}export{E as startScorecardsWorker};
@@ -1 +1 @@
1
- import{DEFAULT_SSO_IDP_TITLE as d}from"../../../constants/common.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const f="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",y="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function O(g){return{id:"sso",async processContent(e){await u("build.plugin.sso",async c=>{const o=e.getConfig();if(c?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(o.sso||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0||o.sso&&Array.isArray(o.sso)&&!o.sso.length)return;const a=!!(o.rbac&&typeof o.rbac=="object"&&Object.keys(o.rbac).length!==0),p=o.requiresLogin;if(!a&&!p)return;let n=f,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?y:"";const s=o.residency;if(s){const r=s.endsWith("/")?s.slice(0,-1):s;n=`${r.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?`${r}/api/sso/oidc/introspect`:""}let t="AUTO";o.sso&&(Array.isArray(o.sso)?t=o.sso.join(","):t=o.sso);const l={oidc:{title:d,type:"OIDC",configurationUrl:n,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:{login_hint:"{{ process.env.ORG_SLUG }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORG_ID }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{O as ssoPlugin};
1
+ import{DEFAULT_SSO_IDP_TITLE as d}from"../../../constants/common.js";import{telemetryTraceStep as u}from"../../../cli/telemetry/helpers/trace-step.js";const f="https://auth.cloud.redocly.com/oidc/.well-known/openid-configuration",y="https://auth.cloud.redocly.com/api/sso/oidc/introspect";async function _(g){return{id:"sso",async processContent(e){await u("build.plugin.sso",async c=>{const o=e.getConfig();if(c?.setAttribute("config",`{"ssoDirect": ${JSON.stringify(o.ssoDirect||{})}}, {"sso": ${JSON.stringify(o.sso||{})}}`),o.ssoDirect&&typeof o.ssoDirect=="object"&&Object.keys(o.ssoDirect).length!==0||o.sso&&Array.isArray(o.sso)&&!o.sso.length)return;const a=!!(o.rbac&&typeof o.rbac=="object"&&Object.keys(o.rbac).length!==0),p=o.requiresLogin;if(!a&&!p)return;let n=f,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?y:"";const s=o.residency;if(s){const r=s.endsWith("/")?s.slice(0,-1):s;n=`${r.replace("app.","auth.")}/oidc/.well-known/openid-configuration`,i=process.env.REDOCLY_OAUTH_USE_INTROSPECT?`${r}/api/sso/oidc/introspect`:""}let t="AUTO";o.sso&&(Array.isArray(o.sso)?t=o.sso.join(","):t=o.sso);const l={oidc:{title:d,type:"OIDC",configurationUrl:n,clientId:"{{ process.env.OAUTH_CLIENT_ID }}",clientSecret:"{{ process.env.OAUTH_CLIENT_SECRET }}",teamsClaimName:"https://redocly.com/sso/teams",scopes:["openid"],authorizationRequestCustomParams:{login_hint:"{{ process.env.ORGANIZATION_SLUG }}",login_type:t,prompt:"login"},audience:"{{ process.env.ORGANIZATION_SLUG }}",introspectEndpoint:i}};e.setGlobalConfig({ssoDirect:l})})},async afterRoutesCreated(e){}}}export{_ as ssoPlugin};
@@ -9,5 +9,6 @@ export declare abstract class BaseRepository {
9
9
  protected constructor(dbConnection: DatabaseConnection);
10
10
  close(): Promise<void>;
11
11
  sync(): Promise<void>;
12
+ isNonRemoteDatabaseMode: () => boolean;
12
13
  }
13
14
  //# sourceMappingURL=base-repository.d.ts.map
@@ -1 +1 @@
1
- class n{static#e="ORGANIZATION_ID";static#t="PROJECT_ID";organizationId;projectId;databaseClient;path;constructor(t){const e=this.#r();this.organizationId=this.#n(e),this.projectId=this.#i(e),this.databaseClient=t.client,this.path=t.path}async close(){await this.databaseClient.close()}async sync(){await this.databaseClient.sync()}#n=t=>{const e=process.env.ORGANIZATION_ID;if(e)return e;if(t)return n.#e;throw new Error("ORGANIZATION_ID environment variable is required. Ensure it is set in your environment configuration.")};#i=t=>{const e=process.env.PROJECT_ID;if(e)return e;if(t)return n.#t;throw new Error("PROJECT_ID environment variable is required. Ensure it is set in your environment configuration.")};#r=()=>!process.env.SQLD_REMOTE_DATABASE_URL&&!process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN}export{n as BaseRepository};
1
+ import{SQLD_REMOTE_DATABASE_URL_NO_DEPLOYMENT_YET_VAR as i}from"../../constants/plugins/catalog-entities.js";class n{static#e="ORGANIZATION_ID";static#t="PROJECT_ID";organizationId;projectId;databaseClient;path;constructor(t){const e=this.isNonRemoteDatabaseMode();this.organizationId=this.#n(e),this.projectId=this.#i(e),this.databaseClient=t.client,this.path=t.path}async close(){await this.databaseClient.close()}async sync(){await this.databaseClient.sync()}#n=t=>{const e=process.env.ORGANIZATION_ID;if(e)return e;if(t)return n.#e;throw new Error("ORGANIZATION_ID environment variable is required. Ensure it is set in your environment configuration.")};#i=t=>{const e=process.env.PROJECT_ID;if(e)return e;if(t)return n.#t;throw new Error("PROJECT_ID environment variable is required. Ensure it is set in your environment configuration.")};isNonRemoteDatabaseMode=()=>process.env.SQLD_REMOTE_DATABASE_URL===i||!process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN}export{n as BaseRepository};
@@ -1 +1 @@
1
- import{logger as e}from"../../tools/notifiers/logger.js";import{CATALOG_LOCAL_DATABASE_MIGRATIONS_FOLDER as r,CATALOG_LOCAL_DATABASE_FOLDER as i,CATALOG_LOCAL_DATABASE_NAME as s,MAIN_LOCAL_DATABASE_MIGRATIONS_FOLDER as _,MAIN_LOCAL_DATABASE_FOLDER as E,MAIN_LOCAL_DATABASE_NAME as l,SQLD_REMOTE_DATABASE_FOLDER as c,SQLD_REMOTE_DATABASE_MIGRATIONS_FOLDER as D,SQLD_REMOTE_DATABASE_NAME as T}from"./constants.js";import{LocalDatabaseInitializationStrategy as n,RemoteDatabaseInitializationStrategy as L}from"./database-initialization-strategy.js";import{DatabaseConnectionsManager as O}from"./database-connections-manager.js";class g{static async create(a,t){switch(a){case"main-local":return await this.#a(t);case"catalog-local":return await this.#t(t);case"sqld-remote":return await this.#e(t);default:return null}}static async#a(a){return await new n().initialize({...a,databaseName:l,additionalFolder:E,migrationsFolder:_})}static async#t(a){return await new n().initialize({...a,databaseName:s,additionalFolder:i,migrationsFolder:r})}static async#e(a){const t=process.env.SQLD_REMOTE_DATABASE_URL&&process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN,A=a.sqldRemoteDatabaseUrl&&a.sqldRemoteDatabaseAuthToken;if(!t&&!A)return process.env.NEW_CATALOG_ENABLED==="true"&&e.warn("SQLD_REMOTE_DATABASE_URL and SQLD_REMOTE_DATABASE_AUTH_TOKEN env variables or sqldRemoteDatabaseUrl and sqldRemoteDatabaseAuthToken options not set - remote database will not be initialized"),null;try{return await O.getConnection({config:{...a,databaseName:T,additionalFolder:c,migrationsFolder:D,syncUrl:process.env.SQLD_REMOTE_DATABASE_URL||a.sqldRemoteDatabaseUrl,authToken:process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN||a.sqldRemoteDatabaseAuthToken},strategy:new L})}catch(o){return e.error("Remote database connection initialization failed",o),null}}}export{g as DatabaseConnectionFactory};
1
+ import{logger as n}from"../../tools/notifiers/logger.js";import{isLocalDevelopment as i}from"../../../utils/env/is-local-development.js";import{CATALOG_LOCAL_DATABASE_FOLDER as A,CATALOG_LOCAL_DATABASE_MIGRATIONS_FOLDER as s,CATALOG_LOCAL_DATABASE_NAME as l,MAIN_LOCAL_DATABASE_FOLDER as _,MAIN_LOCAL_DATABASE_MIGRATIONS_FOLDER as c,MAIN_LOCAL_DATABASE_NAME as E,SQLD_REMOTE_DATABASE_FOLDER as D,SQLD_REMOTE_DATABASE_MIGRATIONS_FOLDER as T,SQLD_REMOTE_DATABASE_NAME as L}from"./constants.js";import{LocalDatabaseInitializationStrategy as o,RemoteDatabaseInitializationStrategy as d}from"./database-initialization-strategy.js";import{DatabaseConnectionsManager as m}from"./database-connections-manager.js";import{SQLD_REMOTE_DATABASE_URL_NO_DEPLOYMENT_YET_VAR as O}from"../../constants/plugins/catalog-entities.js";class N{static async create(a,t){switch(a){case"main-local":return await this.#a(t);case"catalog-local":return await this.#t(t);case"sqld-remote":return await this.#e(t);default:return null}}static async#a(a){return await new o().initialize({...a,databaseName:E,additionalFolder:_,migrationsFolder:c})}static async#t(a){return await new o().initialize({...a,databaseName:l,additionalFolder:A,migrationsFolder:s})}static async#e(a){try{const t=process.env.SQLD_REMOTE_DATABASE_URL||a.sqldRemoteDatabaseUrl,e=t===O?void 0:t,r=process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN||a.sqldRemoteDatabaseAuthToken;return(!e||!r)&&!i()?(n.warn("Your remote database is not initialized yet, please wait for production deployment."),null):await m.getConnection({config:{...a,databaseName:L,additionalFolder:D,migrationsFolder:T,syncUrl:e,authToken:process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN||a.sqldRemoteDatabaseAuthToken},strategy:new d})}catch(t){return n.error("Remote database connection initialization failed",t),null}}}export{N as DatabaseConnectionFactory};
@@ -157,54 +157,60 @@ export declare const scorecardsConfigTable: import("drizzle-orm/sqlite-core").SQ
157
157
  archivedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
158
158
  name: "archived_at";
159
159
  tableName: "scorecards_config";
160
- dataType: "number";
161
- columnType: "SQLiteInteger";
162
- data: number;
163
- driverParam: number;
160
+ dataType: "string";
161
+ columnType: "SQLiteText";
162
+ data: string;
163
+ driverParam: string;
164
164
  notNull: false;
165
165
  hasDefault: false;
166
166
  isPrimaryKey: false;
167
167
  isAutoincrement: false;
168
168
  hasRuntimeDefault: false;
169
- enumValues: undefined;
169
+ enumValues: [string, ...string[]];
170
170
  baseColumn: never;
171
171
  identity: undefined;
172
172
  generated: undefined;
173
- }, {}, {}>;
173
+ }, {}, {
174
+ length: number | undefined;
175
+ }>;
174
176
  createdAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
175
177
  name: "created_at";
176
178
  tableName: "scorecards_config";
177
- dataType: "number";
178
- columnType: "SQLiteInteger";
179
- data: number;
180
- driverParam: number;
179
+ dataType: "string";
180
+ columnType: "SQLiteText";
181
+ data: string;
182
+ driverParam: string;
181
183
  notNull: true;
182
184
  hasDefault: false;
183
185
  isPrimaryKey: false;
184
186
  isAutoincrement: false;
185
187
  hasRuntimeDefault: false;
186
- enumValues: undefined;
188
+ enumValues: [string, ...string[]];
187
189
  baseColumn: never;
188
190
  identity: undefined;
189
191
  generated: undefined;
190
- }, {}, {}>;
192
+ }, {}, {
193
+ length: number | undefined;
194
+ }>;
191
195
  updatedAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
192
196
  name: "updated_at";
193
197
  tableName: "scorecards_config";
194
- dataType: "number";
195
- columnType: "SQLiteInteger";
196
- data: number;
197
- driverParam: number;
198
+ dataType: "string";
199
+ columnType: "SQLiteText";
200
+ data: string;
201
+ driverParam: string;
198
202
  notNull: true;
199
203
  hasDefault: false;
200
204
  isPrimaryKey: false;
201
205
  isAutoincrement: false;
202
206
  hasRuntimeDefault: false;
203
- enumValues: undefined;
207
+ enumValues: [string, ...string[]];
204
208
  baseColumn: never;
205
209
  identity: undefined;
206
210
  generated: undefined;
207
- }, {}, {}>;
211
+ }, {}, {
212
+ length: number | undefined;
213
+ }>;
208
214
  };
209
215
  dialect: "sqlite";
210
216
  }>;
@@ -1 +1 @@
1
- import{sqliteTable as o,text as e,integer as n,index as t}from"drizzle-orm/sqlite-core";const c=o("scorecards_config",{id:e("id").primaryKey().notNull(),key:e("key").notNull(),slug:e("slug").notNull(),name:e("name").notNull(),description:e("description"),entitiesFilter:e("entities_filter").notNull(),levels:e("levels").notNull(),configHash:e("config_hash").notNull(),archivedAt:n("archived_at"),createdAt:n("created_at").notNull(),updatedAt:n("updated_at").notNull()},i=>[t("idx_config_key").on(i.key),t("idx_config_slug").on(i.slug),t("idx_config_hash").on(i.configHash),t("idx_config_archived").on(i.archivedAt)]);export{c as scorecardsConfigTable};
1
+ import{sqliteTable as n,text as e,index as t}from"drizzle-orm/sqlite-core";const l=n("scorecards_config",{id:e("id").primaryKey().notNull(),key:e("key").notNull(),slug:e("slug").notNull(),name:e("name").notNull(),description:e("description"),entitiesFilter:e("entities_filter").notNull(),levels:e("levels").notNull(),configHash:e("config_hash").notNull(),archivedAt:e("archived_at"),createdAt:e("created_at").notNull(),updatedAt:e("updated_at").notNull()},i=>[t("idx_config_key").on(i.key),t("idx_config_slug").on(i.slug),t("idx_config_hash").on(i.configHash),t("idx_config_archived").on(i.archivedAt)]);export{l as scorecardsConfigTable};
@@ -1 +1 @@
1
- import{logger as g}from"../../tools/notifiers/logger.js";import{reporter as m}from"../../tools/notifiers/reporter.js";import{enhanceContext as f}from"../../api-routes/helpers/enhance-context.js";import{KvService as l}from"../../persistence/kv/services/kv-service.js";import{enhanceRequest as u}from"../../api-routes/helpers/enhance-request.js";async function S({route:r,ctx:t,staticData:n,serverPropsGetters:a,serverPropsUser:p,actions:s}){try{if(!a[r.fsPath]||!t)return;const e=a[r.fsPath];e||await m.panicOnBuild(`Invalid page props getter id: "${r.fsPath}" for route "${r.slug}"`);const o=async()=>await l.getInstance({baseDbDir:s.serverOutDir,sqldRemoteDatabaseUrl:process.env.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),c=f({honoCtx:t,ctx:{user:p,config:s.getConfig()},getKv:o}),i=await u(t);return await(await e()).default(n,i,c)}catch(e){const o=r.fsPath.replace(/\.(page\.tsx?|md)$/,".props.ts");return g.error(`Page prop getter error: ${e.message}`),{pagePropGetterError:{message:`${e.message||"An unknown error occurred"} in ${o}`,name:"ServerPropsGetterError",stack:e.stack}}}}export{S as getServerPropsFromUserHandler};
1
+ import{logger as i}from"../../tools/notifiers/logger.js";import{reporter as m}from"../../tools/notifiers/reporter.js";import{enhanceContext as f}from"../../api-routes/helpers/enhance-context.js";import{KvService as l}from"../../persistence/kv/services/kv-service.js";import{enhanceRequest as u}from"../../api-routes/helpers/enhance-request.js";async function S({route:r,ctx:t,staticData:n,serverPropsGetters:a,serverPropsUser:p,actions:s}){try{if(!a[r.fsPath]||!t)return;const e=a[r.fsPath];e||await m.panicOnBuild(`Invalid page props getter id: "${r.fsPath}" for route "${r.slug}"`);const o=async()=>l.getInstance({baseDbDir:s.serverOutDir,sqldRemoteDatabaseUrl:process.env.SQLD_REMOTE_DATABASE_URL,sqldRemoteDatabaseAuthToken:process.env.SQLD_REMOTE_DATABASE_AUTH_TOKEN}),c=f({honoCtx:t,ctx:{user:p,config:s.getConfig()},getKv:o}),g=await u(t);return await(await e()).default(n,g,c)}catch(e){const o=r.fsPath.replace(/\.(page\.tsx?|md)$/,".props.ts");return i.error(`Page prop getter error: ${e.message}`),{pagePropGetterError:{message:`${e.message||"An unknown error occurred"} in ${o}`,name:"ServerPropsGetterError",stack:e.stack}}}}export{S as getServerPropsFromUserHandler};
@@ -8,6 +8,7 @@ import type { SearchFacet } from '@redocly/theme/core/types';
8
8
  import type { BundledDefinition as OpenApiBundledDefinition } from './plugins/openapi-docs/load-definition.js';
9
9
  import type { BundledDefinition as AsyncApiBundledDefinition } from './plugins/asyncapi-docs/asyncapi-doc-loader.js';
10
10
  import type { SearchEngine } from './plugins/search/engines/search-engine.js';
11
+ import { KvService } from './persistence/kv/services/kv-service.js';
11
12
  export declare const MARKDOC_PARTIALS_DATA_KEY = "markdown/partials";
12
13
  export declare const MARKDOC_PARTIALS_DEPS_KEY = "markdown/partials-deps";
13
14
  export declare const USER_DEFINED_API_FUNCTIONS_COUNTER_KEY = "userDefinedApiFunctions";
@@ -91,7 +92,7 @@ export declare class Store {
91
92
  frontMatterKeysToResolve?: string[] | undefined;
92
93
  partialsFolders?: string[] | undefined;
93
94
  lastUpdatedBlock?: {
94
- format?: "short" | "long" | "timeago" | "iso" | undefined;
95
+ format?: "timeago" | "iso" | "long" | "short" | undefined;
95
96
  hide?: boolean | undefined;
96
97
  locale?: string | undefined;
97
98
  } | undefined;
@@ -117,6 +118,7 @@ export declare class Store {
117
118
  };
118
119
  setGlobalData: (data: GlobalData) => void;
119
120
  getGlobalData: () => GlobalData;
121
+ getKv: () => Promise<KvService>;
120
122
  parseMarkdoc: (input: MarkdownParseInput, context: LifecycleContext, deps?: MarkdocDeps) => Promise<{
121
123
  info: {
122
124
  sharedDataDeps?: Set<string>;