@redocly/realm 0.136.0-next.7 → 0.136.0-next.9
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.
- package/CHANGELOG.md +42 -0
- package/dist/server/api-routes/helpers/enhance-context.js +1 -1
- package/dist/server/api-routes/run-api-routes-worker.js +1 -1
- package/dist/server/config/env-config.d.ts +0 -2
- package/dist/server/config/env-schema.d.ts +0 -5
- package/dist/server/config/env-schemas/feature-flags.d.ts +0 -4
- package/dist/server/config/env-schemas/feature-flags.js +1 -1
- package/dist/server/plugins/catalog-entities/database/repositories/catalog-entities-repository.js +1 -1
- package/dist/server/plugins/mcp/codemode/capabilities/types.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/capabilities/utils.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/code-audit.d.ts +12 -0
- package/dist/server/plugins/mcp/codemode/code-audit.js +1 -0
- package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +11 -0
- package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -0
- package/dist/server/plugins/mcp/codemode/tools/describe-tools.d.ts +2 -3
- package/dist/server/plugins/mcp/codemode/tools/execute-schema.d.ts +1 -1
- package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
- package/dist/server/plugins/mcp/constants.d.ts +1 -1
- package/dist/server/plugins/mcp/constants.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +19 -18
- package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +2 -2
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-bridge.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.d.ts +2 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/fetch-telemetry.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.d.ts +6 -0
- package/dist/server/plugins/mcp/gateway-mcp/fetch/normalize-path.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/rate-limit/apply-edge-rate-limit.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.d.ts +8 -0
- package/dist/server/plugins/mcp/gateway-mcp/rate-limit/rate-limit-telemetry.js +1 -0
- package/dist/server/plugins/mcp/gateway-mcp/upstream-auth.d.ts +1 -1
- package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
- package/dist/server/plugins/mcp/handlers/errors.js +1 -1
- package/dist/server/plugins/mcp/servers/docs-server.d.ts +2 -3
- package/dist/server/plugins/mcp/servers/docs-server.js +1 -1
- package/dist/server/plugins/mcp/servers/mcp-server.d.ts +10 -14
- package/dist/server/plugins/mcp/servers/mcp-server.js +1 -1
- package/dist/server/plugins/mcp/types.d.ts +6 -6
- package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +9 -0
- package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -0
- package/dist/server/plugins/mcp/utils/mode.js +1 -1
- package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +9 -1
- package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +2 -2
- package/dist/server/plugins/search/engines/flexsearch/index.js +1 -1
- package/dist/server/plugins/search/engines/flexsearch/search-index.js +1 -1
- package/dist/server/plugins/search/engines/typesense/index.js +1 -1
- package/dist/server/tools/notifiers/logger.js +1 -1
- package/dist/server/tools/notifiers/reporter.js +6 -6
- package/dist/server/types/plugins/common.d.ts +1 -1
- package/dist/server/web-server/auth.js +3 -3
- package/dist/server/web-server/middleware/telemetry-middleware.js +1 -1
- package/dist/server/web-server/routes/catalog/bff-catalog-related-entities.js +1 -1
- package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -1
- package/dist/server/web-server/routes/catalog/bff-catalog.js +1 -1
- package/dist/server/web-server/routes/catalog/catalog-relations.js +1 -1
- package/dist/server/web-server/routes/catalog/catalog.js +1 -1
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/a2a.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/agent-card.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-server-card.js +1 -1
- package/dist/server/web-server/routes/page-data.js +1 -1
- package/dist/server/web-server/routes/search.js +1 -1
- package/dist/server/web-server/routes/skills/skill-markdown.js +1 -1
- package/dist/server/web-server/routes/skills/skills-index.js +1 -1
- package/dist/utils/url/parse-preview-url.d.ts +22 -0
- package/dist/utils/url/parse-preview-url.js +1 -0
- package/package.json +9 -10
- package/dist/server/plugins/mcp/handlers/sse-keepalive.d.ts +0 -15
- package/dist/server/plugins/mcp/handlers/sse-keepalive.js +0 -3
- package/dist/server/plugins/mcp/servers/session-manager.d.ts +0 -15
- package/dist/server/plugins/mcp/servers/session-manager.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import m from"path";import{REDOCLY_ROUTE_RBAC as
|
|
1
|
+
import m from"path";import{REDOCLY_ROUTE_RBAC as M,REDOCLY_TEAMS_RBAC as S}from"@redocly/config";import{combineUrls as V,withoutPathPrefix as W,withPathPrefix as Z}from"@redocly/theme/core/utils";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as D,CACHE_CONTROL_PUBLIC_HTML as J,DEFAULT_IMMUTABLE_CACHE_MAX_AGE as K,X_REDOCLY_CACHE_CONTROL_HEADER as Q,X_REDOCLY_CACHE_CONTROL_PUBLIC_HTML as x}from"../../constants/common.js";import{removeTrailingSlash as ee}from"../../../utils/url/remove-trailing-slash.js";import{findInIterable as te}from"../../../utils/collection/find-in-iterable.js";import{sanitizeRedirectPathname as ne}from"../../../utils/url/sanitize-redirect-pathname.js";import{envConfig as re}from"../../config/env-config.js";import{sanitizePath as oe}from"../../../utils/path/sanitize-path.js";import{normalizeRouteSlug as ie}from"../../../utils/path/normalize-route-slug.js";import{isPathInFolder as ae}from"../../../utils/path/is-path-in-folder.js";import{getLlmsTxtMdPathBySlug as se}from"../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{removeLeadingSlash as H}from"../../../utils/url/remove-leading-slash.js";import{processRedirects as ce}from"./helpers/process-redirects.js";import{renderPage as le,getServerProps as me}from"../../ssr/index.js";import{canAccessAsset as ue,canAccessResource as q}from"../../utils/rbac.js";import{handleErrorPageRender as v,handleUnauthorized as B,handleUnauthorizedAsset as F}from"../utils.js";import{DEFAULT_MAX_AGE_FOR_MIME_TYPE as de,MIME_TYPES as ge}from"../mime-types.js";import{fileExistsAsync as z}from"../../utils/index.js";import{isAiAgentRequest as fe}from"../../utils/ai-agent-detection.js";import{getRedirectRoute as pe}from"../utils/legacy-openapi-redirects.js";import{getContentTypeHeaderValue as he}from"../utils/content-type.js";import{telemetry as Re}from"../../../cli/telemetry/index.js";import{telemetry as Ce}from"../../telemetry/index.js";function ke(e,Y,G){return async n=>{const A=n.get("logger"),i=n.req,a=new URL(i.url),o=W(oe(decodeURIComponent(a.pathname))),E=m.parse(o).ext===".md",L=fe({accept:i.header("accept"),signatureAgent:i.header("signature-agent"),signature:i.header("signature"),signatureInput:i.header("signature-input"),userAgent:i.header("user-agent")}),s=ie(o),r=(i.method==="GET"||i.method==="HEAD")&&!E?e.getRouteBySlug(s,{followRedirect:!1})||te(e.routesBySlug?.values(),t=>t.hasClientRoutes&&(o===t.slug||o.startsWith(t.slug+"/"))):void 0,_=e.getRedirect(s);if(_){const t=ce({redirect:_,reqUrlSearch:a.search});return Ce.sendRedirectMessage([{id:s,object:"redirect",uri:`urn:redocly:realm:api:redirect:${s}`,from:s,templateId:t.type.toString()}]),n.newResponse(null,t.type,{Location:t.location})}const f=re.isProductionEnv?301:302;if(r?.metadata?.type==="openapi"){const t=pe(a.pathname);if(t)return A.info("Legacy OpenAPI docs redirect from "+a.pathname),n.newResponse(null,f,{Location:encodeURI(t)});if(a.pathname.match(/[A-Z]/))return A.warn("Redirect to lowercase route to avoid 404 error"),n.newResponse(null,f,{Location:encodeURI(a.pathname.toLowerCase())})}if(o.endsWith("/")&&o!=="/"){const t=ne(new URL(s||"/",n.req.url).pathname);return n.newResponse(null,f,{Location:encodeURI(Z((t==="/"?"/":ee(t))+a.search))})}const u=r&&L?se(r.slug):void 0,w=u?await z(m.resolve(e.outdir,H(u))):!1,{isAuthenticated:d,teams:p,claims:{email:h}}=n.get("auth");if(r&&!q(r,{isAuthenticated:d,email:h,teams:p},e.config.access?.rbac,e.config.access?.requiresLogin))return d?v(n,e,{slug:r.slug,[S]:r[S],[M]:r[M]},403):B(n,e,r.slug);if(r&&(!L||!w)){const t=await Y(r),C=await me(r,n,t,e),{html:$,statusCode:U,error:k}=await le(r,C,n,e,Re),b=e.config.access?.rbac,O=!e.config.access?.requiresLogin&&(!b||!Object.keys(b).length),I=U>=400||!!k||!!e.compilationErrors?.length,j=O&&!I;let g;return I?g=D:O?g=J:g="private",n.html($,U,{"Cache-Control":g,...j&&{[Q]:x}})}const P=u&&w?u:o,N=H(P),c=m.resolve(e.outdir,N);if(!ae(c,e.outdir))return F(n);let l;if(E){const t=o==="/index.html.md"?"/":o.replace(/\.md$/,"");if(l=e.getRouteBySlug(t,{followRedirect:!1}),l&&!q(l,{isAuthenticated:d,email:h,teams:p},e.config.access?.rbac,e.config.access?.requiresLogin))return B(n,e,o)}const T=e.getGlobalConfig("access");if(!ue(P,T?.rbac||{},T?.requiresLogin||!1,e.getGlobalConfig("directoryPaths"),{isAuthenticated:d,email:h,teams:p}))return F(n);const y=ge[m.extname(c)]||"text/plain",R=c.match(/assets\/.*\.[a-f0-9]{8,}\..+/)||c.match(/runtime\/chunks\/.*/)?K:de[y],X=R?{"Cache-Control":`public, max-age=${R}, immutable`,Expires:new Date(Date.now()+R*1e3).toUTCString()}:{"Cache-Control":D};if(await z(c)){const t=i.query("download")!=null,C=await G(c);return n.newResponse(C,200,{"Content-Type":he(y),"Access-Control-Allow-Origin":"*",...X,...l&&{"X-Robots-Tag":"noindex, follow",...e.config.seo?.siteUrl&&{Link:`<${V(e.config.seo.siteUrl,l.slug)}>; rel="canonical"`}},...t&&{"Content-Disposition":`attachment; filename="${m.basename(c)}"`}})}else return v(n,e,{slug:s},404)}}export{ke as dynamicRouteHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{withPathPrefix as
|
|
1
|
+
import{withPathPrefix as i}from"@redocly/theme/core/utils";import{MCP_SERVER_CARD_SLUG as a}from"../../../../constants/common.js";import{telemetryTraceStep as l}from"../../../telemetry/helpers/trace-step.js";import{SKILLS_INDEX_SLUG as n}from"../skills/constants.js";function f(s){return async o=>await l("com.redocly.a2a.requested",async e=>{const r=s.config.skills?.hide!==!0,t=[`<${i(a)}>; rel="mcp-server-card"`];return r&&t.push(`<${i(n)}>; rel="agent-skills"`),e?.setAttribute("skillsAdvertised",r),e?.setAttribute("object","a2a"),e?.setAttribute("id","a2aId"),e?.setAttribute("uri","urn:redocly:realm:api:a2a:a2aId"),o.json({error:{code:"405",message:"Method not allowed"}},405,{Link:t.join(", ")})})}export{f as a2aHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as
|
|
1
|
+
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as c}from"../../../constants/common.js";import{telemetryTraceStep as d}from"../../../telemetry/helpers/trace-step.js";import{getAccessibleSkills as g}from"../../../utils/skills/get-accessible-skills.js";import{resolvePublicBaseUrl as m}from"../../../web-server/utils/resolve-public-base-url.js";import{shouldHandleMcpAuth as A}from"../../../plugins/mcp/auth/auth-handlers.js";import{buildAgentCard as C}from"./utils/build-agent-card.js";function y(e){return async r=>await d("com.redocly.agentCard.served",async t=>{if(t?.setAttribute("id","agentCardId"),t?.setAttribute("object","agentCard"),t?.setAttribute("uri","urn:redocly:realm:api:agentCard:agentCardId"),e.config.skills?.hide===!0)return r.newResponse(null,404);const{isAuthenticated:l,teams:a,claims:{email:u}}=r.get("auth"),i=e.config.access?.rbac||{},n=!!e.config.access?.requiresLogin,s=g(e.getSkills(),{isAuthenticated:l,teams:a,email:u},i,n),o=A(n,i);return t?.setAttribute("skillsCount",s.length),t?.setAttribute("mcpAuthRequired",o),r.json(C({seo:e.getGlobalConfig("seo"),baseUrl:m(e,r),skills:s,mcpAuthRequired:o}),200,{"Cache-Control":c,"Access-Control-Allow-Origin":"*"})})}export{y as agentCardHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{withPathPrefix as S}from"@redocly/theme/core/utils";import{DEFAULT_DOCS_MCP_SERVER_NAME as h,MCP_PROTOCOL_VERSION as f}from"../../../plugins/mcp/constants.js";import{RESERVED_ROUTES as O}from"../../../plugins/get-reserved-routes.js";import{isMcpCodeModeEnabled as A}from"../../../plugins/mcp/utils/mode.js";import{CODE_MODE_TOOL_NAMES as T,DESCRIBE_TOOLS_TOOL_NAME as b,FETCH_TOOL_NAME as M}from"../../../plugins/mcp/codemode/constants.js";import{EXECUTE_TOOL_SCHEMA as R}from"../../../plugins/mcp/codemode/tools/execute-schema.js";import{describeToolsSchema as g}from"../../../plugins/mcp/codemode/tools/describe-tools.js";import{buildCodeModeInstructions as v,buildExecuteDescription as I,DESCRIBE_TOOLS_DESCRIPTION as L}from"../../../plugins/mcp/codemode/prompts.js";import{composeExecuteAnnotations as D}from"../../../plugins/mcp/codemode/capabilities/index.js";import{ALL_CAPABILITIES as P}from"../../../plugins/mcp/codemode/capabilities/registry.js";import{isGatewayCapabilityEnabled as y}from"../../../plugins/mcp/gateway-mcp/eligibility.js";import{shouldHandleMcpAuth as V}from"../../../plugins/mcp/auth/auth-handlers.js";import{resolvePublicBaseUrl as H}from"../../../web-server/utils/resolve-public-base-url.js";import{telemetryTraceStep as N}from"../../../telemetry/helpers/trace-step.js";import{MCP_AUTH_SCHEMES as U}from"./constants.js";const x="https://static.modelcontextprotocol.io/schemas/mcp-server-card/v1.json",w="1.0";function oe(r){const i=A(),u=new Date().toISOString().slice(0,10);return async c=>await N("com.redocly.mcpServerCard.served",async e=>{e?.setAttribute("id","mcpServerCardId"),e?.setAttribute("object","mcpServerCard"),e?.setAttribute("uri","urn:redocly:realm:api:mcpServerCard:mcpServerCardId");const o=r.getConfig(),m=o.mcp?.docs?.name||h,a=r.getMcpTools().filter(t=>!T.has(t.name)),s=y(o.mcp)?[...P]:[],d=s.some(t=>t.id===M),n=(i?[{...R,description:I(d),annotations:D(s)},{name:b,description:L,schema:g(a,s)}]:a).map(({name:t,description:E,schema:_,annotations:p})=>({name:t,description:E,inputSchema:_,...p?{annotations:p}:{}})),C=o.skills?.hide===!0?[]:r.getSkills(),l={$schema:x,version:w,protocolVersion:f,serverInfo:{name:m,title:m,version:u},description:o.seo?.description,documentationUrl:H(r,c),transport:{type:"streamable-http",endpoint:S(O.mcp)},capabilities:{logging:{},tools:{listChanged:!0},...C.length>0?{resources:{listChanged:!0},completions:{}}:{}},authentication:V(!!o.access?.requiresLogin,o.access?.rbac)?{required:!0,schemes:U}:void 0,instructions:i?v(d):void 0,tools:n.length>0?n:["dynamic"]};return e?.setAttribute("mode",i?"code":"tools"),e?.setAttribute("toolsCount",n.length),e?.setAttribute("authRequired",l.authentication!==void 0),c.json(l,200,{"Access-Control-Allow-Origin":"*","Cache-Control":"public, max-age=3600"})})}export{oe as mcpServerCardHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ServerRoutes as
|
|
1
|
+
import{ServerRoutes as $}from"../../../constants/api.js";import{DEV_LOGIN_SLUG as w}from"../../../constants/common.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as a,DEFAULT_TITLE as U}from"../../constants/common.js";import{findInIterable as F}from"../../../utils/collection/find-in-iterable.js";import{removeTrailingSlash as N}from"../../../utils/url/remove-trailing-slash.js";import{envConfig as b}from"../../config/env-config.js";import{canAccessResource as q,filterDataByAccessDeep as T,isResourcePubliclyAccessible as B}from"../../utils/rbac.js";import{getServerProps as H}from"../../ssr/index.js";import{readSharedData as M}from"../../utils/index.js";import{getRedirectLoginUrl as G}from"../utils/get-redirect-login-url.js";import{processRedirects as V}from"./helpers/process-redirects.js";import{removeErrorDetails as W}from"../utils/remove-error-details.js";import{telemetry as k}from"../../telemetry/index.js";import{MCP_NOT_ALLOWED_TEMPLATE_ID as K}from"../../plugins/mcp/constants.js";function ie(e,n){return async(t,g)=>{const m=t.get("logger"),{req:p}=t,{pathname:d}=new URL(p.url),{seo:f,ssoDirect:h}=e.getConfig(),i=f?.title||U;if(e?.compilationErrors?.length&&b.isDevelopMode)return t.json({templateId:"compilation-error",props:{compilationErrors:e?.compilationErrors},sharedDataIds:{}},500,{"Cache-Control":a});const u=d.match(/page-data(.*)data.json$/);if(!u)return g();const c=decodeURI(u[1]),r=c==="/index/"?"/":N(c),o=e.getRouteBySlug(r,{followRedirect:!1})||F(e.routesBySlug.values(),s=>s.hasClientRoutes&&c.startsWith(s.slug+"/"));if(c===$.OIDC_CALLBACK+"/")return t.json({templateId:"403OIDC",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}}},200,{"Cache-Control":a});const{isAuthenticated:C,teams:D,claims:{name:j,picture:A,email:I}}=t.get("auth"),R={isAuthenticated:C,email:I,teams:D},l={isAuthenticated:C,name:j,picture:A,email:I,teams:D};if(r==="/mcp"&&e.globalData.mcpData?.docs?.enabled)return t.json({templateId:K,sharedDataIds:{},props:{},userData:l},405,{"Cache-Control":a});const L=e.getRedirect(r);if(L){const s=V({redirect:L}).location;return k.sendRedirectMessage([{id:r,object:"redirect",uri:`urn:redocly:realm:api:redirect:${r}`,from:r,templateId:"404"}]),t.json({templateId:"404",redirectTo:s,sharedDataIds:{},props:{}},301,{"Cache-Control":a})}if(!o){const s=e.getRouteBySlug(r,{followRedirect:!0});return m.error(`Page not found: ${d}`),t.json({templateId:"404",redirectTo:s?.slug,sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l},404,{"Cache-Control":a})}if(m.verbose(`Page viewed: ${o.slug}`),!q(o,R,e.config.access?.rbac,e.config.access?.requiresLogin)&&o.slug!==w){if(C)return t.json({templateId:"403",sharedDataIds:{},props:{seo:{title:`${i} - Forbidden`}},userData:l},403,{"Cache-Control":a});const s=Object.keys(h||{}).length>0;return t.json({templateId:"404",sharedDataIds:{},props:{seo:{title:`${i} - Not Found`}},userData:l,...s?{redirectTo:G(e,o.slug)}:{}},s?401:404,{"Cache-Control":a})}const S=T(o.versions,R,e.config.access?.rbac,e.config.access?.requiresLogin),_=e.routesSharedData.get(o.slug)||{},v=await n(o),P=await H(o,t,v,e),{sharedDataIds:y,...E}=P,O={templateId:o.templateId,versions:S,sharedDataIds:{..._,...y||{}},props:b.isProductionEnv?W(E):E,slug:o.slug,userData:l,isPublic:B(o,e.config)};return t.json(O,200,{"Cache-Control":a})}}function ce(e){return async(n,t)=>{const g=n.get("logger"),{req:m}=n,{pathname:p}=new URL(m.url),d=p.match(/\/page-data\/shared\/(.*)\.json/);if(!d)return t();const f=decodeURIComponent(d[1]),h=await M(f,e.outdir),{isAuthenticated:i,teams:u,claims:{email:c}}=n.get("auth"),r=T(h,{isAuthenticated:i,email:c,teams:u},e.config.access?.rbac,e.config.access?.requiresLogin);return r?n.json(r,200,{"Cache-Control":a}):(g.error(`Shared data not found: ${p}`),n.text("Not Found",404,{"Cache-Control":a}))}}export{ie as pageDataHandler,ce as sharedPageDataHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{telemetryTraceStep as
|
|
1
|
+
import{telemetryTraceStep as b}from"../../telemetry/helpers/trace-step.js";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as C}from"../../constants/common.js";import{expandTeamsForRead as E}from"../../utils/rbac.js";function v(t){return async s=>(s.header("Cache-Control",C),await b("com.redocly.search.performed",async e=>{e?.setAttribute("id","searchQueryId"),e?.setAttribute("object","searchQuery"),e?.setAttribute("uri","urn:redocly:realm:api:searchQuery:searchQueryId");const i=s.get("logger"),r=s.get("auth"),d=i.startTiming(),a=t.getConfig().access?.requiresLogin&&!r.isAuthenticated,u=s.req.valid("json");e?.setAttribute("engine",t?.searchEngine?.type),e?.setAttribute("query",u.query||""),e?.setAttribute("user",r.claims.email??"anonymous"),e?.setAttribute("noAccess",a);const l=t.getSearchFacets(),o=a?{}:t.searchEngine?await t.searchEngine.search(u,{...r,teams:E(t.config.access?.rbac,r.teams)},l):{};let h=0;if(Object.keys(o).length){const g=o.documents;for(const[c,n]of Object.entries(g))h+=n.length}return i.infoTime(d,`Search with query "${u.query||""}". Total results: ${h}`),e?.setAttribute("resultsCount",h),s.json(o)}))}function p(t){return async s=>(s.header("Cache-Control",C),await b("com.redocly.search.facets",async e=>{e?.setAttribute("id","searchFacetsId"),e?.setAttribute("object","searchFacets"),e?.setAttribute("uri","urn:redocly:realm:api:searchFacets:searchFacetsId");const i=s.get("logger"),r=s.get("auth"),m=t.getConfig().access?.requiresLogin&&!r.isAuthenticated,a=s.req.valid("json");e?.setAttribute("engine",t?.searchEngine?.type),e?.setAttribute("user",r.claims.email??"anonymous"),e?.setAttribute("noAccess",m);const u=i.startTiming(),l=t.getSearchFacets(),o=m?{}:t.searchEngine?await t.searchEngine.countFacets(a,r,l):{},h=!!a.field;let g=[];if(h){const c=a.field,n=c&&l.get(c);if(n){const f={...n};f.values=o?.[c]||[],g.push(f)}}else{const c=new Map;for(const[n,f]of l){const y=o?.[n],A={...f};A.values=y||f.values.map(T=>({value:T,count:0})),c.set(n,A)}g=Array.from(c,([,n])=>n)}return i.verboseTime(u,"Search facets"),s.json(g)}))}export{p as searchFacetsHandler,v as searchHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as c}from"../../../constants/common.js";import{telemetryTraceStep as a}from"../../../telemetry/helpers/trace-step.js";import{canAccessSkill as
|
|
1
|
+
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as c}from"../../../constants/common.js";import{telemetryTraceStep as a}from"../../../telemetry/helpers/trace-step.js";import{canAccessSkill as u}from"../../../utils/skills/can-access-skill.js";import{MIME_TYPES as m}from"../../mime-types.js";import{getContentTypeHeaderValue as g}from"../../utils/content-type.js";function y(n){return async e=>await a("com.redocly.agentSkill.served",async t=>{t?.setAttribute("object","agentSkill");const r=e.req.param("slug")??"";if(t?.setAttribute("id",r),t?.setAttribute("uri",`urn:redocly:realm:api:agentSkill:${r}`),t?.setAttribute("skill",r),n.config.skills?.hide===!0)return e.newResponse(null,404);const s=n.skills.get(r),{isAuthenticated:i,teams:l,claims:{email:o}}=e.get("auth");return s&&u(s,{isAuthenticated:i,teams:l,email:o},n.config.access?.rbac,n.config.access?.requiresLogin)?e.newResponse(s.content,200,{"Content-Type":g(m[".md"]),"Cache-Control":c,"Access-Control-Allow-Origin":"*"}):e.newResponse(null,404)})}export{y as skillMarkdownHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as o}from"../../../constants/common.js";import{telemetryTraceStep as
|
|
1
|
+
import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as o}from"../../../constants/common.js";import{telemetryTraceStep as u}from"../../../telemetry/helpers/trace-step.js";import{getAccessibleSkills as a}from"../../../utils/skills/get-accessible-skills.js";import{resolvePublicBaseUrl as c}from"../../utils/resolve-public-base-url.js";import{buildSkillsIndex as d}from"./build-skills-index.js";function f(e){return async l=>await u("com.redocly.agentSkillsIndex.served",async i=>{if(i?.setAttribute("id","agentSkillsIndexId"),i?.setAttribute("object","agentSkillsIndex"),i?.setAttribute("uri","urn:redocly:realm:api:agentSkillsIndex:agentSkillsIndexId"),e.config.skills?.hide===!0)return i?.setAttribute("skillsCount",0),l.newResponse(null,404);const{isAuthenticated:s,teams:n,claims:{email:r}}=l.get("auth"),t=a(e.getSkills(),{isAuthenticated:s,teams:n,email:r},e.config.access?.rbac,e.config.access?.requiresLogin);return i?.setAttribute("skillsCount",t.length),l.json(d(t,c(e,l)),200,{"Cache-Control":o,"Access-Control-Allow-Origin":"*"})})}export{f as skillsIndexHandler};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses an absolute preview URL string. Accepts `https:` on any host, and `http:`
|
|
3
|
+
* only on `localhost` hosts, which is how previews are served in the local dev
|
|
4
|
+
* environment. Returns `null` on parse errors and for any other scheme/host pair.
|
|
5
|
+
*
|
|
6
|
+
* @param uri - Absolute URL string to parse.
|
|
7
|
+
* @returns A `URL` when the string is a valid preview URL; otherwise `null`.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* parsePreviewUrl('https://slug--branch.preview.redocly.app');
|
|
12
|
+
* // URL { href: 'https://slug--branch.preview.redocly.app/' }
|
|
13
|
+
*
|
|
14
|
+
* parsePreviewUrl('http://slug--branch.preview.localhost');
|
|
15
|
+
* // URL { href: 'http://slug--branch.preview.localhost/' }
|
|
16
|
+
*
|
|
17
|
+
* parsePreviewUrl('http://slug--branch.preview.redocly.app');
|
|
18
|
+
* // null
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function parsePreviewUrl(uri: string): URL | null;
|
|
22
|
+
//# sourceMappingURL=parse-preview-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parseHttpsUrl as n}from"./parse-https-url.js";function s(t){const o=n(t);if(o)return o;try{const r=new URL(t);return r.protocol==="http:"&&l(r.hostname)?r:null}catch{return null}}function l(t){return t==="localhost"||t.endsWith(".localhost")}export{s as parsePreviewUrl};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/realm",
|
|
3
|
-
"version": "0.136.0-next.
|
|
3
|
+
"version": "0.136.0-next.9",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"@jitl/quickjs-singlefile-mjs-release-sync": "0.32.0",
|
|
22
22
|
"@libsql/client": "0.17.3",
|
|
23
23
|
"@markdoc/markdoc": "0.5.2",
|
|
24
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
24
25
|
"@opentelemetry/api": "1.9.1",
|
|
25
26
|
"@opentelemetry/context-zone": "2.0.1",
|
|
26
27
|
"@opentelemetry/core": "2.8.0",
|
|
@@ -32,7 +33,6 @@
|
|
|
32
33
|
"@opentelemetry/sdk-trace-web": "2.8.0",
|
|
33
34
|
"@opentelemetry/semantic-conventions": "1.40.0",
|
|
34
35
|
"@redocly/ajv": "8.18.0",
|
|
35
|
-
"@redocly/mcp-typescript-sdk": "1.18.1",
|
|
36
36
|
"@redocly/openapi-core": "2.43.1",
|
|
37
37
|
"@shikijs/transformers": "3.21.0",
|
|
38
38
|
"@tanstack/react-query": "5.62.3",
|
|
@@ -51,11 +51,10 @@
|
|
|
51
51
|
"enquirer": "2.3.6",
|
|
52
52
|
"esbuild": "0.28.1",
|
|
53
53
|
"escape-carriage": "^1.3.1",
|
|
54
|
-
"fetch-to-node": "^2.1.0",
|
|
55
54
|
"fflate": "0.7.4",
|
|
56
55
|
"flexsearch": "0.7.43",
|
|
57
56
|
"graphql": "16.12.0",
|
|
58
|
-
"hono": "4.12.
|
|
57
|
+
"hono": "4.12.34",
|
|
59
58
|
"htmlparser2": "8.0.2",
|
|
60
59
|
"i18next": "22.4.15",
|
|
61
60
|
"is-glob": "4.0.3",
|
|
@@ -94,14 +93,14 @@
|
|
|
94
93
|
"xpath": "0.0.34",
|
|
95
94
|
"yaml-ast-parser": "0.0.43",
|
|
96
95
|
"zod": "^3.25.76",
|
|
97
|
-
"@redocly/api-docs": "0.1.0-next.
|
|
98
|
-
"@redocly/asyncapi-docs": "1.13.0-next.
|
|
96
|
+
"@redocly/api-docs": "0.1.0-next.1",
|
|
97
|
+
"@redocly/asyncapi-docs": "1.13.0-next.8",
|
|
99
98
|
"@redocly/config": "0.53.1",
|
|
100
|
-
"@redocly/graphql-docs": "1.13.0-next.
|
|
101
|
-
"@redocly/openapi-docs": "3.24.0-next.
|
|
99
|
+
"@redocly/graphql-docs": "1.13.0-next.8",
|
|
100
|
+
"@redocly/openapi-docs": "3.24.0-next.8",
|
|
102
101
|
"@redocly/portal-legacy-ui": "0.18.0",
|
|
103
|
-
"@redocly/portal-plugin-mock-server": "0.21.0-next.
|
|
104
|
-
"@redocly/realm-asyncapi-sdk": "0.14.0-next.
|
|
102
|
+
"@redocly/portal-plugin-mock-server": "0.21.0-next.8",
|
|
103
|
+
"@redocly/realm-asyncapi-sdk": "0.14.0-next.2",
|
|
105
104
|
"@redocly/theme": "0.68.0-next.5"
|
|
106
105
|
},
|
|
107
106
|
"peerDependencies": {
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { ServerResponse } from 'node:http';
|
|
2
|
-
export type SseKeepalive = {
|
|
3
|
-
stop: () => void;
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* Wraps res.writeHead so that, the moment the transport starts an SSE response
|
|
7
|
-
* (status 200 + Content-Type: text/event-stream), headers are flushed immediately
|
|
8
|
-
* (so intermediary proxies like CloudFront receive them before their origin
|
|
9
|
-
* response timeout) and SSE comment pings are written on an interval.
|
|
10
|
-
*
|
|
11
|
-
* Returns a handle whose stop() clears the timer; it also auto-stops on the
|
|
12
|
-
* response's 'finish'/'close'/'error' events.
|
|
13
|
-
*/
|
|
14
|
-
export declare function attachSseKeepalive(res: ServerResponse, intervalMs?: number): SseKeepalive;
|
|
15
|
-
//# sourceMappingURL=sse-keepalive.d.ts.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{SSE_KEEPALIVE_INTERVAL_MS as u}from"../constants.js";const s="text/event-stream",d=`: keepalive
|
|
2
|
-
|
|
3
|
-
`;function p(t){const[a,r,o]=t;if(a!==200)return!1;const e=typeof r=="object"&&r!==null?r:o;if(!e||typeof e!="object")return!1;if(!Array.isArray(e)){for(const[n,i]of Object.entries(e))if(n.toLowerCase()==="content-type")return String(i).toLowerCase().includes(s);return!1}if(e.length&&Array.isArray(e[0]))return e.some(([n,i])=>String(n).toLowerCase()==="content-type"&&String(i).toLowerCase().includes(s));for(let n=0;n+1<e.length;n+=2)if(String(e[n]).toLowerCase()==="content-type"&&String(e[n+1]).toLowerCase().includes(s))return!0;return!1}function S(t,a=u){let r,o=!1;const e=()=>{o=!0,r&&(clearInterval(r),r=void 0)},n=()=>!t.writableEnded&&!t.destroyed,i=()=>{o||r||(r=setInterval(()=>{if(!n()){e();return}try{t.write(d)}catch{e()}},a),r.unref?.())};t.once("finish",e),t.once("close",e),t.once("error",e);const c=t.writeHead.bind(t);return t.writeHead=function(...f){t.writeHead=c;const l=c(...f);if(!o&&p(f)){try{t.flushHeaders()}catch{}i()}return l},{stop:e}}export{S as attachSseKeepalive};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { McpServerInstance } from './mcp-server.js';
|
|
2
|
-
type SessionManagerOptions = {
|
|
3
|
-
maxSessions?: number;
|
|
4
|
-
onEvict?: (sessionId: string) => void;
|
|
5
|
-
};
|
|
6
|
-
export declare class McpSessionManager {
|
|
7
|
-
#private;
|
|
8
|
-
constructor(options?: SessionManagerOptions);
|
|
9
|
-
get(sessionId: string): McpServerInstance | undefined;
|
|
10
|
-
set(sessionId: string, instance: McpServerInstance): void;
|
|
11
|
-
close(sessionId: string): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
export declare const mcpSessionManager: McpSessionManager;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=session-manager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{logger as i}from"../../../tools/notifiers/logger.js";const a=1800*1e3,c=60*1e3,o=500;class r{#t=new Map;#e;#s;constructor(t={}){this.#e=t.maxSessions??o,this.#s=t.onEvict??(()=>{}),setInterval(()=>{this.#i()},c).unref?.()}get(t){const e=this.#t.get(t);if(e)return e.lastAccess=Date.now(),this.#t.delete(t),this.#t.set(t,e),e.instance}set(t,e){const s=this.#t.get(t);if(this.#t.delete(t),this.#t.set(t,{instance:e,lastAccess:Date.now()}),s&&s.instance!==e&&this.#n(t,s.instance),this.#t.size>this.#e){const n=this.#t.keys().next().value;n!==void 0&&this.close(n)}}async close(t){const e=this.#t.get(t);e&&(this.#t.delete(t),this.#s(t),await this.#n(t,e.instance))}async#n(t,e){try{await e.cleanup()}catch(s){i.warn(`Failed to clean up MCP session ${t.slice(0,8)}\u2026: ${s instanceof Error?s.message:String(s)}`)}}async#i(){const t=Date.now()-a;for(const[e,s]of this.#t)s.lastAccess<=t&&await this.close(e)}}const f=new r;export{r as McpSessionManager,f as mcpSessionManager};
|