@redocly/realm 0.138.0-next.4 → 0.138.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 (138) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/cli/build/analytics/collect-analytics.js +1 -1
  3. package/dist/cli/build/analytics/collectors/get-sidebars-usage.d.ts +12 -0
  4. package/dist/cli/build/analytics/collectors/get-sidebars-usage.js +1 -0
  5. package/dist/cli/build/index.js +1 -1
  6. package/dist/cli/eject/resolveEjectParams.js +1 -1
  7. package/dist/cli/generate/string-utils.js +1 -1
  8. package/dist/cli/stats/collectors/extension-sampling.js +1 -1
  9. package/dist/cli/translations/collect-config-translations.js +1 -1
  10. package/dist/client/TestProvider.js +1 -1
  11. package/dist/client/app/Link.js +1 -1
  12. package/dist/client/app/Sidebar/useSidebarItems.js +1 -1
  13. package/dist/client/app/hooks/codeHighlight/treeview-transformer.js +1 -1
  14. package/dist/client/app/hooks/markdown/useMarkdownText.js +1 -1
  15. package/dist/client/app/search/index.d.ts +1 -1
  16. package/dist/client/app/search/index.js +1 -1
  17. package/dist/client/app/search/useSearch.d.ts +3 -0
  18. package/dist/client/app/search/useSearch.js +1 -1
  19. package/dist/client/providers/page-data/hooks.d.ts +2 -0
  20. package/dist/client/providers/page-data/hooks.js +1 -1
  21. package/dist/client/providers/theme/ThemeDataProvider.js +1 -1
  22. package/dist/client/runtime/loader.js +1 -1
  23. package/dist/client/templates/api-docs/helpers.js +1 -1
  24. package/dist/client/templates/api-docs/template.js +7 -3
  25. package/dist/client/utils/catalog/parse-filter-query.js +1 -1
  26. package/dist/client/{app/Sidebar/helpers → utils}/filter-out-versioned-items.d.ts +12 -2
  27. package/dist/client/utils/filter-out-versioned-items.js +1 -0
  28. package/dist/client/utils/navigation-tabs.d.ts +14 -0
  29. package/dist/client/utils/navigation-tabs.js +1 -0
  30. package/dist/constants/l10n/langs/ar.js +1 -1
  31. package/dist/constants/l10n/langs/de.js +1 -1
  32. package/dist/constants/l10n/langs/en.js +1 -1
  33. package/dist/constants/l10n/langs/es.js +1 -1
  34. package/dist/constants/l10n/langs/fr.js +1 -1
  35. package/dist/constants/l10n/langs/hi.js +1 -1
  36. package/dist/constants/l10n/langs/it.js +1 -1
  37. package/dist/constants/l10n/langs/ja.js +1 -1
  38. package/dist/constants/l10n/langs/ko.js +1 -1
  39. package/dist/constants/l10n/langs/pl.js +1 -1
  40. package/dist/constants/l10n/langs/pt-BR.js +1 -1
  41. package/dist/constants/l10n/langs/pt.js +1 -1
  42. package/dist/constants/l10n/langs/ru.js +1 -1
  43. package/dist/constants/l10n/langs/uk.js +1 -1
  44. package/dist/constants/l10n/langs/zh.js +1 -1
  45. package/dist/server/config/env-config.d.ts +0 -2
  46. package/dist/server/config/env-schema.d.ts +0 -5
  47. package/dist/server/config/env-schemas/feature-flags.d.ts +0 -4
  48. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  49. package/dist/server/constants/common.d.ts +0 -1
  50. package/dist/server/constants/common.js +1 -1
  51. package/dist/server/plugins/api-docs/index.js +1 -1
  52. package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.d.ts +9 -0
  53. package/dist/server/plugins/api-docs/utils/apply-nav-item-to-root.js +1 -0
  54. package/dist/server/plugins/api-docs/utils/decorators.js +1 -1
  55. package/dist/server/plugins/catalog-entities/utils/ajv-validator.js +1 -1
  56. package/dist/server/plugins/catalog-entities/utils/extract-parts-from-components-ref.js +1 -1
  57. package/dist/server/plugins/catalog-entities/utils/is-valid-tag-name.js +1 -1
  58. package/dist/server/plugins/catalog-entities/utils/openapi-component-content-extractor.js +1 -1
  59. package/dist/server/plugins/default-theme/extract-team-names.js +1 -1
  60. package/dist/server/plugins/get-reserved-routes.d.ts +4 -2
  61. package/dist/server/plugins/get-reserved-routes.js +1 -1
  62. package/dist/server/plugins/l10n/index.js +1 -1
  63. package/dist/server/plugins/markdown/search/to-markdown.js +1 -1
  64. package/dist/server/plugins/markdown/utils/sanitize-malformed-md-content.js +1 -1
  65. package/dist/server/plugins/mcp/audit/secret-patterns.js +1 -1
  66. package/dist/server/plugins/mcp/auth/assistant-anonymous-token.js +1 -1
  67. package/dist/server/plugins/mcp/auth/auth-handlers.js +1 -1
  68. package/dist/server/plugins/mcp/codemode/build-tool-list.d.ts +6 -1
  69. package/dist/server/plugins/mcp/codemode/build-tool-list.js +2 -2
  70. package/dist/server/plugins/mcp/codemode/code-execution-audit.d.ts +3 -2
  71. package/dist/server/plugins/mcp/codemode/code-execution-audit.js +1 -1
  72. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.d.ts +3 -4
  73. package/dist/server/plugins/mcp/codemode/code-execution-telemetry.js +1 -1
  74. package/dist/server/plugins/mcp/codemode/prompts.js +1 -1
  75. package/dist/server/plugins/mcp/codemode/tools/describe-tools.js +2 -2
  76. package/dist/server/plugins/mcp/codemode/tools/execute.js +1 -1
  77. package/dist/server/plugins/mcp/codemode/tools/manage-credentials.js +2 -2
  78. package/dist/server/plugins/mcp/custom-tools/scan-custom-tools.js +1 -1
  79. package/dist/server/plugins/mcp/docs-mcp/tool-schemas.js +1 -1
  80. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/endpoint-suggestions.js +1 -1
  81. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-endpoint-info.js +1 -1
  82. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/get-security-schemes.js +1 -1
  83. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.d.ts +3 -4
  84. package/dist/server/plugins/mcp/docs-mcp/tools/openapi/utils.js +1 -1
  85. package/dist/server/plugins/mcp/docs-mcp/utils/resolve-refs.js +1 -1
  86. package/dist/server/plugins/mcp/gateway-mcp/elicitation.d.ts +15 -3
  87. package/dist/server/plugins/mcp/gateway-mcp/elicitation.js +6 -5
  88. package/dist/server/plugins/mcp/gateway-mcp/fetch/allowed-hosts.js +1 -1
  89. package/dist/server/plugins/mcp/gateway-mcp/fetch/url-placeholders.js +1 -1
  90. package/dist/server/plugins/mcp/gateway-mcp/upstream-auth-scheme.js +2 -2
  91. package/dist/server/plugins/mcp/handlers/docs-mcp-handler.js +1 -1
  92. package/dist/server/plugins/mcp/handlers/mcp-credentials-page.js +35 -35
  93. package/dist/server/plugins/mcp/index.js +1 -1
  94. package/dist/server/plugins/mcp/servers/mcp-server.js +3 -3
  95. package/dist/server/plugins/mcp/types.d.ts +5 -11
  96. package/dist/server/plugins/mcp/utils/json-schema-validator.d.ts +2 -2
  97. package/dist/server/plugins/mcp/utils/json-schema-validator.js +1 -1
  98. package/dist/server/plugins/mcp/utils/mcp-client.js +1 -1
  99. package/dist/server/plugins/mcp/utils/public-endpoint.d.ts +9 -0
  100. package/dist/server/plugins/mcp/utils/public-endpoint.js +1 -0
  101. package/dist/server/plugins/mcp/utils/telemetry-attributes.d.ts +2 -1
  102. package/dist/server/plugins/mcp/utils/telemetry-attributes.js +1 -1
  103. package/dist/server/plugins/mcp/utils/xmcp-utils.d.ts +0 -7
  104. package/dist/server/plugins/mcp/utils/xmcp-utils.js +1 -1
  105. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -1
  106. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.d.ts +5 -7
  107. package/dist/server/plugins/mcp/workers/mcp-tool-telemetry.js +1 -1
  108. package/dist/server/plugins/nav-utils.js +1 -1
  109. package/dist/server/plugins/scorecard-classic/index.js +1 -1
  110. package/dist/server/plugins/scorecard-classic/template/useData.js +1 -1
  111. package/dist/server/plugins/search/llmstxt/index.js +1 -1
  112. package/dist/server/plugins/sidebars/index.js +7 -3
  113. package/dist/server/plugins/sidebars/tabs.d.ts +19 -0
  114. package/dist/server/plugins/sidebars/tabs.js +1 -0
  115. package/dist/server/plugins/sso/index.js +1 -1
  116. package/dist/server/store.js +1 -1
  117. package/dist/server/tools/notifiers/helpers/privacy/mask-subject.js +1 -1
  118. package/dist/server/tools/notifiers/helpers/privacy/remove-pii.js +1 -1
  119. package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.d.ts +3 -0
  120. package/dist/server/utils/catalog-classic/get-catalog-shared-data-id.js +1 -0
  121. package/dist/server/utils/envs/interpolate-env-variables.js +1 -1
  122. package/dist/server/utils/rbac.js +1 -1
  123. package/dist/server/utils/report-all-errors.js +1 -1
  124. package/dist/server/utils/sandbox-context.js +1 -1
  125. package/dist/server/utils/write-problems-report.d.ts +3 -0
  126. package/dist/server/utils/write-problems-report.js +1 -0
  127. package/dist/server/web-server/auth.d.ts +9 -3
  128. package/dist/server/web-server/auth.js +4 -4
  129. package/dist/server/web-server/routes/auth.js +1 -1
  130. package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
  131. package/dist/utils/path/parse-path-versions.js +1 -1
  132. package/dist/utils/string/to-kebab-case.js +1 -1
  133. package/package.json +7 -7
  134. package/dist/client/app/Sidebar/helpers/filter-out-versioned-items.js +0 -1
  135. package/dist/server/plugins/mcp/auth/token-audience-telemetry.d.ts +0 -7
  136. package/dist/server/plugins/mcp/auth/token-audience-telemetry.js +0 -1
  137. package/dist/server/plugins/mcp/auth/token-audience.d.ts +0 -6
  138. package/dist/server/plugins/mcp/auth/token-audience.js +0 -1
@@ -57,7 +57,6 @@ export declare const envSchema: z.ZodEffects<z.ZodObject<{
57
57
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL: z.ZodOptional<z.ZodString>;
58
58
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT: z.ZodOptional<z.ZodString>;
59
59
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
60
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
61
60
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
62
61
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
63
62
  } & {
@@ -138,7 +137,6 @@ export declare const envSchema: z.ZodEffects<z.ZodObject<{
138
137
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
139
138
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
140
139
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: boolean | undefined;
141
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: boolean | undefined;
142
140
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: boolean | undefined;
143
141
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: boolean | undefined;
144
142
  SEARCH_DEV_REINIT?: string | undefined;
@@ -212,7 +210,6 @@ export declare const envSchema: z.ZodEffects<z.ZodObject<{
212
210
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
213
211
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
214
212
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: "false" | "true" | undefined;
215
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: "false" | "true" | undefined;
216
213
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: "false" | "true" | undefined;
217
214
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: "false" | "true" | undefined;
218
215
  SEARCH_DEV_REINIT?: string | undefined;
@@ -286,7 +283,6 @@ export declare const envSchema: z.ZodEffects<z.ZodObject<{
286
283
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
287
284
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
288
285
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: boolean | undefined;
289
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: boolean | undefined;
290
286
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: boolean | undefined;
291
287
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: boolean | undefined;
292
288
  SEARCH_DEV_REINIT?: string | undefined;
@@ -360,7 +356,6 @@ export declare const envSchema: z.ZodEffects<z.ZodObject<{
360
356
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
361
357
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
362
358
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: "false" | "true" | undefined;
363
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: "false" | "true" | undefined;
364
359
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: "false" | "true" | undefined;
365
360
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: "false" | "true" | undefined;
366
361
  SEARCH_DEV_REINIT?: string | undefined;
@@ -17,8 +17,6 @@ export declare const featureFlagsSchema: z.ZodObject<{
17
17
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT: z.ZodOptional<z.ZodString>;
18
18
  /** Escape hatch: disables the Node Permission Model sandbox on API function and MCP tool worker processes (hosted Reunite environments only). */
19
19
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
20
- /** Rejects `/mcp` bearer tokens whose `aud` claim is not `ORGANIZATION_ID` with a 401; log-only when unset. */
21
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
22
20
  /** Experimental: register custom MCP tools from `@mcp` folders. */
23
21
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED: z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "false" | "true" | undefined>;
24
22
  /** Experimental: enables the GraphQL request body in Try It and embedded Replay. */
@@ -34,7 +32,6 @@ export declare const featureFlagsSchema: z.ZodObject<{
34
32
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
35
33
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
36
34
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: boolean | undefined;
37
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: boolean | undefined;
38
35
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: boolean | undefined;
39
36
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: boolean | undefined;
40
37
  }, {
@@ -48,7 +45,6 @@ export declare const featureFlagsSchema: z.ZodObject<{
48
45
  REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL?: string | undefined;
49
46
  REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT?: string | undefined;
50
47
  REDOCLY_DISABLE_API_FUNCTION_SANDBOX?: "false" | "true" | undefined;
51
- REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE?: "false" | "true" | undefined;
52
48
  REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED?: "false" | "true" | undefined;
53
49
  REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED?: "false" | "true" | undefined;
54
50
  }>;
@@ -1 +1 @@
1
- import{z as _}from"zod";import{envBooleanStringOptional as E}from"../../utils/envs/env-boolean-string.js";const D=_.object({NEW_CATALOG_ENABLED:E(),NEW_SCORECARDS_ENABLED:E(),ENABLE_COMMENTS:_.string().optional(),REDOCLY_EXP_DISABLE_MD_VALIDATION:E(),ENABLE_SOURCE_MAPS:E(),PLAN_GATES:_.string().optional(),REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED:E(),REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL:_.string().optional(),REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT:_.string().optional(),REDOCLY_DISABLE_API_FUNCTION_SANDBOX:E(),REDOCLY_MCP_ENFORCE_TOKEN_AUDIENCE:E(),REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED:E(),REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED:E()});export{D as featureFlagsSchema};
1
+ import{z as _}from"zod";import{envBooleanStringOptional as E}from"../../utils/envs/env-boolean-string.js";const D=_.object({NEW_CATALOG_ENABLED:E(),NEW_SCORECARDS_ENABLED:E(),ENABLE_COMMENTS:_.string().optional(),REDOCLY_EXP_DISABLE_MD_VALIDATION:E(),ENABLE_SOURCE_MAPS:E(),PLAN_GATES:_.string().optional(),REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED:E(),REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_URL:_.string().optional(),REDOCLY_EXP_LLMSTXT_AGENT_ENDPOINT:_.string().optional(),REDOCLY_DISABLE_API_FUNCTION_SANDBOX:E(),REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED:E(),REDOCLY_EXP_REPLAY_GRAPHQL_ENABLED:E()});export{D as featureFlagsSchema};
@@ -31,7 +31,6 @@ export declare const PROJECT_SLUG: string | undefined;
31
31
  export declare const ORG_ID: string | undefined;
32
32
  export declare const ORG_SLUG: string | undefined;
33
33
  export declare const BH_API_PROJECTS_URL: string | undefined;
34
- export declare const BH_API_PROJECTS_URL_V2: string | undefined;
35
34
  export declare const ENTITLEMENTS_JWKS_URL: string;
36
35
  export declare const FEEDBACK_API_URL: string;
37
36
  export declare const ASK_AI_API_URL: string;
@@ -1 +1 @@
1
- import{ServerRoutes as S}from"../../constants/api.js";import{USER_THEME_ALIAS as c}from"../../constants/common.js";import{envConfig as _}from"../config/env-config.js";const U="runtime",M="/assets",P="/_spec",i="/_bundle",l="static",m="static-data",F="redocly:::linkOriginal",K="@",H="default",B=new RegExp("((?!@i18n\\/|@l10n\\/)\\/?@.*?(?=\\/))","g"),Y="@redocly/theme/plugin.js",d="styles.css",u=["@theme/plugin.js","@theme/plugin.cjs","@theme/plugin.mjs"],L="test_secret_key",G=_.JWT_SECRET_KEY||L,r=4096,p=196,g=r-p,W=3600,h=1440*60,O="@i18n",C="@l10n",J=[c,O,C,"@api","@mcp"],f="https://redocly.com/auth/aud",k="catalog.json",$="scorecard.json",j="page-count.json",w="sitemap.xml",V="llms.txt",o=_.PROJECT_ID,R=_.PROJECT_SLUG,e=_.ORGANIZATION_ID,s=_.ORG_SLUG,t=_.BH_API_URL,T=t&&s&&R?`${t}/orgs/${s}/projects/${R}`:void 0,E=t&&e&&o?`${t}/orgs/${e}/projects/${o}`:void 0,D=t?`${t}/entitlements/.well-known/jwks`:"https://app.cloud.redocly.com/api/entitlements/.well-known/jwks",X=_.ENTITLEMENTS_JWKS_CDN_URL||D,v=T?`${T}/feedback`:"",y=E?`${E}/ai-agentic-conversations`:"",b=E?`${E}/ai-assistant-escalations`:"",Z=E?`${E}/ai-assistant-feedback`:"",q=E?`${E}/semantic-search`:"",z="no-store",Q=365*24*60*60,__="X-Redocly-Cache-Control",E_="no-cache",t_="public, s-maxage=86400, max-age=10, must-revalidate",o_=_.AUTH_URL,R_="Developer Documentation",n=_.REDOCLY_SSR_RENDER_MODE==="worker"?"worker":"main",e_=n==="main"?0:_.REDOCLY_SSR_WORKERS_MIN!=null?Number(_.REDOCLY_SSR_WORKERS_MIN):2,s_=n==="main"?1:_.REDOCLY_SSR_WORKERS_MAX!=null?Number(_.REDOCLY_SSR_WORKERS_MAX):5,T_="-----BEGIN CERTIFICATE-----",n_="-----END CERTIFICATE-----",A_=!_.isDevelopMode&&_.REDOCLY_TELEMETRY!=="off"||_.REDOCLY_TELEMETRY==="on",I_="http://localhost:4318/v1/traces",S_=[S.HEALTH],A=_.SERVER_EDITOR_APP_URL||"http://127.0.0.1:3000",c_=_.REDOCLY_CORS_ORIGINS?_.REDOCLY_CORS_ORIGINS.split(",").map(I=>I.trim()).filter(Boolean).concat(A):[A],L_="markdown/partials",r_="markdown/partials-deps";export{b as AI_ASSISTANT_ESCALATIONS_API_URL,Z as AI_ASSISTANT_FEEDBACK_API_URL,c_ as ALLOWED_CORS_ORIGINS,f as ALTERNATIVE_AUD_CLAIM_NAME,y as ASK_AI_API_URL,o_ as AUTH_URL,T_ as BEGIN_CERTIFICATE_DELIMITER,T as BH_API_PROJECTS_URL,E as BH_API_PROJECTS_URL_V2,z as CACHE_CONTROL_NO_STORE_HEADER_VALUE,E_ as CACHE_CONTROL_PUBLIC_HTML,k as CATALOG_OUTPUT_FILE_NAME,Q as DEFAULT_IMMUTABLE_CACHE_MAX_AGE,u as DEFAULT_PROJECT_PLUGIN_PATHS,Y as DEFAULT_THEME_PLUGIN_PATH,R_ as DEFAULT_TITLE,H as DEFAULT_VERSION_NAME,P as DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER,n_ as END_CERTIFICATE_DELIMITER,X as ENTITLEMENTS_JWKS_URL,L as FALLBACK_JWT_SECRET_KEY,v as FEEDBACK_API_URL,O as I18N_DIR_NAME,G as JWT_SECRET_KEY,C as L10N_DIR_NAME,F as LINK_ORIGINAL_ATTR_NAME,V as LLMS_TXT_FILE_NAME,L_ as MARKDOC_PARTIALS_DATA_KEY,r_ as MARKDOC_PARTIALS_DEPS_KEY,g as MAX_AUTH_TOKEN_COOKIE_BYTES,W as MCP_ACCESS_TOKEN_TTL_SEC,h as MCP_REFRESH_SESSION_LIFETIME_SEC,e as ORG_ID,s as ORG_SLUG,S_ as OTEL_EXCLUDED_ROUTES,I_ as OTEL_TRACES_DEV_URL,j as PAGE_COUNT_OUTPUT_FILE_NAME,o as PROJECT_ID,R as PROJECT_SLUG,i as PUBLIC_API_DEFINITIONS_FOLDER,M as PUBLIC_ASSETS_FOLDER,l as PUBLIC_STATIC_FOLDER,J as RESERVED_DIR_NAMES,U as RUNTIME_RESOURCES_DIR,$ as SCORECARD_OUTPUT_FILE_NAME,q as SEMANTIC_SEARCH_API_URL,A as SERVER_EDITOR_APP_URL,w as SITEMAP_FILE_NAME,n as SSR_RENDER_MODE,s_ as SSR_WORKERS_MAX,e_ as SSR_WORKERS_MIN,m as STATIC_DATA_FOLDER,d as STYLES_FILE,A_ as TELEMETRY_ENABLED,B as VERSIONED_FOLDER_REGEXP_MATCH,K as VERSION_SEPARATOR,__ as X_REDOCLY_CACHE_CONTROL_HEADER,t_ as X_REDOCLY_CACHE_CONTROL_PUBLIC_HTML};
1
+ import{ServerRoutes as n}from"../../constants/api.js";import{USER_THEME_ALIAS as A}from"../../constants/common.js";import{envConfig as _}from"../config/env-config.js";const N="runtime",x="/assets",a="/_spec",U="/_bundle",M="static",l="static-data",P="redocly:::linkOriginal",i="@",m="default",F=new RegExp("((?!@i18n\\/|@l10n\\/)\\/?@.*?(?=\\/))","g"),K="@redocly/theme/plugin.js",H="styles.css",Y=["@theme/plugin.js","@theme/plugin.cjs","@theme/plugin.mjs"],I="test_secret_key",B=_.JWT_SECRET_KEY||I,S=4096,L=196,d=S-L,u=3600,G=1440*60,c="@i18n",r="@l10n",g=[A,c,r,"@api","@mcp"],W="https://redocly.com/auth/aud",h="catalog.json",k="scorecard.json",J="page-count.json",f="sitemap.xml",w="llms.txt",o=_.PROJECT_ID,X=_.PROJECT_SLUG,R=_.ORGANIZATION_ID,j=_.ORG_SLUG,t=_.BH_API_URL,E=t&&R&&o?`${t}/orgs/${R}/projects/${o}`:void 0,p=t?`${t}/entitlements/.well-known/jwks`:"https://app.cloud.redocly.com/api/entitlements/.well-known/jwks",V=_.ENTITLEMENTS_JWKS_CDN_URL||p,$=E?`${E}/feedback`:"",v=E?`${E}/ai-agentic-conversations`:"",y=E?`${E}/ai-assistant-escalations`:"",b=E?`${E}/ai-assistant-feedback`:"",Z=E?`${E}/semantic-search`:"",q="no-store",z=365*24*60*60,Q="X-Redocly-Cache-Control",__="no-cache",E_="public, s-maxage=86400, max-age=10, must-revalidate",t_=_.AUTH_URL,o_="Developer Documentation",e=_.REDOCLY_SSR_RENDER_MODE==="worker"?"worker":"main",R_=e==="main"?0:_.REDOCLY_SSR_WORKERS_MIN!=null?Number(_.REDOCLY_SSR_WORKERS_MIN):2,e_=e==="main"?1:_.REDOCLY_SSR_WORKERS_MAX!=null?Number(_.REDOCLY_SSR_WORKERS_MAX):5,T_="-----BEGIN CERTIFICATE-----",s_="-----END CERTIFICATE-----",n_=!_.isDevelopMode&&_.REDOCLY_TELEMETRY!=="off"||_.REDOCLY_TELEMETRY==="on",A_="http://localhost:4318/v1/traces",I_=[n.HEALTH],T=_.SERVER_EDITOR_APP_URL||"http://127.0.0.1:3000",S_=_.REDOCLY_CORS_ORIGINS?_.REDOCLY_CORS_ORIGINS.split(",").map(s=>s.trim()).filter(Boolean).concat(T):[T],L_="markdown/partials",c_="markdown/partials-deps";export{y as AI_ASSISTANT_ESCALATIONS_API_URL,b as AI_ASSISTANT_FEEDBACK_API_URL,S_ as ALLOWED_CORS_ORIGINS,W as ALTERNATIVE_AUD_CLAIM_NAME,v as ASK_AI_API_URL,t_ as AUTH_URL,T_ as BEGIN_CERTIFICATE_DELIMITER,E as BH_API_PROJECTS_URL,q as CACHE_CONTROL_NO_STORE_HEADER_VALUE,__ as CACHE_CONTROL_PUBLIC_HTML,h as CATALOG_OUTPUT_FILE_NAME,z as DEFAULT_IMMUTABLE_CACHE_MAX_AGE,Y as DEFAULT_PROJECT_PLUGIN_PATHS,K as DEFAULT_THEME_PLUGIN_PATH,o_ as DEFAULT_TITLE,m as DEFAULT_VERSION_NAME,a as DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER,s_ as END_CERTIFICATE_DELIMITER,V as ENTITLEMENTS_JWKS_URL,I as FALLBACK_JWT_SECRET_KEY,$ as FEEDBACK_API_URL,c as I18N_DIR_NAME,B as JWT_SECRET_KEY,r as L10N_DIR_NAME,P as LINK_ORIGINAL_ATTR_NAME,w as LLMS_TXT_FILE_NAME,L_ as MARKDOC_PARTIALS_DATA_KEY,c_ as MARKDOC_PARTIALS_DEPS_KEY,d as MAX_AUTH_TOKEN_COOKIE_BYTES,u as MCP_ACCESS_TOKEN_TTL_SEC,G as MCP_REFRESH_SESSION_LIFETIME_SEC,R as ORG_ID,j as ORG_SLUG,I_ as OTEL_EXCLUDED_ROUTES,A_ as OTEL_TRACES_DEV_URL,J as PAGE_COUNT_OUTPUT_FILE_NAME,o as PROJECT_ID,X as PROJECT_SLUG,U as PUBLIC_API_DEFINITIONS_FOLDER,x as PUBLIC_ASSETS_FOLDER,M as PUBLIC_STATIC_FOLDER,g as RESERVED_DIR_NAMES,N as RUNTIME_RESOURCES_DIR,k as SCORECARD_OUTPUT_FILE_NAME,Z as SEMANTIC_SEARCH_API_URL,T as SERVER_EDITOR_APP_URL,f as SITEMAP_FILE_NAME,e as SSR_RENDER_MODE,e_ as SSR_WORKERS_MAX,R_ as SSR_WORKERS_MIN,l as STATIC_DATA_FOLDER,H as STYLES_FILE,n_ as TELEMETRY_ENABLED,F as VERSIONED_FOLDER_REGEXP_MATCH,i as VERSION_SEPARATOR,Q as X_REDOCLY_CACHE_CONTROL_HEADER,E_ as X_REDOCLY_CACHE_CONTROL_PUBLIC_HTML};
@@ -1 +1 @@
1
- import{REDOCLY_ROUTE_RBAC as w,REDOCLY_TEAMS_RBAC as v}from"@redocly/config";import{mcpTagSchemas as Z,schemaDefinitionTag as ee,markdocParser as N}from"@redocly/api-docs";import{withPathPrefix as B}from"@redocly/theme/core/utils";import{API_DOCS_TEMPLATE_ID as U,GRAPHQL_SPEC_SLUG as te,PUBLIC_RBAC_SCOPE_ITEM as q}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as oe,PUBLIC_API_DEFINITIONS_FOLDER as re}from"../../constants/common.js";import{API_DOCS_SHARED_DATA_PREFIX as C}from"../../constants/plugins/api-docs.js";import{fromCurrentDir as ae}from"../../utils/paths.js";import{normalizeRouteSlug as se}from"../../../utils/path/normalize-route-slug.js";import{createSlugify as ne}from"../create-slugify.js";import{apiDocLoader as ie,apiDocsLoader as ce}from"./loader.js";import{getTemplatePath as V}from"./get-template-path.js";import{storeDefinitionBundles as pe}from"./store-definition-bundles.js";import{telemetryTraceStep as ue}from"../../../cli/telemetry/helpers/trace-step.js";import{searchResolver as de}from"./search/search-resolver.js";import{getAiDocumentsStore as le}from"./search/get-ai-search-documents.js";import{getApiConfigByPath as me}from"../get-api-config.js";import{getRouteSlugsForPath as fe}from"../utils.js";import{collectItemRoutes as ge}from"./utils/collect-item-routes.js";import{buildRoutesMapping as he}from"./utils/build-routes-mapping.js";import{buildItemPositions as De}from"./utils/build-item-positions.js";import{resolveApiDocTitle as Se}from"./utils/resolve-api-doc-title.js";import{resolveConfigRbac as Pe}from"./utils/resolve-config-rbac.js";import{relativePathToBaseSlug as ye}from"./utils/relative-path-to-base-slug.js";import{normalizeApiVersion as Ie}from"./utils/normalize-api-version.js";import{importApiDocsBuilder as j}from"./import-api-docs-builder.js";import{envConfig as x}from"../../config/env-config.js";import{logger as Ae}from"../../tools/notifiers/logger.js";const T="openapi-spec-download",ve={asyncapi:"AsyncAPI Docs",graphql:"GraphQL Docs",openapi:"OpenAPI Docs"};async function rt(){let t=[],r=new Map;const s=new WeakMap;let i=new Set,m={};function k(o,g,A){const P=s.get(o)??new Map;s.set(o,P);const h=g??"";return P.get(h)===A?!1:(P.set(h,A),!0)}return{id:"api-docs",requiredEntitlements:["openapi","asyncapi","graphql"],loaders:{"api-doc":ie,"api-docs":ce},processContent:async(o,g)=>{await ue("com.redocly.build.plugin.apiDocs",async()=>{o.createRequestHandler(T,ae(import.meta.url,"./spec-download.api.js")),o.addApiRoute({slug:re+"/*",requestHandlerId:T,httpMethod:"all",[v]:q,getStaticData:async()=>({props:{}})}),o.addApiRoute({slug:oe+"/*",requestHandlerId:T,httpMethod:"all",[v]:q,getStaticData:async()=>({props:{}})}),o.addApiRoute({slug:te+"/*",requestHandlerId:T,httpMethod:"all",[v]:q,getStaticData:async()=>({props:{}})});const A=o.createTemplate(U,V("../../../client/templates/api-docs/template.js")),P=o.registerServerPropsGetter(U,V("./get-server-props.js")),h=await g.getConfig();r=new Map,m={};const y=await o.loadApiDocuments(g);pe(y,o.outdir);const E=!!h.plugins?.some(e=>typeof e=="string"&&e.startsWith("@redocly/portal-plugin-async-api/"));E&&y.some(e=>e.type==="asyncapi")&&Ae.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");const c=E?y.filter(e=>e.type!=="asyncapi"):y;t=c.map(({markdocChunks:e,relativePath:I,isVirtual:u,customOutputRelativeFile:a,realRelativePath:f})=>({chunks:e??[],relativePath:I,realRelativePath:f,isVirtual:a!=null||u}));const{buildItems:n}=await j(o.serverOutDir),D=(await g.cache.load("content-slugs","content-slugs")).data,S=ne(D),O=e=>se(S(e));for(const e of c){const I=e.customOutputRelativeFile||e.relativePath,u=O(I);_e(e,u);const{items:a,store:f}=await n({type:e.type,document:e.document,options:e.options,basePath:u,markdownParser:N}),R=`${C}${e.relativePath}`,M=x.isDevelopMode?e.relativePath:void 0,p=we(e.document),b=p?.["x-metadata"],_=e.isVirtual?void 0:b?.apiId,$={document:e,basePath:u,sourcePath:M,apiId:_};await o.createSharedData(R,W($,a,f));const z=Pe(e.config),F=!!e.options.excludeFromSearch,K=e.type==="openapi",d=ge(a,z).map(l=>{const J=l.metadata?.seo,H={...Ee(l.link,u),fsPath:I,templateId:A,sharedData:[{key:"apiDocsStore",id:R}],serverPropsGetterIds:[P],excludeFromSearch:F,getStaticData:be(l.label,J),[v]:l[v]};return K?{...H,...l.httpVerb?{httpVerb:l.httpVerb,metadata:{subType:"openapi-operation"}}:{}}:H});if(!d.length)continue;const G=Se(p,e.type,a),Y=Ie(p?.version),L={type:e.type,title:G,version:Y,description:typeof p?.description=="string"?p.description:void 0,summary:typeof p?.summary=="string"?p.summary:void 0,...p?.["x-metadata"]&&typeof p["x-metadata"]=="object"?p["x-metadata"]:{}};d[0]={...d[0],metadata:L,hasClientRoutes:!0,getSidebar:()=>Q(a),getNavText:()=>G??ve[e.type]??"API Docs",getSearchDocuments:de(a,L,o.getSearchFacets,o.setSearchFacets,F,f,e.document),getAiDocumentsStore:le({items:a,metadata:L,store:f,document:e.document,specType:e.type,excludeFromSearch:F,basePath:u,getSearchFacets:o.getSearchFacets,markdocTags:{...Z,schemaDefinition:ee}})};const X=d[0];d[0]=d[d.length-1],d[d.length-1]=X;for(const l of d)o.addRoute(l);if(_){const l=me(e.config?.apis,e.realRelativePath);m[_]={[v]:l.rbac,[w]:{fsPath:I}}}r.set(R,$)}})},afterRoutesCreated:async(o,g)=>{const{buildItems:A,simplifyAstStructure:P}=await j(o.serverOutDir),h=new Set,y=new Set;for(const{chunks:c,relativePath:n,isVirtual:D}of t){const S=`${C}${n}`,O=fe(o.getAllRoutes(),n);for(const{node:e,markdown:I,pointer:u,key:a,relativePath:f}of c){const{ast:R,compoundHash:M}=await o.parseMarkdoc({input:{content:I,relativePath:f,isVirtual:D},resource:u,context:g,deps:{sharedDataIds:[`${C}${f}`],routeSlugs:O}});if(h.add(u),!(a==="graphql-docs"?e?.description?.value!==void 0:!!(a&&e[a]))||!k(e,a,M))continue;y.add(S);const b=P(R);if(a==="graphql-docs"){e.description&&(e.description.value=b);const _=`${C}${f}`;Re(r.get(_),b)}else a&&(e[a]=b)}}const E=i.difference(h);for(const c of E)g.cache.delete(c);i=h,Object.entries(m).forEach(([c,n])=>{const D=n[w]?.fsPath;if(!D)return;const S=o.getRouteByFsPath(D)?.baseSlug;m[c]={...n,[w]:{...n[w],slug:S},slug:S}}),o.setGlobalData({apiProducts:m});for(const[c,n]of r){if(!y.has(c))continue;const{items:D,store:S}=await A({type:n.document.type,document:n.document.document,options:n.document.options,basePath:n.basePath,markdownParser:N});await o.createSharedData(c,W(n,D,S))}}}}function W({document:t,basePath:r,sourcePath:s,apiId:i},m,k){return{items:m,store:k,options:t.options,baseSlug:r,routesMapping:x.isDevelopMode?he(m,r):{},graphqlPositions:x.isDevelopMode&&t.type==="graphql"?De(m,r):void 0,sourcePath:s,apiId:i}}function Re(t,r){t?.document.type!=="graphql"||!t.document.options||(t.document.options.info={...t.document.options.info||{},description:r})}function be(t,r){return async function(s){return{props:{settings:{baseUrlPath:B(s.baseSlug)},disableAutoScroll:!0,seo:{title:t,...r}}}}}function _e(t,r){const s=t.options?.mockServer,i=B(`/_mock${ye(t.relativePath)}`);s?.url===i&&(t.options={...t.options,mockServer:{...s,url:B(`/_mock${r}`)}})}function Ee(t,r){if(t===r)return{};const s=r==="/"?"/":`${r}/`;if(t.startsWith(s)){const i=t.slice(s.length);return i?{slugSuffix:i}:{}}return{slug:t}}function we(t){if(t&&typeof t=="object"&&"info"in t)return t.info}function Q(t){return t.map(({content:r,items:s,...i})=>({...i,...s&&{items:Q(s)}}))}export{rt as apiDocsPlugin,Ee as toRouteSlugFields};
1
+ import{REDOCLY_ROUTE_RBAC as w,REDOCLY_TEAMS_RBAC as v}from"@redocly/config";import{mcpTagSchemas as Z,schemaDefinitionTag as ee,markdocParser as U}from"@redocly/api-docs";import{withPathPrefix as q}from"@redocly/theme/core/utils";import{API_DOCS_TEMPLATE_ID as V,GRAPHQL_SPEC_SLUG as te,PUBLIC_RBAC_SCOPE_ITEM as x}from"../../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as oe,PUBLIC_API_DEFINITIONS_FOLDER as re}from"../../constants/common.js";import{API_DOCS_SHARED_DATA_PREFIX as C}from"../../constants/plugins/api-docs.js";import{fromCurrentDir as ae}from"../../utils/paths.js";import{normalizeRouteSlug as se}from"../../../utils/path/normalize-route-slug.js";import{createSlugify as ie}from"../create-slugify.js";import{apiDocLoader as ne,apiDocsLoader as ce}from"./loader.js";import{getTemplatePath as j}from"./get-template-path.js";import{storeDefinitionBundles as pe}from"./store-definition-bundles.js";import{telemetryTraceStep as ue}from"../../../cli/telemetry/helpers/trace-step.js";import{searchResolver as le}from"./search/search-resolver.js";import{getAiDocumentsStore as de}from"./search/get-ai-search-documents.js";import{getApiConfigByPath as me}from"../get-api-config.js";import{getRouteSlugsForPath as fe}from"../utils.js";import{collectItemRoutes as ge}from"./utils/collect-item-routes.js";import{applyNavItemToRoot as he}from"./utils/apply-nav-item-to-root.js";import{buildRoutesMapping as De}from"./utils/build-routes-mapping.js";import{buildItemPositions as Se}from"./utils/build-item-positions.js";import{resolveApiDocTitle as Pe}from"./utils/resolve-api-doc-title.js";import{resolveConfigRbac as ye}from"./utils/resolve-config-rbac.js";import{relativePathToBaseSlug as Ie}from"./utils/relative-path-to-base-slug.js";import{normalizeApiVersion as Ae}from"./utils/normalize-api-version.js";import{importApiDocsBuilder as W}from"./import-api-docs-builder.js";import{envConfig as $}from"../../config/env-config.js";import{logger as ve}from"../../tools/notifiers/logger.js";const T="openapi-spec-download",Re={asyncapi:"AsyncAPI Docs",graphql:"GraphQL Docs",openapi:"OpenAPI Docs"};async function st(){let t=[],r=new Map;const s=new WeakMap;let n=new Set,m={};function k(o,g,A){const P=s.get(o)??new Map;s.set(o,P);const h=g??"";return P.get(h)===A?!1:(P.set(h,A),!0)}return{id:"api-docs",requiredEntitlements:["openapi","asyncapi","graphql"],loaders:{"api-doc":ne,"api-docs":ce},processContent:async(o,g)=>{await ue("com.redocly.build.plugin.apiDocs",async()=>{o.createRequestHandler(T,ae(import.meta.url,"./spec-download.api.js")),o.addApiRoute({slug:re+"/*",requestHandlerId:T,httpMethod:"all",[v]:x,getStaticData:async()=>({props:{}})}),o.addApiRoute({slug:oe+"/*",requestHandlerId:T,httpMethod:"all",[v]:x,getStaticData:async()=>({props:{}})}),o.addApiRoute({slug:te+"/*",requestHandlerId:T,httpMethod:"all",[v]:x,getStaticData:async()=>({props:{}})});const A=o.createTemplate(V,j("../../../client/templates/api-docs/template.js")),P=o.registerServerPropsGetter(V,j("./get-server-props.js")),h=await g.getConfig();r=new Map,m={};const y=await o.loadApiDocuments(g);pe(y,o.outdir);const E=!!h.plugins?.some(e=>typeof e=="string"&&e.startsWith("@redocly/portal-plugin-async-api/"));E&&y.some(e=>e.type==="asyncapi")&&ve.warn("The plugin '@redocly/portal-plugin-async-api' is deprecated. Please remove it from your config to use built-in AsyncAPI docs.");const c=E?y.filter(e=>e.type!=="asyncapi"):y;t=c.map(({markdocChunks:e,relativePath:I,isVirtual:p,customOutputRelativeFile:a,realRelativePath:f})=>({chunks:e??[],relativePath:I,realRelativePath:f,isVirtual:a!=null||p}));const{buildItems:i}=await W(o.serverOutDir),D=(await g.cache.load("content-slugs","content-slugs")).data,S=ie(D),O=e=>se(S(e));for(const e of c){const I=e.customOutputRelativeFile||e.relativePath,p=O(I);Ee(e,p);const{items:a,store:f}=await i({type:e.type,document:e.document,options:e.options,basePath:p,markdownParser:U}),R=`${C}${e.relativePath}`,M=$.isDevelopMode?e.relativePath:void 0,u=Ce(e.document),b=u?.["x-metadata"],_=e.isVirtual?void 0:b?.apiId,N={document:e,basePath:p,sourcePath:M,apiId:_};await o.createSharedData(R,Q(N,a,f));const K=ye(e.config),F=!!e.options.excludeFromSearch,Y=e.type==="openapi",d=ge(a,K).map(l=>{const B=l.metadata?.seo,H={...we(l.link,p),fsPath:I,templateId:A,sharedData:[{key:"apiDocsStore",id:R}],serverPropsGetterIds:[P],excludeFromSearch:F,getStaticData:_e(l.label,B),[v]:l[v]};return Y?{...H,...l.httpVerb?{httpVerb:l.httpVerb,metadata:{subType:"openapi-operation"}}:{}}:H});if(!d.length)continue;const G=Pe(u,e.type,a),X=Ae(u?.version),L={type:e.type,title:G,version:X,description:typeof u?.description=="string"?u.description:void 0,summary:typeof u?.summary=="string"?u.summary:void 0,...u?.["x-metadata"]&&typeof u["x-metadata"]=="object"?u["x-metadata"]:{}};d[0]={...d[0],metadata:L,hasClientRoutes:!0,getSidebar:(l,B)=>he(z(a),p,B),getNavText:()=>G??Re[e.type]??"API Docs",getSearchDocuments:le(a,L,o.getSearchFacets,o.setSearchFacets,F,f,e.document),getAiDocumentsStore:de({items:a,metadata:L,store:f,document:e.document,specType:e.type,excludeFromSearch:F,basePath:p,getSearchFacets:o.getSearchFacets,markdocTags:{...Z,schemaDefinition:ee}})};const J=d[0];d[0]=d[d.length-1],d[d.length-1]=J;for(const l of d)o.addRoute(l);if(_){const l=me(e.config?.apis,e.realRelativePath);m[_]={[v]:l.rbac,[w]:{fsPath:I}}}r.set(R,N)}})},afterRoutesCreated:async(o,g)=>{const{buildItems:A,simplifyAstStructure:P}=await W(o.serverOutDir),h=new Set,y=new Set;for(const{chunks:c,relativePath:i,isVirtual:D}of t){const S=`${C}${i}`,O=fe(o.getAllRoutes(),i);for(const{node:e,markdown:I,pointer:p,key:a,relativePath:f}of c){const{ast:R,compoundHash:M}=await o.parseMarkdoc({input:{content:I,relativePath:f,isVirtual:D},resource:p,context:g,deps:{sharedDataIds:[`${C}${f}`],routeSlugs:O}});if(h.add(p),!(a==="graphql-docs"?e?.description?.value!==void 0:!!(a&&e[a]))||!k(e,a,M))continue;y.add(S);const b=P(R);if(a==="graphql-docs"){e.description&&(e.description.value=b);const _=`${C}${f}`;be(r.get(_),b)}else a&&(e[a]=b)}}const E=n.difference(h);for(const c of E)g.cache.delete(c);n=h,Object.entries(m).forEach(([c,i])=>{const D=i[w]?.fsPath;if(!D)return;const S=o.getRouteByFsPath(D)?.baseSlug;m[c]={...i,[w]:{...i[w],slug:S},slug:S}}),o.setGlobalData({apiProducts:m});for(const[c,i]of r){if(!y.has(c))continue;const{items:D,store:S}=await A({type:i.document.type,document:i.document.document,options:i.document.options,basePath:i.basePath,markdownParser:U});await o.createSharedData(c,Q(i,D,S))}}}}function Q({document:t,basePath:r,sourcePath:s,apiId:n},m,k){return{items:m,store:k,options:t.options,baseSlug:r,routesMapping:$.isDevelopMode?De(m,r):{},graphqlPositions:$.isDevelopMode&&t.type==="graphql"?Se(m,r):void 0,sourcePath:s,apiId:n}}function be(t,r){t?.document.type!=="graphql"||!t.document.options||(t.document.options.info={...t.document.options.info||{},description:r})}function _e(t,r){return async function(s){return{props:{settings:{baseUrlPath:q(s.baseSlug)},disableAutoScroll:!0,seo:{title:t,...r}}}}}function Ee(t,r){const s=t.options?.mockServer,n=q(`/_mock${Ie(t.relativePath)}`);s?.url===n&&(t.options={...t.options,mockServer:{...s,url:q(`/_mock${r}`)}})}function we(t,r){if(t===r)return{};const s=r==="/"?"/":`${r}/`;if(t.startsWith(s)){const n=t.slice(s.length);return n?{slugSuffix:n}:{}}return{slug:t}}function Ce(t){if(t&&typeof t=="object"&&"info"in t)return t.info}function z(t){return t.map(({content:r,items:s,...n})=>({...n,...s&&{items:z(s)}}))}export{st as apiDocsPlugin,we as toRouteSlugFields};
@@ -0,0 +1,9 @@
1
+ import type { NavItem, ResolvedNavItem } from '@redocly/config';
2
+ /** A sidebars.yaml entry as core passes it to `getSidebar`: `icon` is the resolved path, or `undefined`
3
+ * with the resolved `srcSet` when the entry's icon is an `icon.srcSet` object. */
4
+ export type SidebarEntry = NavItem & {
5
+ srcSet?: string;
6
+ };
7
+ /** Puts the sidebars.yaml entry's label, icon and badges on the API root item, as core does for a page. */
8
+ export declare function applyNavItemToRoot(items: ResolvedNavItem[], basePath: string, entry?: SidebarEntry): ResolvedNavItem[];
9
+ //# sourceMappingURL=apply-nav-item-to-root.d.ts.map
@@ -0,0 +1 @@
1
+ const u=[({label:n,labelTranslationKey:o})=>n?{label:n,labelTranslationKey:o}:void 0,({icon:n,srcSet:o})=>{const t=typeof n=="string"?n:void 0;return t||o?{icon:t,srcSet:o}:void 0},({badges:n})=>n?{badges:n}:void 0];function c(n,o,t){if(!t)return n;const r=d(t);return n.map(e=>i(e,o)?{...e,...r}:e)}function d(n){return u.reduce((o,t)=>({...o,...t(n)}),{})}function i(n,o){return n.link===o}export{c as applyNavItemToRoot};
@@ -1 +1 @@
1
- import b from"node:path";import{REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{slash as k}from"../../../../utils/path/slash.js";function f(t,r,a){if(!r)throw new Error("Visitor required");if(t){t.description&&r(t,"description",a.location.absolutePointer+"/description",a);for(const o in t["x-enumDescriptions"])r(t["x-enumDescriptions"],o,a.location.absolutePointer+"/x-enumDescriptions/"+o,a)}}const x=/^[a-zA-Z0-9\s\-,.!?:;'"()/]+$/,d=/^\s*(?:[-+*]\s|\d+[.)]\s)/m;function g(t){return x.test(t)&&!d.test(t)}const s=({outputRelativePath:t,cwd:r})=>{const a=function(e,m,l,u){const{node:n}=u.resolve(e[m]);if(!n||typeof n!="string"||g(n))return;const i=u.getVisitorData();i.markdocChunks=i.markdocChunks||[],i.markdocChunks.push({node:e,pointer:k(b.relative(r,l)),markdown:n,relativePath:t,key:m})};return{any:{leave(o,e){f(o,a,e)}},ref:{leave(o,e){f(o,a,e)}}}},c=()=>{const t={};return{Tag:{enter(r){r?.["x-rbac"]&&(t[String(r.name)]=r["x-rbac"])}},any:{leave(r,a){if((a.type.name==="Operation"||a.type.name==="Webhook")&&"tags"in r&&Array.isArray(r.tags))for(const o of r.tags)t[o]&&(r["x-rbac"]=r["x-rbac"]||t[o]);r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}},ref:{leave(r){r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}}}};function D(t,r,a){const o={id:"markdown",decorators:{oas2:{markdown:s,rbac:c},oas3:{markdown:s,rbac:c},async3:{markdown:s,rbac:c}}};return{...t,decorators:{"markdown/rbac":"on","markdown/markdown":{outputRelativePath:r,cwd:a},...t.decorators||{}},plugins:[...t.plugins||[],o]}}export{s as MarkdownParserDecorator,c as RbacDecorator,D as injectDecoratorIntoConfig,g as isPlainNonMarkdownText};
1
+ import b from"node:path";import{REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{slash as k}from"../../../../utils/path/slash.js";function f(t,r,a){if(!r)throw new Error("Visitor required");if(t){t.description&&r(t,"description",a.location.absolutePointer+"/description",a);for(const o in t["x-enumDescriptions"])r(t["x-enumDescriptions"],o,a.location.absolutePointer+"/x-enumDescriptions/"+o,a)}}const x=/^[a-zA-Z0-9\s\-,.!?:;'"()/]+$/,d=/^[^\S\r\n\u2028\u2029]*(?:[-+*]\s|\d+[.)]\s)/m;function g(t){return x.test(t)&&!d.test(t)}const s=({outputRelativePath:t,cwd:r})=>{const a=function(e,u,l,m){const{node:n}=m.resolve(e[u]);if(!n||typeof n!="string"||g(n))return;const i=m.getVisitorData();i.markdocChunks=i.markdocChunks||[],i.markdocChunks.push({node:e,pointer:k(b.relative(r,l)),markdown:n,relativePath:t,key:u})};return{any:{leave(o,e){f(o,a,e)}},ref:{leave(o,e){f(o,a,e)}}}},c=()=>{const t={};return{Tag:{enter(r){r?.["x-rbac"]&&(t[String(r.name)]=r["x-rbac"])}},any:{leave(r,a){if((a.type.name==="Operation"||a.type.name==="Webhook")&&"tags"in r&&Array.isArray(r.tags))for(const o of r.tags)t[o]&&(r["x-rbac"]=r["x-rbac"]||t[o]);r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}},ref:{leave(r){r?.["x-rbac"]&&(r[p]=r["x-rbac"],delete r["x-rbac"])}}}};function D(t,r,a){const o={id:"markdown",decorators:{oas2:{markdown:s,rbac:c},oas3:{markdown:s,rbac:c},async3:{markdown:s,rbac:c}}};return{...t,decorators:{"markdown/rbac":"on","markdown/markdown":{outputRelativePath:r,cwd:a},...t.decorators||{}},plugins:[...t.plugins||[],o]}}export{s as MarkdownParserDecorator,c as RbacDecorator,D as injectDecoratorIntoConfig,g as isPlainNonMarkdownText};
@@ -1 +1 @@
1
- import u from"@redocly/ajv";const o=new u({coerceTypes:!0,removeAdditional:!0,discriminator:!0,allErrors:!0});o.addKeyword({keyword:"nodeTypeName",schemaType:"string"}),o.addFormat("uri",{type:"string",validate:e=>{try{return new URL(e),!0}catch{return!1}}}),o.addFormat("email",{type:"string",validate:e=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)});function f(e,t){const{errorPrefix:a,dataVar:n="data"}=t??{},r=o.compile(e);return function(i){if(!r(i)){const c=r.errors?.length?r.errors.map(s=>{const l=s.instancePath.replaceAll("/",".");return`'${n}${l}' ${s.message}`}).join(", "):"unknown error",d=a?`${a} `:"";throw new Error(`${d}${c}`)}return i}}function h(e,t){const a=o.compile(e),n=a(t);return{success:n,data:n?t:void 0,error:n?void 0:a.errors?.map(r=>`${r.instancePath} ${r.message}`).join(", ")}}export{f as createValidator,h as validateWithResult};
1
+ import l from"@redocly/ajv";const i=new l({coerceTypes:!0,removeAdditional:!0,discriminator:!0,allErrors:!0});i.addKeyword({keyword:"nodeTypeName",schemaType:"string"}),i.addFormat("uri",{type:"string",validate:r=>{try{return new URL(r),!0}catch{return!1}}}),i.addFormat("email",{type:"string",validate:r=>{if(!r||/\s/.test(r))return!1;const e=r.indexOf("@");return e<=0||r.indexOf("@",e+1)!==-1?!1:r.slice(e+2,-1).includes(".")}});function p(r,e){const{errorPrefix:n,dataVar:a="data"}=e??{},t=i.compile(r);return function(o){if(!t(o)){const c=t.errors?.length?t.errors.map(s=>{const u=s.instancePath.replaceAll("/",".");return`'${a}${u}' ${s.message}`}).join(", "):"unknown error",d=n?`${n} `:"";throw new Error(`${d}${c}`)}return o}}function h(r,e){const n=i.compile(r),a=n(e);return{success:a,data:a?e:void 0,error:a?void 0:n.errors?.map(t=>`${t.instancePath} ${t.message}`).join(", ")}}export{p as createValidator,h as validateWithResult};
@@ -1 +1 @@
1
- function t(o){const e=/^#\/components\/(?<componentType>.+)\/(?<componentName>.+)$/,n=o.match(e);return!n||!n.groups?null:{componentType:n?.groups?.componentType??null,componentName:n?.groups?.componentName??null}}export{t as extractPartsFromComponentsRef};
1
+ function t(o){const e=/^#\/components\/(?<componentType>.+)\/(?<componentName>[^/\n]+\/?)$/,n=o.match(e);return!n||!n.groups?null:{componentType:n?.groups?.componentType??null,componentName:n?.groups?.componentName??null}}export{t as extractPartsFromComponentsRef};
@@ -1 +1 @@
1
- function e(t){if(!t||typeof t!="string")return!1;const i=t.trim();return i?![/^\[.*\/.*\]/,/^\//,/\{\?/,/\?[\w=&]+/].some(n=>n.test(i)):!1}export{e as isValidTagName};
1
+ function e(t){if(!t||typeof t!="string")return!1;const n=t.trim();return n?![/^\[[^/\n]*\/.*\]/,/^\//,/\{\?/,/\?[\w=&]+/].some(i=>i.test(n)):!1}export{e as isValidTagName};
@@ -1 +1 @@
1
- class i{#n;constructor(t){this.#n=t}extract({component:t,definition:p,openapiOperation:e,visitedRefs:r=new Set}){if("content"in t)return t?.content??{};const n=t?.$ref;if(!n)return{};if(r.has(n))return this.#n.warn(`Circular reference detected: ${n} for operation: ${e.operationId}`),{};r.add(n);const s=/^#\/components\/(?<componentType>.+)\/(?<componentName>.+)$/,c=n.match(s);if(!c?.groups?.componentType||!c?.groups?.componentName)return this.#n.warn(`Invalid component reference format: ${n}. Should be #/components/<componentType>/<componentName>`),{};const{componentType:m,componentName:a}=c.groups,o=p.components?.[m]?.[a];return o?"$ref"in o?this.extract({component:o,definition:p,openapiOperation:e,visitedRefs:r}):"content"in o?o.content??{}:{}:(this.#n.warn(`Component not found: ${m}/${a} for operation: ${e.operationId}`),{})}}export{i as OpenapiComponentContentExtractor};
1
+ class i{#n;constructor(t){this.#n=t}extract({component:t,definition:p,openapiOperation:e,visitedRefs:r=new Set}){if("content"in t)return t?.content??{};const n=t?.$ref;if(!n)return{};if(r.has(n))return this.#n.warn(`Circular reference detected: ${n} for operation: ${e.operationId}`),{};r.add(n);const s=/^#\/components\/(?<componentType>.+)\/(?<componentName>[^/\n]+\/?)$/,c=n.match(s);if(!c?.groups?.componentType||!c?.groups?.componentName)return this.#n.warn(`Invalid component reference format: ${n}. Should be #/components/<componentType>/<componentName>`),{};const{componentType:m,componentName:a}=c.groups,o=p.components?.[m]?.[a];return o?"$ref"in o?this.extract({component:o,definition:p,openapiOperation:e,visitedRefs:r}):"content"in o?o.content??{}:{}:(this.#n.warn(`Component not found: ${m}/${a} for operation: ${e.operationId}`),{})}}export{i as OpenapiComponentContentExtractor};
@@ -1 +1 @@
1
- import{DEFAULT_ANONYMOUS_VISITOR_TEAM as c,DEFAULT_AUTHENTICATED_TEAM as T}from"../../../constants/common.js";function A(o){const t=[];if(!o?.content)return t;const s=Object.values(o.content);for(const e of s){const n=Object.keys(e);t.push(...n)}const r=t.filter(e=>e!==c&&e!==T&&!/^\S+@\S+\.\S+$/.test(e));return Array.from(new Set(r))}export{A as extractTeamNames};
1
+ import{DEFAULT_ANONYMOUS_VISITOR_TEAM as c,DEFAULT_AUTHENTICATED_TEAM as f}from"../../../constants/common.js";function i(e){if(/\s/.test(e))return!1;const t=e.indexOf("@",1);return t!==-1&&e.slice(t+2,-1).includes(".")}function u(e){const t=[];if(!e?.content)return t;const n=Object.values(e.content);for(const s of n){const r=Object.keys(s);t.push(...r)}const o=t.filter(s=>s!==c&&s!==f&&!i(s));return Array.from(new Set(o))}export{u as extractTeamNames};
@@ -1,14 +1,16 @@
1
1
  import type { RedoclyConfig } from '@redocly/config';
2
2
  type RouteReservationRule = {
3
3
  slug: string;
4
- isEnabled: (config?: RedoclyConfig) => boolean;
4
+ isEnabled: (config: RedoclyConfig) => boolean;
5
5
  };
6
6
  export declare const RESERVED_ROUTES: {
7
7
  mcp: string;
8
+ mcpPublic: string;
8
9
  };
9
10
  /**
10
11
  * Checks if a given route slug is reserved based on configuration.
11
- * A route is considered reserved if:
12
+ * A route is considered reserved if a rule for it is enabled, meaning the system serves
13
+ * that slug: content pages cannot use it, and links to it resolve.
12
14
  *
13
15
  * @param slug - The route slug to check
14
16
  * @param config - The Redocly configuration
@@ -1 +1 @@
1
- import{EntitlementsProvider as n}from"../entitlements/entitlements-provider.js";const o={mcp:"/mcp"},r=[{slug:o.mcp,isEnabled:e=>!e?.mcp?.hide&&!e?.mcp?.docs?.hide&&!!n.instance().canAccessFeature("mcp")}];function m(e,t,c=[]){return[...r,...c].some(s=>s.slug===e&&s.isEnabled(t))}export{o as RESERVED_ROUTES,m as isRouteReserved};
1
+ import{MCP_ROUTE as i,PUBLIC_MCP_ROUTE as r}from"@redocly/theme/core/constants/mcp";import{EntitlementsProvider as m}from"../entitlements/entitlements-provider.js";import{getPublicMcpEndpointStatus as p}from"./mcp/utils/public-endpoint.js";const t={mcp:i,mcpPublic:r};function s(){return!!m.instance().canAccessFeature("mcp")}const E=[{slug:t.mcp,isEnabled:e=>!e?.mcp?.hide&&!e?.mcp?.docs?.hide&&s()},{slug:t.mcpPublic,isEnabled:e=>s()&&p(e)==="served"}];function l(e,n,o=[]){return[...E,...o].some(c=>c.slug===e&&c.isEnabled(n))}export{t as RESERVED_ROUTES,l as isRouteReserved};
@@ -1 +1 @@
1
- import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as A}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{reporter as w}from"../../tools/notifiers/reporter.js";import{EntitlementsProvider as O}from"../../entitlements/entitlements-provider.js";import{isL10nPath as E}from"../../fs/utils/is-l10n-path.js";import{isOpenapiDoc as I}from"../api-docs/utils/is-api-doc.js";import{telemetryTraceStep as N}from"../../../cli/telemetry/helpers/trace-step.js";async function $(){return{id:"l10n",async processContent(n,i){await N("com.redocly.build.plugin.l10n",async a=>{const{fs:t,cache:c,getConfig:r}=i,e={},p=O.instance(),l=await r();a?.setAttribute("config",JSON.stringify(l.l10n||{}));const s=l.l10n?.defaultLocale||d;if(p.canAccessFeature("l10n")){await F(i);for(const{relativePath:o}of t.scan(/(^|.*[/\\])translations\.yaml$/)){const u=await c.load(o,"yaml"),L=P(o)||s;e[L]={translation:u.data||{}}}}e[s]={translation:{...e[s]?.translation||{}}};const f=l.l10n?.locales||[d,...t.localeFolders].map(o=>({code:o.toLowerCase(),name:o}));a?.setAttribute("locales",JSON.stringify(f)),n.setGlobalData({l10n:{translations:e,defaultLocale:s,locales:f.map(o=>({code:o.code,name:o.name||o.code}))}})})}}}function P(n){return n.indexOf("/")>0?n.split("/")[1]:void 0}async function F(n){const i=n.fs.scan();for(const{isVirtual:a,realRelativePath:t}of i){if(a)continue;if(E(t)&&t.endsWith(".page.tsx")&&await w.panicOnBuild(`The file %rp is not allowed in ${A} or ${y} folders`,t),g.posix.basename(t)===h){const r=/^(?:@(i18n|l10n)[/\\][^/\\]+[/\\])?translations\.yaml$/.test(t),e=await I(t,n);!r&&!e&&m.warn("The file %rp is in the wrong location. Make sure it is located in the root directory or in the locale root directory.",t),r&&e&&m.warn("It looks like the file %rp might be an OpenAPI definition and is located in a location reserved for translation files. Please rename it or move to another directory if it is not a translations file",t)}}}export{$ as l10nPlugin};
1
+ import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as A}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{reporter as w}from"../../tools/notifiers/reporter.js";import{EntitlementsProvider as O}from"../../entitlements/entitlements-provider.js";import{isL10nPath as E}from"../../fs/utils/is-l10n-path.js";import{isOpenapiDoc as I}from"../api-docs/utils/is-api-doc.js";import{telemetryTraceStep as N}from"../../../cli/telemetry/helpers/trace-step.js";async function $(){return{id:"l10n",async processContent(n,i){await N("com.redocly.build.plugin.l10n",async a=>{const{fs:t,cache:c,getConfig:r}=i,e={},p=O.instance(),l=await r();a?.setAttribute("config",JSON.stringify(l.l10n||{}));const s=l.l10n?.defaultLocale||d;if(p.canAccessFeature("l10n")){await F(i);for(const{relativePath:o}of t.scan(/(?:^|[/\\])translations\.yaml$/)){const u=await c.load(o,"yaml"),L=P(o)||s;e[L]={translation:u.data||{}}}}e[s]={translation:{...e[s]?.translation||{}}};const f=l.l10n?.locales||[d,...t.localeFolders].map(o=>({code:o.toLowerCase(),name:o}));a?.setAttribute("locales",JSON.stringify(f)),n.setGlobalData({l10n:{translations:e,defaultLocale:s,locales:f.map(o=>({code:o.code,name:o.name||o.code}))}})})}}}function P(n){return n.indexOf("/")>0?n.split("/")[1]:void 0}async function F(n){const i=n.fs.scan();for(const{isVirtual:a,realRelativePath:t}of i){if(a)continue;if(E(t)&&t.endsWith(".page.tsx")&&await w.panicOnBuild(`The file %rp is not allowed in ${A} or ${y} folders`,t),g.posix.basename(t)===h){const r=/^(?:@(i18n|l10n)[/\\][^/\\]+[/\\])?translations\.yaml$/.test(t),e=await I(t,n);!r&&!e&&m.warn("The file %rp is in the wrong location. Make sure it is located in the root directory or in the locale root directory.",t),r&&e&&m.warn("It looks like the file %rp might be an OpenAPI definition and is located in a location reserved for translation files. Please rename it or move to another directory if it is not a translations file",t)}}}export{$ as l10nPlugin};
@@ -14,7 +14,7 @@ import{isPrimitive as m}from"../../../../utils/guards/is-primitive.js";import{ge
14
14
  \`\`\`${`${i||""}${l?`${i?" ":""}${l}`:""}`}
15
15
  ${n.trimEnd()}
16
16
  \`\`\`
17
- `;t.push(h)}continue}if(e.tag==="json-example"){const n=j(e);n&&t.push(n);continue}if(e.tag==="json-schema"){const n=S(e);n&&t.push(n);continue}if(r.renderTag){const n=r.renderTag(e,{getBody:()=>a(e.children,r)});if(n!==void 0){t.push(n);continue}}t.push(`${a(e.children,r)}`);break;default:t.push(a(e.children,r));break}else $(e)&&t.push(a(e.children,r));k(e)&&t.push(a([f(e,r.variables)],r))}return r.isTrim?d(t.map(e=>d(e)).join("")):t.join("")}function d(s){return s.replace(/^[ \t\r\f]+|[ \t\r\f]+$/g,"")}function u(s,r={},t=!1){const e=c(s,"title"),n=c(s,"language"),i=`${n||""}${e?`${n?" ":""}${e}`:""}`,l=t?(c(s,"content")||"").trimEnd():a(s.children,r).trimEnd();return`
17
+ `;t.push(h)}continue}if(e.tag==="json-example"){const n=j(e);n&&t.push(n);continue}if(e.tag==="json-schema"){const n=S(e);n&&t.push(n);continue}if(r.renderTag){const n=r.renderTag(e,{getBody:()=>a(e.children,r)});if(n!==void 0){t.push(n);continue}}t.push(`${a(e.children,r)}`);break;default:t.push(a(e.children,r));break}else $(e)&&t.push(a(e.children,r));k(e)&&t.push(a([f(e,r.variables)],r))}return r.isTrim?d(t.map(e=>d(e)).join("")):t.join("")}function d(s){return s.replace(/^[ \t\r\f]+|(?<![ \t\r\f])[ \t\r\f]+$/g,"")}function u(s,r={},t=!1){const e=c(s,"title"),n=c(s,"language"),i=`${n||""}${e?`${n?" ":""}${e}`:""}`,l=t?(c(s,"content")||"").trimEnd():a(s.children,r).trimEnd();return`
18
18
  \`\`\`${i}
19
19
  ${l}
20
20
  \`\`\`
@@ -1,2 +1,2 @@
1
- function c(n){return n.replace(/\[([^\]]*<[^>]*>[^\]]*)\]\(([^)]+)\)/g,(r,t,s)=>`[${t.replace(/(`+)[^`]+\1|[<>]/g,e=>e==="<"?"&lt;":e===">"?"&gt;":e)}](${s})`).replace(/({%\s*(\w+)(?:\s+[^%]*)?%})(\s*)({%\s*\/\2\s*%})/g,(r,t,s,l,e)=>`${t}
1
+ function c(n){return n.replace(/\[(?<!\[[^\]()]*?\[)([^\]<]*<[^>]*>[^\]]*)\]\(([^)]+)\)/g,(r,t,s)=>`[${t.replace(/(`{1,16})[^`]+\1|[<>]/g,e=>e==="<"?"&lt;":e===">"?"&gt;":e)}](${s})`).replace(/({%\s*(\w+)(?:\s[^%]*)?%})(\s*)({%\s*\/\2\s*%})/g,(r,t,s,l,e)=>`${t}
2
2
  ${e}`)}export{c as sanitizeMalformedMdContent};
@@ -1 +1 @@
1
- const n=[{name:"aws_access_key_id",re:/\bAKIA[0-9A-Z]{16}\b/g},{name:"aws_temp_key",re:/\bASIA[0-9A-Z]{16}\b/g},{name:"github_token",re:/\bgh[pousr]_[A-Za-z0-9_]{20,255}\b/g},{name:"github_fine_grained",re:/\bgithub_pat_[A-Za-z0-9_]{60,255}\b/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g},{name:"pem_private_key",re:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"slack_token",re:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{name:"bearer_token",re:/(?<=[Aa]uthorization\s*[:=]\s*["']?[Bb]earer\s+)[A-Za-z0-9._\-+/=]{20,}/g},{name:"anthropic_key",re:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"openai_key",re:/\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g},{name:"stripe_key",re:/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{name:"sendgrid_key",re:/\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g},{name:"basic_auth_url",re:/\b([a-z][a-z0-9+\-.]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi}];function t(e){if(!e)return e;let a=e;for(const{name:r,re:_}of n)a=a.replace(_,(A,b)=>r==="basic_auth_url"?`${b??""}[REDACTED:${r}]@`:`[REDACTED:${r}]`);return a}export{t as redactSecretShapes};
1
+ const n=[{name:"aws_access_key_id",re:/\bAKIA[0-9A-Z]{16}\b/g},{name:"aws_temp_key",re:/\bASIA[0-9A-Z]{16}\b/g},{name:"github_token",re:/\bgh[pousr]_[A-Za-z0-9_]{20,255}\b/g},{name:"github_fine_grained",re:/\bgithub_pat_[A-Za-z0-9_]{60,255}\b/g},{name:"jwt",re:/\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g},{name:"pem_private_key",re:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----[\s\S]*?-----END (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g},{name:"google_api_key",re:/\bAIza[0-9A-Za-z_-]{35}\b/g},{name:"slack_token",re:/\bxox[abprs]-[A-Za-z0-9-]{10,}\b/g},{name:"bearer_token",re:/(?<=[Aa]uthorization\s*[:=]\s*["']?[Bb]earer\s{1,16})[A-Za-z0-9._\-+/=]{20,}/g},{name:"anthropic_key",re:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g},{name:"openai_key",re:/\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g},{name:"stripe_key",re:/\b(?:sk|rk|pk)_(?:live|test)_[A-Za-z0-9]{20,}\b/g},{name:"sendgrid_key",re:/\bSG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}\b/g},{name:"basic_auth_url",re:/\b([a-z][a-z0-9+\-.]*:\/\/)[^\s/:@]+:[^\s/@]+@/gi}];function t(e){if(!e)return e;let a=e;for(const{name:r,re:_}of n)a=a.replace(_,(A,b)=>r==="basic_auth_url"?`${b??""}[REDACTED:${r}]@`:`[REDACTED:${r}]`);return a}export{t as redactSecretShapes};
@@ -1 +1 @@
1
- import{hkdfSync as S}from"node:crypto";import{FALLBACK_JWT_SECRET_KEY as c}from"../../../constants/common.js";import{envConfig as o}from"../../../config/env-config.js";import{AlgorithmTypes as i}from"../../../web-server/jwt/types.js";import*as r from"../../../web-server/jwt/jwt.js";import{InternalTokenTypes as a}from"../../../web-server/jwt/token-types.js";import{toAudienceList as m}from"./token-audience.js";const T=600,u="ai-assistant-anonymous";function f(){const n=o.JWT_SECRET_KEY;if(!(!n||n===c||!o.PROJECT_ID))return Buffer.from(S("sha256",n,u,u,32)).toString("hex")}async function N(){const n=f();if(!n)return;const t=Math.floor(Date.now()/1e3);return r.sign({type:a.AI_ASSISTANT_ANONYMOUS,anonymous:!0,aud:o.PROJECT_ID,iat:t,exp:t+T},n,i.HS256)}async function I(n){const t=f();if(!t)return!1;try{await r.verify(n,t,i.HS256)}catch{return!1}const{payload:e}=r.decode(n),s=o.PROJECT_ID;return e.type===a.AI_ASSISTANT_ANONYMOUS&&e.anonymous===!0&&!!s&&m(e.aud).includes(s)}export{N as createAssistantAnonymousToken,I as isAssistantAnonymousToken};
1
+ import{hkdfSync as S}from"node:crypto";import{FALLBACK_JWT_SECRET_KEY as c}from"../../../constants/common.js";import{envConfig as o}from"../../../config/env-config.js";import{AlgorithmTypes as i}from"../../../web-server/jwt/types.js";import*as r from"../../../web-server/jwt/jwt.js";import{InternalTokenTypes as a}from"../../../web-server/jwt/token-types.js";import{ensureArray as m}from"../../../../utils/array/ensure-array.js";const T=600,u="ai-assistant-anonymous";function f(){const n=o.JWT_SECRET_KEY;if(!(!n||n===c||!o.PROJECT_ID))return Buffer.from(S("sha256",n,u,u,32)).toString("hex")}async function N(){const n=f();if(!n)return;const t=Math.floor(Date.now()/1e3);return r.sign({type:a.AI_ASSISTANT_ANONYMOUS,anonymous:!0,aud:o.PROJECT_ID,iat:t,exp:t+T},n,i.HS256)}async function I(n){const t=f();if(!t)return!1;try{await r.verify(n,t,i.HS256)}catch{return!1}const{payload:e}=r.decode(n),s=o.PROJECT_ID;return e.type===a.AI_ASSISTANT_ANONYMOUS&&e.anonymous===!0&&!!s&&m(e.aud).includes(s)}export{N as createAssistantAnonymousToken,I as isAssistantAnonymousToken};
@@ -1 +1 @@
1
- import{extractTokenFromAuthHeader as p}from"../../../plugins/mcp/utils/jwt.js";import{SUPPORTED_MCP_SCOPES as f}from"../constants.js";import{getUserParamsFromCookies as h}from"../../../web-server/auth.js";import{ServerRoutes as c}from"../../../../constants/api.js";import{withPathPrefix as l}from"@redocly/theme/core/utils";import{shouldHandleMcpAuth as m}from"../../../utils/rbac/should-handle-mcp-auth.js";import{isAssistantAnonymousToken as A}from"./assistant-anonymous-token.js";import{checkTokenAudience as T,isTokenAudienceEnforced as k,toAudienceList as C}from"./token-audience.js";import{reportMcpTokenAudienceMismatch as g}from"./token-audience-telemetry.js";function x(t){const e=t.getConfig().access;return m(!!e?.requiresLogin,e?.rbac||{})}async function S(t,e){const n=t.headers.get("Authorization");if(!n)return{isAuthenticated:!1};const o=p(n);if(o&&await A(o))return{isAuthenticated:!1,isTokenValid:!0,isFirstPartyAnonymous:!0};const r=e?.config?.ssoDirect||{},i=o?await h(r,{authorization:o}):{};if(!(o&&i&&i.isAuthenticated))return{isAuthenticated:!1,isTokenValid:!1};const s=i.aud;if(T(s)==="mismatch"){const a=k();if(g({audience:C(s).join(","),enforced:a}),a)return{isAuthenticated:!1,isTokenValid:!1}}return{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:i.teams||[],email:i.email||"",claims:i,isAuthenticated:!0,idpAccessToken:i.idpAccessToken||void 0,idpId:i.idpId||void 0},accessToken:o}}function u(t,e){const n=`${t}${c.MCP_OAUTH_PROTECTED_RESOURCE}${l("/mcp")}`,o=`${t}${c.MCP_OAUTH_AUTHORIZATION_SERVER}`,r=e?[`error="${e.code}"`,`error_description="${e.description}"`]:[];return r.push(`resource_metadata="${n}"`,`scope="${f.join(" ")}"`,`authorization_uri="${o}"`),`Bearer ${r.join(", ")}`}function d(t,e){return e?`${t}. A public endpoint that serves anonymous-accessible content is available at ${e}.`:t}function U(t,e){const n=d("Authentication required",e);return new Response(JSON.stringify({error:"unauthorized",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":u(t),"Access-Control-Allow-Origin":"*"}})}function b(){return new Response(JSON.stringify({error:"forbidden",message:"You do not have access to this MCP server"}),{status:403,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function H(t,e){const n=d("Invalid or expired token",e);return new Response(JSON.stringify({error:"invalid_token",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":u(t,{code:"invalid_token",description:"Invalid or expired token"}),"Access-Control-Allow-Origin":"*"}})}export{b as constructForbiddenResponse,H as constructInvalidTokenResponse,U as constructUnauthorizedResponse,S as handleMcpAuth,x as isMcpContentProtected};
1
+ import{extractTokenFromAuthHeader as u}from"../../../plugins/mcp/utils/jwt.js";import{SUPPORTED_MCP_SCOPES as d}from"../constants.js";import{getUserParamsFromCookies as p}from"../../../web-server/auth.js";import{ServerRoutes as s}from"../../../../constants/api.js";import{withPathPrefix as l}from"@redocly/theme/core/utils";import{shouldHandleMcpAuth as h}from"../../../utils/rbac/should-handle-mcp-auth.js";import{isAssistantAnonymousToken as f}from"./assistant-anonymous-token.js";function R(t){const e=t.getConfig().access;return h(!!e?.requiresLogin,e?.rbac||{})}async function _(t,e){const n=t.headers.get("Authorization");if(!n)return{isAuthenticated:!1};const o=u(n);if(o&&await f(o))return{isAuthenticated:!1,isTokenValid:!0,isFirstPartyAnonymous:!0};const r=e?.config?.ssoDirect||{},i=o?await p(r,{authorization:o}):{};return o&&i&&i.isAuthenticated?{isAuthenticated:!0,isTokenValid:!0,currentUser:{teams:i.teams||[],email:i.email||"",claims:i,isAuthenticated:!0,idpAccessToken:i.idpAccessToken||void 0,idpId:i.idpId||void 0},accessToken:o}:{isAuthenticated:!1,isTokenValid:!1}}function a(t,e){const n=`${t}${s.MCP_OAUTH_PROTECTED_RESOURCE}${l("/mcp")}`,o=`${t}${s.MCP_OAUTH_AUTHORIZATION_SERVER}`,r=e?[`error="${e.code}"`,`error_description="${e.description}"`]:[];return r.push(`resource_metadata="${n}"`,`scope="${d.join(" ")}"`,`authorization_uri="${o}"`),`Bearer ${r.join(", ")}`}function c(t,e){return e?`${t}. A public endpoint that serves anonymous-accessible content is available at ${e}.`:t}function $(t,e){const n=c("Authentication required",e);return new Response(JSON.stringify({error:"unauthorized",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":a(t),"Access-Control-Allow-Origin":"*"}})}function y(){return new Response(JSON.stringify({error:"forbidden",message:"You do not have access to this MCP server"}),{status:403,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}function v(t,e){const n=c("Invalid or expired token",e);return new Response(JSON.stringify({error:"invalid_token",message:n}),{status:401,headers:{"Content-Type":"application/json","WWW-Authenticate":a(t,{code:"invalid_token",description:"Invalid or expired token"}),"Access-Control-Allow-Origin":"*"}})}export{y as constructForbiddenResponse,v as constructInvalidTokenResponse,$ as constructUnauthorizedResponse,_ as handleMcpAuth,R as isMcpContentProtected};
@@ -4,9 +4,14 @@ import type { SandboxCapability } from './capabilities/types.js';
4
4
  export type ToolListEntry = {
5
5
  name: string;
6
6
  purpose?: string;
7
+ /** A platform tool whose name explains it; its purpose gives way before a custom tool's. */
8
+ builtIn?: boolean;
7
9
  };
8
10
  /** Maps MCP tool schemas and active capabilities to tool-list entries (sandbox names). */
9
11
  export declare function toToolListEntries(tools: McpToolSchema[], capabilities: SandboxCapability[]): ToolListEntry[];
10
- /** Renders one `- name — purpose` line per entry within `maxChars`. */
12
+ /**
13
+ * Renders one `- name — purpose` line per entry within `maxChars`. Built-in purposes shorten
14
+ * and then drop before custom purposes shorten; names alone are the last resort.
15
+ */
11
16
  export declare function buildToolList(entries: ToolListEntry[], maxChars: number): string;
12
17
  //# sourceMappingURL=build-tool-list.d.ts.map
@@ -1,2 +1,2 @@
1
- import{sanitizeToolName as s}from"./build-tool-type-declarations.js";const l=60;function a(e,t){return[...e.map(n=>({name:s(n.name),purpose:n.description})),...t.map(n=>({name:s(n.id),purpose:n.purpose}))]}function $(e,t){if(e.length===0||t<=0)return"";const o=e.map(({name:r,purpose:f})=>{const i=(f??"").replace(/\s+/g," ").trim();if(!i)return`- ${r}`;const m=i.length>l?`${i.slice(0,l-1)}\u2026`:i;return`- ${r} \u2014 ${m}`}).join(`
2
- `);if(o.length<=t)return o;const u=e.map(r=>r.name),p=u.join(", ");return p.length<=t?p:h(u,t)}function h(e,t){const n=[];for(const o of e){if([...n,o].join(", ").length+c(e.length-n.length-1).length>t)break;n.push(o)}return n.length>0?`${n.join(", ")}${c(e.length-n.length)}`:""}function c(e){return e>0?` \u2026 (+${e} more)`:""}export{$ as buildToolList,a as toToolListEntries};
1
+ import{ALL_DEFAULT_TOOL_NAMES as p}from"../docs-mcp/tool-schemas.js";import{sanitizeToolName as c}from"./build-tool-type-declarations.js";const i=60,f=20,m=40;function L(n,e){return[...n.map(t=>({name:c(t.name),purpose:t.description,builtIn:p.has(t.name)})),...e.map(t=>({name:c(t.id),purpose:t.purpose,builtIn:!0}))]}function N(n,e){if(n.length===0||e<=0)return"";const t=n.map(o=>({...o,purpose:(o.purpose??"").replace(/\s+/g," ").trim()}));for(const o of a()){const s=h(t,o);if(s.length<=e)return s}const r=n.map(o=>o.name),u=r.join(", ");return u.length<=e?u:_(r,e)}function*a(){for(let n=i;n>=m;n--)yield{builtIn:n,custom:i};for(let n=i;n>=f;n--)yield{builtIn:0,custom:n}}function h(n,e){return n.map(({name:t,purpose:r,builtIn:u})=>{const o=u?e.builtIn:e.custom;return r&&o>0?`- ${t} \u2014 ${g(r,o)}`:`- ${t}`}).join(`
2
+ `)}function g(n,e){return n.length<=e?n:`${n.slice(0,e-1).replace(/[\uD800-\uDBFF]$/,"").trimEnd()}\u2026`}function _(n,e){const t=[];for(const r of n){if([...t,r].join(", ").length+l(n.length-t.length-1).length>e)break;t.push(r)}return t.length>0?`${t.join(", ")}${l(n.length-t.length)}`:""}function l(n){return n>0?` \u2026 (+${n} more)`:""}export{N as buildToolList,L as toToolListEntries};
@@ -1,5 +1,6 @@
1
1
  import type { CodeAudit } from './code-audit.js';
2
- type CodeExecutionAuditRecord = {
2
+ import type { McpCallAttribution } from '../types.js';
3
+ type CodeExecutionAuditRecord = Pick<McpCallAttribution, 'requestId' | 'messageId'> & {
3
4
  audit: CodeAudit;
4
5
  code: string;
5
6
  description: string;
@@ -12,6 +13,6 @@ type CodeExecutionAuditRecord = {
12
13
  * Full sandbox input for one code mode `execute`, keyed by the same `code_sha256` the
13
14
  * `mcpServer.codeExecuted` telemetry event carries, so a Grafana row resolves to this line.
14
15
  */
15
- export declare function logCodeExecutionAudit({ audit, code, description, sessionHandle, toolNames, fetchBudget, fetchCapable, }: CodeExecutionAuditRecord): void;
16
+ export declare function logCodeExecutionAudit({ audit, code, description, sessionHandle, toolNames, fetchBudget, fetchCapable, requestId, messageId, }: CodeExecutionAuditRecord): void;
16
17
  export {};
17
18
  //# sourceMappingURL=code-execution-audit.d.ts.map
@@ -1 +1 @@
1
- import{auditInput as t,auditSha256 as h,logAuditRecord as a}from"../audit/audit-log.js";function g({audit:e,code:c,description:d,sessionHandle:o,toolNames:i,fetchBudget:n,fetchCapable:u}){a("Record code execution input",{code_sha256:e.sha256,code_length:e.length,flags:e.flags,subject_sha256:o?h(o):void 0,description:t(d),tools:[...i].sort().join(","),fetch_capable:u,fetch_budget:n,code:t(c)})}export{g as logCodeExecutionAudit};
1
+ import{auditInput as t,auditSha256 as g,logAuditRecord as h}from"../audit/audit-log.js";function f({audit:e,code:c,description:d,sessionHandle:o,toolNames:i,fetchBudget:u,fetchCapable:n,requestId:s,messageId:a}){h("Record code execution input",{code_sha256:e.sha256,code_length:e.length,request_id:s,message_id:a,flags:e.flags,subject_sha256:o?g(o):void 0,description:t(d),tools:[...i].sort().join(","),fetch_capable:n,fetch_budget:u,code:t(c)})}export{f as logCodeExecutionAudit};
@@ -1,18 +1,17 @@
1
1
  import { telemetry } from '../../../telemetry/index.js';
2
2
  import type { CodeAudit } from './code-audit.js';
3
+ import type { McpCallAttribution } from '../types.js';
3
4
  type CodeExecutedData = Parameters<typeof telemetry.sendMcpCodeExecutedMessage>[0][number];
4
5
  export type McpCodeFailureReason = NonNullable<CodeExecutedData['failure_reason']>;
5
- type CodeExecutedEvent = {
6
+ type CodeExecutedEvent = McpCallAttribution & {
6
7
  audit: CodeAudit;
7
8
  fetchCount: number;
8
9
  outcome: CodeExecutedData['outcome'];
9
10
  durationMs: number;
10
11
  failureReason?: McpCodeFailureReason;
11
12
  failedTool?: string;
12
- client?: string;
13
- clientVersion?: string;
14
13
  };
15
14
  /** Audit record for one sandbox run. Carries the code fingerprint, never the code. */
16
- export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, failureReason, failedTool, client, clientVersion, }: CodeExecutedEvent): void;
15
+ export declare function reportCodeExecuted({ audit, fetchCount, outcome, durationMs, failureReason, failedTool, client, clientVersion, requestId, messageId, }: CodeExecutedEvent): void;
17
16
  export {};
18
17
  //# sourceMappingURL=code-execution-telemetry.d.ts.map
@@ -1 +1 @@
1
- import{telemetry as l}from"../../../telemetry/index.js";import{logger as n}from"../../../tools/notifiers/logger.js";import{McpServerType as m}from"../constants.js";import{serverAttributes as h}from"../utils/telemetry-attributes.js";function d({audit:e,fetchCount:t,outcome:c,durationMs:s,failureReason:o,failedTool:r,client:f,clientVersion:g}){try{l.sendMcpCodeExecutedMessage([{...h(m.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:t,outcome:c,flags:e.flags,duration_ms:s,failure_reason:o,failed_tool:r,client:f,client_version:g}])}catch{}n.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${c} codeLength=${e.length} fetchCount=${t}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${s}`+(o?` failureReason=${o}`:"")+(r?` failedTool=${r}`:""))}export{d as reportCodeExecuted};
1
+ import{telemetry as m}from"../../../telemetry/index.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{McpServerType as p}from"../constants.js";import{serverAttributes as a}from"../utils/telemetry-attributes.js";function x({audit:e,fetchCount:t,outcome:s,durationMs:c,failureReason:o,failedTool:r,client:g,clientVersion:f,requestId:l,messageId:n}){try{m.sendMcpCodeExecutedMessage([{...a(p.Docs),code_sha256:e.sha256,code_length:e.length,fetch_count:t,outcome:s,flags:e.flags,duration_ms:c,failure_reason:o,failed_tool:r,client:g,client_version:f,message_id:n}],{requestId:l})}catch{}h.info(`Gateway MCP code executed [${e.sha256.slice(0,12)}] outcome=${s} codeLength=${e.length} fetchCount=${t}`+(e.flags?` flags=${e.flags}`:"")+` durationMs=${c}`+(o?` failureReason=${o}`:"")+(r?` failedTool=${r}`:""))}export{x as reportCodeExecuted};
@@ -1,7 +1,7 @@
1
1
  import{buildToolList as i}from"./build-tool-list.js";const r=2048,d="Both `execute` arguments are required: `code` (the JavaScript to run; return a value to receive it) and `description` (a short human-readable summary of what the code does).",n="Available tools (exact signatures come from `describe-tools`):";function a(e,t){if(t.length===0)return e;const o=r-e.length-n.length-3,s=i(t,o);return s?[e,"",n,s].join(`
2
2
  `):e}function h(e,t=[]){const o=["Run JavaScript in a sandbox against the documentation tools on the global `tools` object.",e?"The extra globals are `tools`, `fetch`, `URL`, `URLSearchParams`, and `FormData` - there is no `console`, `setTimeout`, `require`, or Node.js API; all other I/O goes through `tools`.":"The only extra global is `tools` - there is no `fetch`, `console`, `setTimeout`, `require`, or Node.js API; all I/O goes through `tools`.","","Workflow - minimize round-trips; one `describe-tools` call plus one `execute` call covers most requests:","1. Analyze the request and decide which sandbox tools it needs.","2. Call `describe-tools` with those names to get their exact TypeScript signatures - inputs, result shapes, and a worked example. NEVER call `execute` with guessed method names, parameter names, enum values, or result field names: read fields off the declared return types, not from assumptions.","3. Batch everything into a SINGLE script: chain tool calls, pass one call's output into the next, process results in plain JavaScript, and `return` only what the request needs."].join(`
3
3
  `);return a(o,t)}const p=["Get the exact TypeScript signatures of the sandbox tools available to `execute`.","Analyze the user request first, then pass `tools` with only the tool names the request needs (every name is listed in this input schema / description); omit `tools` only when you cannot tell which tools apply.","Always call this before your first `execute` and never guess signatures. Request every tool the task may need in ONE call instead of calling this repeatedly."].join(`
4
- `);function m(e,t=[]){const o=["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through `describe-tools` and `execute`:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with only the tool names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",...e?["The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs."]:[]].join(`
4
+ `);function m(e,t=[]){const o=["This server exposes documentation tools (API discovery, endpoint details, security schemes, full-text search) through `describe-tools` and `execute`:","- `describe-tools` returns the exact TypeScript signatures of the sandbox tools.","- `execute` runs JavaScript that calls those tools on the global `tools` object.","Workflow: analyze the request, call `describe-tools` once with `tools` set to only the names it needs, then batch everything into a single `execute` script. Minimize round-trips and never guess tool signatures.",...e?["The sandbox also has a global `fetch` that can call the documented APIs (allow-listed hosts only). Include `fetch` in your `describe-tools` call to get its contract and the list of callable APIs."]:[]].join(`
5
5
  `);return a(o,t)}const l=["listApis","getEndpoints"],c=["Example - list the write endpoints of an API:","","```ts","const { items } = await tools.listApis({ filter: 'billing' });","const [api] = items;",`if (!api) return { error: 'no API matches "billing"' };`,"const { endpoints } = await tools.getEndpoints({ name: api.name });","const writes = endpoints.filter((e) => e.method !== 'GET');","return { api: api.name, writes: writes.map((e) => `${e.method} ${e.path}`) };","```"].join(`
6
6
  `);function g(e){if(l.every(o=>e.includes(o)))return c;const[t]=e;return t?[`Example - call \`${t}\` and return what the request needs:`,"","```ts",`const result = await tools.${t}({ /* the input its signature above declares */ });`,"return result;","```"].join(`
7
7
  `):""}const b=["Types named `OpenApi\u2026` are the standard OpenAPI Specification objects.","Payload samples live on a media type object (`requestBody.content[mediaType]`, `responses[code].content[mediaType]`): `.example` holds a single value, `.examples[name].value` a named map, and some descriptions only set `.schema.example`. Read each before concluding a sample is absent."].join(`
@@ -1,3 +1,3 @@
1
- import{renderDescribeToolsOutput as S}from"../capabilities/index.js";import{McpServerType as v}from"../../constants.js";import{reportMcpToolCalled as _,reportMcpToolError as k}from"../../workers/mcp-tool-telemetry.js";import{DESCRIBE_TOOLS_TOOL_NAME as d}from"../constants.js";import{DESCRIBE_TOOLS_DESCRIPTION as D}from"../prompts.js";import{sanitizeToolName as n}from"../build-tool-type-declarations.js";import{UnknownToolError as M}from"./tool-errors.js";function q(a,c){const t=[...new Set([...a.map(s=>n(s.name)),...c.map(s=>n(s.id))])];return{name:d,title:"Describe tools",description:D,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},schema:{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:`Tool names to describe: ${t.join(", ")}. Omit to describe everything.`,items:t.length>0?{type:"string",enum:t}:{type:"string"},nullable:!0}}}}}function x(a,c,t,s){const l=new Map(a.map(r=>[n(r.name),r])),f=new Map(t.map(r=>[n(r.id),r]));return async r=>{const u=performance.now(),h=s.mcpMode??"code";try{const o=[...new Set((r.tools??[]).map(n))],i=o.length===0,y=o.filter(e=>!l.has(e)&&!f.has(e));if(y.length>0){const e=[...l.keys(),...f.keys()];throw new M(`Unknown tool(s): ${y.join(", ")}. Valid tools: ${e.join(", ")}.`)}const E=i?t:t.filter(e=>o.includes(n(e.id))),p=i?a:o.filter(e=>l.has(e)).map(e=>l.get(e)),T=await Promise.all(p.map(e=>c(e.name))),O=p.filter((e,m)=>T[m]),w=p.filter((e,m)=>!T[m]),g=[S(O,E,s)];w.length>0&&g.push(`Not available for this request: ${w.map(e=>n(e.name)).join(", ")}`);const b=g.join(`
1
+ import{renderDescribeToolsOutput as _}from"../capabilities/index.js";import{McpServerType as u}from"../../constants.js";import{logMcpToolCallAudit as E,reportMcpToolCalled as k,reportMcpToolError as C}from"../../workers/mcp-tool-telemetry.js";import{DESCRIBE_TOOLS_TOOL_NAME as l}from"../constants.js";import{DESCRIBE_TOOLS_DESCRIPTION as j}from"../prompts.js";import{sanitizeToolName as s}from"../build-tool-type-declarations.js";import{UnknownToolError as O}from"./tool-errors.js";import{callAttribution as N}from"../../utils/telemetry-attributes.js";function U(c,f){const r=[...new Set([...c.map(n=>s(n.name)),...f.map(n=>s(n.id))])];return{name:l,title:"Describe tools",description:j,annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},schema:{type:"object",required:[],additionalProperties:!1,properties:{tools:{type:"array",description:`Tool names to describe: ${r.join(", ")}. Omit to describe everything.`,items:r.length>0?{type:"string",enum:r}:{type:"string"},nullable:!0}}}}}function x(c,f,r,n){const p=new Map(c.map(t=>[s(t.name),t])),w=new Map(r.map(t=>[s(t.id),t]));return async t=>{const b=performance.now(),m=n.mcpMode??"code",d=N(n);try{const o=[...new Set((t.tools??[]).map(s))],i=o.length===0,a=o.filter(e=>!p.has(e)&&!w.has(e));if(a.length>0){const e=[...p.keys(),...w.keys()];throw new O(`Unknown tool(s): ${a.join(", ")}. Valid tools: ${e.join(", ")}.`)}const S=i?r:r.filter(e=>o.includes(s(e.id))),T=i?c:o.filter(e=>p.has(e)).map(e=>p.get(e)),v=await Promise.all(T.map(e=>f(e.name))),D=T.filter((e,y)=>v[y]),M=T.filter((e,y)=>!v[y]),g=[_(D,S,n)];M.length>0&&g.push(`Not available for this request: ${M.map(e=>s(e.name)).join(", ")}`);const h=g.join(`
2
2
 
3
- `);return _({tool:d,mode:h,serverType:v.Docs,durationMs:Math.round(performance.now()-u),outputLength:b.length}),{content:[{type:"text",text:b}]}}catch(o){const i=o instanceof M;throw k({tool:d,mode:h,serverType:v.Docs,durationMs:Math.round(performance.now()-u),message:o instanceof Error?o.message:String(o),stack:!i&&o instanceof Error&&o.stack||"",errorClass:i?"tool_error":"server_error"}),o}}}export{x as describeTools,q as describeToolsSchema};
3
+ `);return E({tool:l,mode:m,serverType:u.Docs,args:t,result:h,...d}),k({tool:l,mode:m,serverType:u.Docs,durationMs:Math.round(performance.now()-b),outputLength:h.length,...d}),{content:[{type:"text",text:h}]}}catch(o){const i=o instanceof O,a=i?"tool_error":"server_error";throw E({tool:l,mode:m,serverType:u.Docs,args:t,errorClass:a,...d}),C({tool:l,mode:m,serverType:u.Docs,durationMs:Math.round(performance.now()-b),message:o instanceof Error?o.message:String(o),stack:!i&&o instanceof Error&&o.stack||"",errorClass:a,...d}),o}}}export{x as describeTools,U as describeToolsSchema};
@@ -1 +1 @@
1
- import{runInSandbox as y}from"../../../../sandbox/sandbox.js";import{SANDBOX_FAILURE as b}from"../../../../sandbox/constants/sandbox.js";import{returnLastExpression as g}from"../../../../sandbox/utils/return-last-expression.js";import{isMcpToolAvailable as A}from"../../workers/execute-mcp-tool.js";import{importMcpToolHandlers as M}from"../../workers/import-mcp-tool-handlers.js";import{isFetchCapable as S}from"../../gateway-mcp/callable-apis.js";import{buildExecuteHostFetch as k}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as v}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as x,EXECUTE_TOOL_NAME as F}from"../constants.js";import{sanitizeToolName as H}from"../build-tool-type-declarations.js";import{invokeTool as R}from"../invoke-tool.js";import{createSandboxSetup as D}from"../sandbox/create-sandbox-setup.js";import{createToolInputValidator as j}from"../sandbox/tool-input-validator.js";import{describeGuestError as B}from"../sandbox/unknown-tool-hint.js";import{auditCode as I}from"../code-audit.js";import{reportCodeExecuted as L}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as N}from"../code-execution-audit.js";import{ToolResultError as P}from"./tool-errors.js";const V=async(e,t,n)=>{const i=new Map,s=await X(t,n,i),a=[],o=S(t)?await k(t,E=>a.push(E)):void 0;let f=0;const m=o?E=>(f+=1,o(E).catch(O=>{throw i.set(T(O),{reason:"runtime_error"}),O})):void 0,c=I(e.code);N({audit:c,code:e.code,description:e.description,sessionHandle:e.sessionHandle,toolNames:Object.keys(s),fetchBudget:t.gatewayFetchBudgetPerExec,fetchCapable:o!==void 0});const l=Date.now(),d=g(e.code),{result:u,error:r,failure:w,errorPosition:C}=await y(d,{setupContext:D(s,m),authoredCode:e.code}),p=r===void 0?void 0:B(d,r,C,Object.keys(s)),h=r!==void 0&&w===b.HostError?i.get(r):void 0;L({audit:c,fetchCount:f,outcome:r===void 0?"ok":"error",durationMs:Date.now()-l,failureReason:U(w,h,p?.unknownTool),failedTool:h?.tool,client:t.client,clientVersion:t.clientVersion});const _=p===void 0?{result:u}:{error:p.message};return v({content:[{type:"text",text:JSON.stringify(_)}],structuredContent:_,isError:r!==void 0,...h?.tool!==void 0?{errorClass:"tool_error"}:{}},a)};function U(e,t,n){return e===b.HostError?t?.reason??"runtime_error":e===b.RuntimeError?n===void 0?e:"unknown_tool":e}async function X(e,t,n){const i=Object.keys(await M()).filter(o=>!x.has(o)),s=await Promise.all(i.map(o=>A({toolName:o,context:e}).catch(()=>!1))),a={};return i.forEach((o,f)=>{if(!s[f])return;const m=H(o),c=e.sandboxToolSchemas?.[o],l=c?j(m,c):void 0;a[m]=d=>{const u=l?.(d);return u?(n.set(u,{tool:o,reason:"inner_tool_error"}),Promise.reject(new Error(u))):R(o,d,e,t).catch(r=>{throw n.set(T(r),{tool:o,reason:r instanceof P?"inner_tool_error":"server_error"}),r})}}),a}function T(e){return e instanceof Error?e.message:String(e)}var ce={[F]:V};export{ce as default};
1
+ import{runInSandbox as y}from"../../../../sandbox/sandbox.js";import{SANDBOX_FAILURE as b}from"../../../../sandbox/constants/sandbox.js";import{returnLastExpression as M}from"../../../../sandbox/utils/return-last-expression.js";import{isMcpToolAvailable as v}from"../../workers/execute-mcp-tool.js";import{reportMcpToolError as A}from"../../workers/mcp-tool-telemetry.js";import{McpServerType as S}from"../../constants.js";import{callAttribution as C}from"../../utils/telemetry-attributes.js";import{importMcpToolHandlers as I}from"../../workers/import-mcp-tool-handlers.js";import{isFetchCapable as k}from"../../gateway-mcp/callable-apis.js";import{buildExecuteHostFetch as F}from"../../gateway-mcp/fetch-capability.js";import{withAuthRequiredMeta as D}from"../../gateway-mcp/upstream-auth.js";import{CODE_MODE_TOOL_NAMES as H,EXECUTE_TOOL_NAME as R}from"../constants.js";import{sanitizeToolName as x}from"../build-tool-type-declarations.js";import{invokeTool as j}from"../invoke-tool.js";import{createSandboxSetup as B}from"../sandbox/create-sandbox-setup.js";import{createToolInputValidator as L}from"../sandbox/tool-input-validator.js";import{describeGuestError as P}from"../sandbox/unknown-tool-hint.js";import{auditCode as q}from"../code-audit.js";import{reportCodeExecuted as N}from"../code-execution-telemetry.js";import{logCodeExecutionAudit as U}from"../code-execution-audit.js";import{ToolResultError as X}from"./tool-errors.js";const z=async(o,r,n)=>{const s=new Map,a=await J(r,n,s),d=[],e=k(r)?await F(r,h=>d.push(h)):void 0;let m=0;const f=e?h=>(m+=1,e(h).catch(w=>{throw s.set(O(w),{reason:"runtime_error"}),w})):void 0,u=q(o.code);U({audit:u,code:o.code,description:o.description,sessionHandle:o.sessionHandle,toolNames:Object.keys(a),fetchBudget:r.gatewayFetchBudgetPerExec,fetchCapable:e!==void 0,requestId:r.requestId,messageId:r.messageId});const l=Date.now(),c=M(o.code),{result:i,error:t,failure:T,errorPosition:g}=await y(c,{setupContext:B(a,f),authoredCode:o.code}),p=t===void 0?void 0:P(c,t,g,Object.keys(a)),E=t!==void 0&&T===b.HostError?s.get(t):void 0;N({audit:u,fetchCount:m,outcome:t===void 0?"ok":"error",durationMs:Date.now()-l,failureReason:G(T,E,p?.unknownTool),failedTool:E?.tool,...C(r)});const _=p===void 0?{result:i}:{error:p.message};return D({content:[{type:"text",text:JSON.stringify(_)}],structuredContent:_,isError:t!==void 0,...E?.tool!==void 0?{errorClass:"tool_error"}:{}},d)};function G(o,r,n){return o===b.HostError?r?.reason??"runtime_error":o===b.RuntimeError?n===void 0?o:"unknown_tool":o}async function J(o,r,n){const s=Object.keys(await I()).filter(e=>!H.has(e)),a=await Promise.all(s.map(e=>v({toolName:e,context:o}).catch(()=>!1))),d={};return s.forEach((e,m)=>{if(!a[m])return;const f=x(e),u=o.sandboxToolSchemas?.[e],l=u?L(f,u):void 0;d[f]=c=>{const i=l?.(c);return i?(A({tool:e,message:i,mode:"code",serverType:S.Docs,durationMs:0,errorClass:"tool_error",...C(o)}),n.set(i,{tool:e,reason:"inner_tool_error"}),Promise.reject(new Error(i))):j(e,c,o,r).catch(t=>{throw n.set(O(t),{tool:e,reason:t instanceof X?"inner_tool_error":"server_error"}),t})}}),d}function O(o){return o instanceof Error?o.message:String(o)}var Eo={[R]:z};export{Eo as default};
@@ -1,2 +1,2 @@
1
- import{MANAGE_API_CREDENTIALS_TOOL_NAME as P}from"../../constants.js";import{buildUpstreamCredentialFallback as b,buildUpstreamCredentialInputRequired as I,dedupeElicitation as S,isCredentialElicitationDeclined as k,isStatelessRequest as E,schemeLabelOf as w,supportsUrlElicitation as C}from"../../gateway-mcp/elicitation.js";import{getCallableApis as u,isFetchCapable as j}from"../../gateway-mcp/callable-apis.js";import{secretStore as T}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as q,resolveSecretSubject as $}from"../../gateway-mcp/subject.js";import{upstreamAuthKey as H}from"../../gateway-mcp/upstream-auth.js";import{resolveUpstreamApiAuth as R}from"../../gateway-mcp/upstream-auth-scheme.js";import{apiTitleKey as L,countApiTitles as N}from"../../docs-mcp/utils/api-titles.js";function W(e){return!!e.elicitationEnabled&&j(e)}function z(e){const s=u(e),t=s.map(i=>i.relativePath),a=[...t,...O(s)];return{name:P,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
2
- `),annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},schema:{type:"object",required:["api"],additionalProperties:!1,properties:{api:{type:"string",description:`The API to manage credentials for: its \`filePath\` or the \`name\` from \`listApis\`.${t.length>0?` The file paths are: ${t.join(", ")}.`:""}`,minLength:1,...a.length>0?{enum:a}:{}},scheme:{type:"string",description:"Name of the security scheme to manage the credential for, as named in the API description (a tool result that reports a rejected credential names it). Omit it to let the link cover every scheme the API accepts.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required while the caller is anonymous, so the credentials are stored against the same subject the API calls use.",minLength:1}}}}}function O(e){const s=N(e);return e.map(t=>t.name).filter(t=>s.get(L(t))===1)}function J(e,s){return async(t,a)=>{const i=$(e.user,typeof t.sessionHandle=="string"?t.sessionHandle:void 0);if(i.kind==="invalid")return h(i.message);if(i.kind==="anonymous")return h(q);const{subject:m}=i,p=typeof t.api=="string"?t.api:"",n=u(e).find(c=>c.relativePath===p||c.name===p);if(!n){const c=u(e).map(g=>g.relativePath).join(", ");return h(`Unknown api "${p}". Credentials can only be managed for the APIs this server can call: ${c||"none"}.`)}if(k(a.mcpReq.inputResponses))return{content:[{type:"text",text:`The user declined the credentials prompt for the "${n.name}" API, so this call minted no link.`}],isError:!1};const r=await R(e,n.relativePath),l=typeof t.scheme=="string"?t.scheme:void 0,y=Object.keys(r.schemes);if(l&&!r.schemes[l])return h(`Unknown scheme "${l}" for api "${n.relativePath}". The security schemes this server can store credentials for are: ${y.join(", ")}.`);const o=l??r.defaultScheme,d=w(r.schemes,o),f=await s.getKv(),A={subject:m,baseUrl:e.baseUrl??"",target:{api:n.relativePath,name:n.name,scheme:o,...d?{schemeLabel:d}:{}},auth:r.schemes[o],apiAuth:r,kv:f,hasExistingSecret:await T.hasSecret(f,m,n.relativePath,o),reason:{kind:"requested"}};if(E(a.mcpReq)&&C(s.getClientCapabilities()))return await I(A);const v=H({api:n.relativePath,scheme:o});return{content:[{type:"text",text:await S(`${m}:${v}`,()=>b(A))}],isError:!1}}}function h(e){return{content:[{type:"text",text:e}],isError:!0}}export{W as isManageApiCredentialsToolAvailable,J as manageApiCredentials,z as manageApiCredentialsSchema};
1
+ import{MANAGE_API_CREDENTIALS_TOOL_NAME as P}from"../../constants.js";import{acceptedCredentialsLink as k,buildCredentialsAcceptedHint as w,buildUpstreamCredentialFallback as S,buildUpstreamCredentialInputRequired as I,credentialElicitationAnswer as E,dedupeElicitation as C,isStatelessRequest as j,schemeLabelOf as q,supportsUrlElicitation as T}from"../../gateway-mcp/elicitation.js";import{getCallableApis as u,isFetchCapable as H}from"../../gateway-mcp/callable-apis.js";import{secretStore as R}from"../../gateway-mcp/secret-store.js";import{MISSING_SESSION_HANDLE_MESSAGE as U,resolveSecretSubject as $}from"../../gateway-mcp/subject.js";import{upstreamAuthKey as L}from"../../gateway-mcp/upstream-auth.js";import{resolveUpstreamApiAuth as N}from"../../gateway-mcp/upstream-auth-scheme.js";import{apiTitleKey as O,countApiTitles as _}from"../../docs-mcp/utils/api-titles.js";function Q(e){return!!e.elicitationEnabled&&H(e)}function V(e){const s=u(e),t=s.map(i=>i.relativePath),r=[...t,...M(s)];return{name:P,title:"Manage API credentials",description:["Get a secure link where the user sets, replaces, or removes the credentials this server sends to a documented API.","Call it when the user wants to change or clear an API key, or when a tool result tells you the stored credentials were rejected.","The link covers every credential the API accepts, so scheme is optional - pass it only when a tool result names the scheme that was rejected.","It returns a link for the user to open - never ask for the secret in the conversation and never pass it as an argument."].join(`
2
+ `),annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},schema:{type:"object",required:["api"],additionalProperties:!1,properties:{api:{type:"string",description:`The API to manage credentials for: its \`filePath\` or the \`name\` from \`listApis\`.${t.length>0?` The file paths are: ${t.join(", ")}.`:""}`,minLength:1,...r.length>0?{enum:r}:{}},scheme:{type:"string",description:"Name of the security scheme to manage the credential for, as named in the API description (a tool result that reports a rejected credential names it). Omit it to let the link cover every scheme the API accepts.",minLength:1},sessionHandle:{type:"string",description:"Handle returned by createAnonymousSession. Required while the caller is anonymous, so the credentials are stored against the same subject the API calls use.",minLength:1}}}}}function M(e){const s=_(e);return e.map(t=>t.name).filter(t=>s.get(O(t))===1)}function X(e,s){return async(t,r)=>{const i=$(e.user,typeof t.sessionHandle=="string"?t.sessionHandle:void 0);if(i.kind==="invalid")return m(i.message);if(i.kind==="anonymous")return m(U);const{subject:c}=i,p=typeof t.api=="string"?t.api:"",n=u(e).find(o=>o.relativePath===p||o.name===p);if(!n){const o=u(e).map(b=>b.relativePath).join(", ");return m(`Unknown api "${p}". Credentials can only be managed for the APIs this server can call: ${o||"none"}.`)}const d=E(r.mcpReq.inputResponses);if(d==="accepted"){const o=await k(r.mcpReq.requestState(),{kv:await s.getKv(),subject:c,baseUrl:e.baseUrl??"",apis:[n.relativePath]});return{content:[{type:"text",text:w(n.name,o?.url)}],isError:!1}}if(d==="declined")return{content:[{type:"text",text:`The user declined the credentials prompt for the "${n.name}" API, so this call minted no link.`}],isError:!1};const a=await N(e,n.relativePath),h=typeof t.scheme=="string"?t.scheme:void 0,y=Object.keys(a.schemes);if(h&&!a.schemes[h])return m(`Unknown scheme "${h}" for api "${n.relativePath}". The security schemes this server can store credentials for are: ${y.join(", ")}.`);const l=h??a.defaultScheme,f=q(a.schemes,l),A=await s.getKv(),v={subject:c,baseUrl:e.baseUrl??"",target:{api:n.relativePath,name:n.name,scheme:l,...f?{schemeLabel:f}:{}},auth:a.schemes[l],apiAuth:a,kv:A,hasExistingSecret:await R.hasSecret(A,c,n.relativePath,l),reason:{kind:"requested"}};if(j(r.mcpReq)&&T(s.getClientCapabilities()))return await I(v);const g=L({api:n.relativePath,scheme:l});return{content:[{type:"text",text:await C(`${c}:${g}`,()=>S(v))}],isError:!1}}}function m(e){return{content:[{type:"text",text:e}],isError:!0}}export{Q as isManageApiCredentialsToolAvailable,X as manageApiCredentials,V as manageApiCredentialsSchema};
@@ -1 +1 @@
1
- import{basename as f,join as d}from"node:path";import{envConfig as p}from"../../../config/env-config.js";import{reporter as i}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as E}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as O}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as h}from"./extract-tool-definition.js";const T=/(^|\/)@mcp\/.*\.(ts|js)$/,M=/^[a-zA-Z0-9_-]{1,64}$/,_=new Set([...E,...O]);async function S(o,r,a){if(!p.REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED)return 0;C(o,a);const u=new Set(o.getMcpTools().map(n=>n.name)),l=new Map;for(const n of r.fs.scan(T)){if(n.isVirtual||n.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=n,e=f(t).replace(/\.(ts|js)$/,"");if(!M.test(e)){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is derived from the file name and may only contain letters, numbers, hyphens, and underscores (max 64 characters). Rename the file.`);continue}const c=l.get(e);if(c){await i.panicOnBuildContentError(`Duplicate MCP tool name "${e}": defined by both "${c}" and "${t}". Tool names are file names, so each file name must be unique across @mcp folders.`);continue}if(_.has(e)||u.has(e)){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is already used by a built-in MCP tool. Rename the file.`);continue}l.set(e,t);const m=d(o.contentDir,t),s=await h({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!s.ok){await i.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${s.errors.join(" ")}`);continue}o.addMcpTools(m,[s.schema]),a.registeredToolNames.push(e)}return a.registeredToolNames.length}function C(o,r){o.removeMcpTools(r.registeredToolNames),r.registeredToolNames=[]}export{C as resetCustomMcpTools,S as scanCustomMcpTools};
1
+ import{basename as d,join as p}from"node:path";import{envConfig as f}from"../../../config/env-config.js";import{logger as h}from"../../../tools/notifiers/logger.js";import{reporter as s}from"../../../tools/notifiers/reporter.js";import{CODE_MODE_TOOL_NAMES as O}from"../codemode/constants.js";import{ALL_DEFAULT_TOOL_NAMES as E}from"../docs-mcp/tool-schemas.js";import{extractToolDefinition as T}from"./extract-tool-definition.js";const M=/(^|\/)@mcp\/.*\.(ts|js)$/,_=/^[a-zA-Z0-9_-]{1,64}$/,C=new Set([...O,...E]);async function w(o,a,n){if(!f.REDOCLY_EXP_MCP_CUSTOM_TOOLS_ENABLED)return 0;N(o,n);const u=new Set(o.getMcpTools().map(r=>r.name)),l=new Map;for(const r of a.fs.scan(M)){if(r.isVirtual||r.relativePath.endsWith(".d.ts"))continue;const{relativePath:t}=r,e=d(t).replace(/\.(ts|js)$/,"");if(!_.test(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is derived from the file name and may only contain letters, numbers, hyphens, and underscores (max 64 characters). Rename the file.`);continue}const c=l.get(e);if(c){await s.panicOnBuildContentError(`Duplicate MCP tool name "${e}": defined by both "${c}" and "${t}". Tool names are file names, so each file name must be unique across @mcp folders.`);continue}if(C.has(e)||u.has(e)){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": the tool name "${e}" is already used by a built-in MCP tool. Rename the file.`);continue}l.set(e,t);const m=p(o.contentDir,t),i=await T({toolName:e,absoluteSourcePath:m,contentDir:o.contentDir,serverOutDir:o.serverOutDir});if(!i.ok){await s.panicOnBuildContentError(`Invalid MCP tool file "${t}": ${i.errors.join(" ")}`);continue}!i.schema.outputSchema&&!n.warnedNoOutputSchemaTools.has(e)&&(n.warnedNoOutputSchemaTools.add(e),h.warn(`MCP tool "${e}" in %rp declares no \`outputSchema\`. Add one that describes the returned value.`,t)),o.addMcpTools(m,[i.schema]),n.registeredToolNames.push(e)}return n.registeredToolNames.length}function N(o,a){o.removeMcpTools(a.registeredToolNames),a.registeredToolNames=[]}export{N as resetCustomMcpTools,w as scanCustomMcpTools};