@redocly/redoc 0.132.0 → 0.133.0-next.0

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 (76) hide show
  1. package/CHANGELOG.md +31 -6
  2. package/dist/cli/build/copy-env-files.js +1 -1
  3. package/dist/cli/develop.js +1 -1
  4. package/dist/cli/telemetry/index.js +1 -1
  5. package/dist/client/app/hooks/catalog/useFetchCatalogEntityRevisions.js +1 -1
  6. package/dist/constants/common.d.ts +2 -1
  7. package/dist/constants/common.js +1 -1
  8. package/dist/server/config/env-config.d.ts +157 -8
  9. package/dist/server/config/env-config.js +1 -1
  10. package/dist/server/config/env-schema.d.ts +148 -185
  11. package/dist/server/config/env-schema.js +1 -3
  12. package/dist/server/config/env-schemas/auth.d.ts +4 -4
  13. package/dist/server/config/env-schemas/auth.js +1 -1
  14. package/dist/server/config/env-schemas/catalog.d.ts +2 -2
  15. package/dist/server/config/env-schemas/catalog.js +1 -1
  16. package/dist/server/config/env-schemas/environment-detection.d.ts +13 -13
  17. package/dist/server/config/env-schemas/environment-detection.js +1 -1
  18. package/dist/server/config/env-schemas/feature-flags.d.ts +9 -6
  19. package/dist/server/config/env-schemas/feature-flags.js +1 -1
  20. package/dist/server/config/env-schemas/search.d.ts +1 -1
  21. package/dist/server/config/env-schemas/search.js +1 -1
  22. package/dist/server/config/env-schemas/server-config.d.ts +2 -2
  23. package/dist/server/config/env-schemas/server-config.js +1 -1
  24. package/dist/server/constants/entitlements.js +1 -1
  25. package/dist/server/esbuild/esbuild-logger.js +3 -3
  26. package/dist/server/esbuild/esbuild.js +2 -2
  27. package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +2 -0
  28. package/dist/server/persistence/kv/repositories/kv-remote-repository.js +2 -2
  29. package/dist/server/persistence/kv/services/kv-service.js +1 -1
  30. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  31. package/dist/server/plugins/catalog-entities/extensions/extractors/api-description/base.js +1 -1
  32. package/dist/server/plugins/catalog-entities/extensions/extractors/fs-entities-extractor.js +1 -1
  33. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  34. package/dist/server/plugins/default-theme/index.js +1 -1
  35. package/dist/server/plugins/enforce-login/index.js +1 -1
  36. package/dist/server/plugins/entitlements/utils/get-billed-catalog-build-pages-count.js +1 -1
  37. package/dist/server/plugins/lifecycle.js +1 -1
  38. package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +26 -26
  39. package/dist/server/plugins/scorecards/plugin.js +1 -1
  40. package/dist/server/providers/database/base-repository.d.ts +1 -0
  41. package/dist/server/providers/database/base-repository.js +5 -1
  42. package/dist/server/providers/database/database-preconnect-service.js +1 -1
  43. package/dist/server/providers/database/pagination/utils/extract-equal-filter-clause-value.d.ts +6 -0
  44. package/dist/server/providers/database/pagination/utils/extract-equal-filter-clause-value.js +1 -0
  45. package/dist/server/providers/database/pagination/utils/index.d.ts +1 -0
  46. package/dist/server/providers/database/pagination/utils/index.js +1 -1
  47. package/dist/server/providers/database/utils/storage-limit-validator.d.ts +13 -0
  48. package/dist/server/providers/database/utils/storage-limit-validator.js +1 -0
  49. package/dist/server/store.js +1 -1
  50. package/dist/server/telemetry/index.js +1 -1
  51. package/dist/server/tools/notifiers/formatter.js +3 -3
  52. package/dist/server/tools/notifiers/helpers/colors.js +1 -1
  53. package/dist/server/utils/envs/env-boolean-string.d.ts +12 -0
  54. package/dist/server/utils/envs/env-boolean-string.js +1 -0
  55. package/dist/server/utils/envs/load-env-variables.js +1 -1
  56. package/dist/server/utils/is-catalog-entities-enabled.js +1 -1
  57. package/dist/server/utils/is-scorecards-enabled.js +1 -1
  58. package/dist/server/utils/lifecycle-hooks.js +1 -1
  59. package/dist/server/version.js +1 -1
  60. package/dist/server/web-server/routes/catalog/bff-catalog-revisions.js +1 -1
  61. package/dist/server/web-server/routes/dynamic-route.js +1 -1
  62. package/dist/server/web-server/routes/feedback.js +1 -1
  63. package/dist/server/web-server/routes/index.js +1 -1
  64. package/dist/server/web-server/routes/otel/otel.d.ts +2 -16
  65. package/dist/server/web-server/routes/otel/otel.js +1 -1
  66. package/dist/server/web-server/routes/otel/otlp.d.ts +4 -1
  67. package/dist/server/web-server/routes/otel/otlp.js +1 -1
  68. package/dist/server/web-server/routes/static-content.js +1 -1
  69. package/dist/server/web-server/utils/content-type.d.ts +2 -0
  70. package/dist/server/web-server/utils/content-type.js +1 -0
  71. package/dist/types/entitlements.d.ts +1 -0
  72. package/package.json +12 -12
  73. package/dist/server/config/env-schemas/test.d.ts +0 -22
  74. package/dist/server/config/env-schemas/test.js +0 -1
  75. package/dist/server/utils/envs/write-env-variable.d.ts +0 -18
  76. package/dist/server/utils/envs/write-env-variable.js +0 -1
@@ -1 +1 @@
1
- import A from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as T}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as M}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as L}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as S}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as k}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{envConfig as G}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as I}from"./ssr/render.js";import{readStaticData as N,writeStaticData as V}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as H}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as R}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as U}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as q}from"./utils/redirects/find-redirect.js";import{followRedirectChain as x}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as W}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const v={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map"},m="markdown/partials",z="markdown/partials-deps",E="PLAN_GATES",Y=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Tt="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:s,serverMode:e=!1,serverOutDir:a}){this.#r=s,this.outdir=t,this.serverMode=e,this.serverOutDir=a,this.userCodeReady=new Promise(r=>{this.#a=r})}on(t,s){const e=this.listeners.get(t);e?e.add(s):this.listeners.set(t,new Set([s]))}queueEvent=(t,s,...e)=>{this.#e.set(t+String(s),[t,s,...e])};runListeners=(t,s,...e)=>{for(const a of this.listeners.get(t)||new Set)s?a(s,...e):a(...e)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=R.instance(),s=await H(this.serverOutDir),e=Object.fromEntries(Object.entries(s.tags).filter(([a])=>D[a]!=null?t.canAccessFeature(D[a]):!0));this.#s={...s,tags:e}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=t=>{const s=this.globalData,e={...this.globalData,...t};this.globalData=e,JSON.stringify(e)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,e)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:t,context:s,deps:e,resource:a})=>{const{data:{info:r,ast:o},compoundHash:l}=await j(t,this.markdocOptions,{actions:this,context:s},a);for(const i of r.sharedDataDeps||[]){for(const n of e?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of e?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const n of e?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of e?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(e?.routeSlugs&&r.partials?.length)for(const i of e.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of r.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:r,ast:o,compoundHash:l}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const s=Object.keys(t);for(const o of s)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=y(t,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:e,unsetEnvVars:a,replacedValues:r}=J(t);for(const o of a)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,r),Object.assign(this.config,e)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,s,e={})=>{if(!R.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(t).toLowerCase();this.config.redirects[o]=s;const{trackOriginalSource:l=!0}=e,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&W(this.config.wildcardRedirectsTree,o)};getRedirect=t=>{const s=h(t).toLowerCase(),e=q(s,this.config.redirects,this.config.wildcardRedirectsTree);if(!e)return null;if(S(e.to)){const a=h(e.to).toLowerCase();if(!a.endsWith("*")&&x(a,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:e.to,type:e.type}};createSharedData=async(t,s,e)=>{if(e&&this.#t[t]===e)return t;const a=JSON.stringify(s),r=e??k(a);return this.#t[t]===r||(this.#t[t]=r,await B(t,a,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,s,e)=>{const a=L(t),r=this.routesSharedData.get(a)||{};r[s]=e,this.routesSharedData.set(a,r),u.verbose(`Adding shared data to ${t}, ${s}, ${e}`)};getRouteSharedDataByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=t=>{const s=this.getGlobalConfig(m)||{},e=this.routesPartials.get(t);if(!e||e.length===0)return{};const a=this.getGlobalConfig(z)||{},r=new Set(e),o=Array.from(e);for(let i=0;i<o.length;i++){const n=o[i],c=a[n]?.partials??[];for(const d of c)r.has(d)||(r.add(d),o.push(d))}const l={};for(const i of r)s[i]&&(l[i]=s[i]);return l};addRoute=t=>{const e={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:e}),u.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,s,e)=>{const a=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(r=>({code:r,name:r}));for(const r of a){const o=C(t,g,r.code,a);this.addRouteSharedData(o,s,e)}};addApiRoute=t=>{this.apiRoutes.push(t),u.verbose("Created API route %s",t.slug)};addMcpTools=(t,s)=>{for(const e of s)this.mcpToolHandlers.set(e.name,{...e,importPath:t}),u.verbose("Created MCP tool %s",e.name)};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());addMiddleware=t=>{this.middleware.push(t),u.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(t,s={})=>{const{followRedirect:e=!0}=s,a=this.getRedirect(t);return e&&a?this.routesBySlug.get(h(a.to)):this.routesBySlug.get(t)};hasRouteOrRedirectBySlug=t=>{if(this.routesBySlug.has(t))return!0;const s=this.getRedirect(t);if(!s)return!1;if(!S(s.to))return!0;const e=h(s.to);return this.routesBySlug.has(e)};getRoutesByTemplateId=t=>this.newRoutes.filter(s=>s.templateId===t);getAllRoutesForLocale=(t=g)=>{const s=Array.from(this.routesBySlug.values()),e=t.toLowerCase();return s.filter(a=>t===g?!K(a.fsPath):a.slug.startsWith(`/${e}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,s)=>(this.templates.set(t,s),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,s)=>(this.apiRoutesRequestHandlers.set(t,s),t);registerServerPropsGetter=(t,s)=>(this.serverPropsGetters.set(t,s),t);registerPagePropsGetter=(t,s)=>{this.pagePropsGetters.set(t,s)};async writeRouteStaticData(t,s){const e=await this.resolveRouteStaticData(t,s,!1);e&&V(t.slug,e,this.outdir)}async resolveRouteStaticData(t,s,e){if(this.serverMode)return N(t.slug,this.outdir);const a={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[t.slug]},resource:f})},r=await t.getStaticData?.(t,a)||{},o=new Set(this.routesDynamicComponents.get(t.slug)),l=this.routesSharedData.get(t.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(t.slug,p,p))}const i=this.getGlobalConfig("seo"),n=r?.frontmatter||{};return{...r,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...r.props,dynamicMarkdocComponents:Array.from(o),metadata:{...r?.props?.metadata,...t.metadata},seo:{title:T,...i,...r.props?.seo},compilationErrors:this.compilationErrors},lastModified:e||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,s){if(!t?.length)return;const e=typeof t[0]=="string"?t.join(""):I(t);e&&(s==="head"?this.ssr.headTags.push(e):s==="preBody"?this.ssr.preBodyTags.push(e):this.ssr.postBodyTags.push(e))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[e,a]of Object.entries(v))switch(a){case"map":const r=Array.from(this[e].entries());t.push([e,r]);break;case"object":e==="config"&&t.push([e,await this.getConfigWithEnvPlaceholders()]),t.push([e,this[e]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(t);return s[E]=G.PLAN_GATES,s}static fromJson(t,s){const e=new P(s);for(const[r,o]of Object.entries(v))switch(o){case"map":e[r]=new Map(t[r]);break;case"object":if(r==="config"){e.setGlobalConfig(t[r]);break}e[r]=t[r];break;default:throw new Error("Invalid format")}e.config[m]=Z(e.config[m]||{});const a=t[E];return a&&_("PLAN_GATES",a),e}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:e}=this.replacedEnvVars[s],a=s.split(":"),r=a.pop(),{error:o,value:l}=y(t,a);if(o||!O(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[r]=e}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(e=>!Y.includes(e));if(t.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(s)}}function Z(b){return M(b,t=>A.Ast.fromJSON(JSON.stringify(t)))}export{m as MARKDOC_PARTIALS_DATA_KEY,z as MARKDOC_PARTIALS_DEPS_KEY,P as Store,Tt as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import A from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as T}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as O}from"../utils/guards/is-object.js";import{mapObject as M}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as L}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as h}from"../utils/path/normalize-route-slug.js";import{isLocalLink as S}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as u}from"./tools/notifiers/logger.js";import{sha1 as k}from"./utils/crypto/sha1.js";import{envConfig as _,setEnv as G}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as I}from"./ssr/render.js";import{readStaticData as N,writeStaticData as V}from"./utils/static-data.js";import{parseAndResolveMarkdoc as j}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as H}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as R}from"./entitlements/entitlements-provider.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as U}from"./utils/globs.js";import{replaceEnvVariablesDeep as J}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as q}from"./utils/redirects/find-redirect.js";import{followRedirectChain as x}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as W}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const v={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map"},m="markdown/partials",z="markdown/partials-deps",E="PLAN_GATES",Y=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],Ct="userDefinedApiFunctions";class P{routesBySlug=new Map;replacedEnvVars={};unsetEnvVars=new Set;lifecycleContext;newRoutes=[];#t={};routesByFsPath=new Map;apiRoutes=[];middleware=[];routesSharedData=new Map;sharedDataDeps=new Map;sharedDataMarkdocComponents=new Map;routesDynamicComponents=new Map;routesPartials=new Map;ssr={preBodyTags:[],postBodyTags:[],headTags:[]};searchFacets=new Map;searchEngine;templates=new Map;browserPlugins=new Set;apiRoutesRequestHandlers=new Map;mcpToolHandlers=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#r;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#a;userCodeReady;#o=Promise.resolve();#i;#n=Promise.resolve();#c;#e=new Map;constructor({outdir:t,contentDir:s,serverMode:e=!1,serverOutDir:a}){this.#r=s,this.outdir=t,this.serverMode=e,this.serverOutDir=a,this.userCodeReady=new Promise(r=>{this.#a=r})}on(t,s){const e=this.listeners.get(t);e?e.add(s):this.listeners.set(t,new Set([s]))}queueEvent=(t,s,...e)=>{this.#e.set(t+String(s),[t,s,...e])};runListeners=(t,s,...e)=>{for(const a of this.listeners.get(t)||new Set)s?a(s,...e):a(...e)};startPluginsRun(){this.clear(),this.#o=new Promise(t=>{this.#i=t})}waitForPluginsLifecycle(){return Promise.all([this.#o,this.#n])}finishPluginsRun(){this.#i?.();for(const t of this.#e.values())this.runListeners(...t);this.#e.clear()}startEsbuildRun(){this.#n=new Promise(t=>{this.#c=t})}finishEsbuildRun(){this.#c?.()}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#r}markUserCodeReady(){this.#a?.(!0)}async reloadMarkdocOptions(){await $("build.reload_markdoc_options",async()=>{const t=R.instance(),s=await H(this.serverOutDir),e=Object.fromEntries(Object.entries(s.tags).filter(([a])=>D[a]!=null?t.canAccessFeature(D[a]):!0));this.#s={...s,tags:e}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=t=>{const s=this.globalData,e={...this.globalData,...t};this.globalData=e,JSON.stringify(e)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,e)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:t,context:s,deps:e,resource:a})=>{const{data:{info:r,ast:o},compoundHash:l}=await j(t,this.markdocOptions,{actions:this,context:s},a);for(const i of r.sharedDataDeps||[]){for(const n of e?.routeSlugs||[])this.addRouteSharedData(n,i,i);for(const n of e?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(i),this.sharedDataDeps.set(n,c)}}for(const i of r.dynamicMarkdocComponents||[]){for(const n of e?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(i),this.routesDynamicComponents.set(n,c)}for(const n of e?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(i),this.sharedDataMarkdocComponents.set(n,c)}}if(e?.routeSlugs&&r.partials?.length)for(const i of e.routeSlugs){const n=this.routesPartials.get(i)||[];for(const c of r.partials)n.includes(c)||n.push(c);this.routesPartials.set(i,n)}return{info:r,ast:o,compoundHash:l}};async loadOpenApiDefinitions(t){return(await t.cache.load(".","load-oas-docs")).data}async loadAsyncApiDefinitions(t){return(await t.cache.load(".","asyncapi-docs")).data}setSearchEngine(t){this.searchEngine=t}setSearchFacets=t=>{this.searchFacets=t};setGlobalConfig=t=>{const s=Object.keys(t);for(const o of s)for(const l in this.replacedEnvVars)if(l===o||l.startsWith(`${o}:`)){const i=l.split(":"),{error:n,value:c}=y(t,i);(n||c!==this.replacedEnvVars[l].replaced)&&delete this.replacedEnvVars[l]}const{resolvedObj:e,unsetEnvVars:a,replacedValues:r}=J(t);for(const o of a)this.unsetEnvVars.add(o);Object.assign(this.replacedEnvVars,r),Object.assign(this.config,e)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,s,e={})=>{if(!R.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const o=h(t).toLowerCase();this.config.redirects[o]=s;const{trackOriginalSource:l=!0}=e,i=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(i)&&!i.includes(o)&&i.push(o),o.endsWith("*")&&W(this.config.wildcardRedirectsTree,o)};getRedirect=t=>{const s=h(t).toLowerCase(),e=q(s,this.config.redirects,this.config.wildcardRedirectsTree);if(!e)return null;if(S(e.to)){const a=h(e.to).toLowerCase();if(!a.endsWith("*")&&x(a,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:e.to,type:e.type}};createSharedData=async(t,s,e)=>{if(e&&this.#t[t]===e)return t;const a=JSON.stringify(s),r=e??k(a);return this.#t[t]===r||(this.#t[t]=r,await B(t,a,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,s,e)=>{const a=L(t),r=this.routesSharedData.get(a)||{};r[s]=e,this.routesSharedData.set(a,r),u.verbose(`Adding shared data to ${t}, ${s}, ${e}`)};getRouteSharedDataByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=t=>{const s=this.getGlobalConfig(m)||{},e=this.routesPartials.get(t);if(!e||e.length===0)return{};const a=this.getGlobalConfig(z)||{},r=new Set(e),o=Array.from(e);for(let i=0;i<o.length;i++){const n=o[i],c=a[n]?.partials??[];for(const d of c)r.has(d)||(r.add(d),o.push(d))}const l={};for(const i of r)s[i]&&(l[i]=s[i]);return l};addRoute=t=>{const e={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:e}),u.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,s,e)=>{const a=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(r=>({code:r,name:r}));for(const r of a){const o=C(t,g,r.code,a);this.addRouteSharedData(o,s,e)}};addApiRoute=t=>{this.apiRoutes.push(t),u.verbose("Created API route %s",t.slug)};addMcpTools=(t,s)=>{for(const e of s)this.mcpToolHandlers.set(e.name,{...e,importPath:t}),u.verbose("Created MCP tool %s",e.name)};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());addMiddleware=t=>{this.middleware.push(t),u.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const s=this.routesByFsPath.get(t);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(t,s={})=>{const{followRedirect:e=!0}=s,a=this.getRedirect(t);return e&&a?this.routesBySlug.get(h(a.to)):this.routesBySlug.get(t)};hasRouteOrRedirectBySlug=t=>{if(this.routesBySlug.has(t))return!0;const s=this.getRedirect(t);if(!s)return!1;if(!S(s.to))return!0;const e=h(s.to);return this.routesBySlug.has(e)};getRoutesByTemplateId=t=>this.newRoutes.filter(s=>s.templateId===t);getAllRoutesForLocale=(t=g)=>{const s=Array.from(this.routesBySlug.values()),e=t.toLowerCase();return s.filter(a=>t===g?!K(a.fsPath):a.slug.startsWith(`/${e}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=t=>this.templates.get(t);getRequestHandler=t=>this.apiRoutesRequestHandlers.get(t);createTemplate=(t,s)=>(this.templates.set(t,s),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,s)=>(this.apiRoutesRequestHandlers.set(t,s),t);registerServerPropsGetter=(t,s)=>(this.serverPropsGetters.set(t,s),t);registerPagePropsGetter=(t,s)=>{this.pagePropsGetters.set(t,s)};async writeRouteStaticData(t,s){const e=await this.resolveRouteStaticData(t,s,!1);e&&V(t.slug,e,this.outdir)}async resolveRouteStaticData(t,s,e){if(this.serverMode)return N(t.slug,this.outdir);const a={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[t.slug]},resource:f})},r=await t.getStaticData?.(t,a)||{},o=new Set(this.routesDynamicComponents.get(t.slug)),l=this.routesSharedData.get(t.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>o.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(t.slug,p,p))}const i=this.getGlobalConfig("seo"),n=r?.frontmatter||{};return{...r,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...r.props,dynamicMarkdocComponents:Array.from(o),metadata:{...r?.props?.metadata,...t.metadata},seo:{title:T,...i,...r.props?.seo},compilationErrors:this.compilationErrors},lastModified:e||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,s){if(!t?.length)return;const e=typeof t[0]=="string"?t.join(""):I(t);e&&(s==="head"?this.ssr.headTags.push(e):s==="preBody"?this.ssr.preBodyTags.push(e):this.ssr.postBodyTags.push(e))}clear=()=>{this.routesByFsPath.clear(),this.templates.clear(),this.newRoutes=[],this.routesBySlug.clear(),this.apiRoutes=[],this.middleware=[],this.routesSharedData.clear(),this.sharedDataDeps.clear(),this.sharedDataMarkdocComponents.clear(),this.routesDynamicComponents.clear(),this.routesPartials.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const t=[];for(const[e,a]of Object.entries(v))switch(a){case"map":const r=Array.from(this[e].entries());t.push([e,r]);break;case"object":e==="config"&&t.push([e,await this.getConfigWithEnvPlaceholders()]),t.push([e,this[e]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(t);return s[E]=_.PLAN_GATES,s}static fromJson(t,s){const e=new P(s);for(const[r,o]of Object.entries(v))switch(o){case"map":e[r]=new Map(t[r]);break;case"object":if(r==="config"){e.setGlobalConfig(t[r]);break}e[r]=t[r];break;default:throw new Error("Invalid format")}e.config[m]=Z(e.config[m]||{});const a=t[E];return a&&G("PLAN_GATES",a),e}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:e}=this.replacedEnvVars[s],a=s.split(":"),r=a.pop(),{error:o,value:l}=y(t,a);if(o||!O(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[r]=e}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(e=>!Y.includes(e));if(t.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(s)}}function Z(b){return M(b,t=>A.Ast.fromJSON(JSON.stringify(t)))}export{m as MARKDOC_PARTIALS_DATA_KEY,z as MARKDOC_PARTIALS_DEPS_KEY,P as Store,Ct as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -1 +1 @@
1
- import{AsyncApiRealmAPI as o}from"@redocly/realm-asyncapi-sdk";import{envConfig as e}from"../config/env-config.js";import{PACKAGE_NAME as t}from"../../config/product-gates.js";import{OTEL_TRACES_DEV_URL as i,TELEMETRY_ENABLED as s}from"../constants/common.js";class l extends o.Telemetry{constructor(){super(),this.updateCloudEventData(()=>({organizationId:e.ORGANIZATION_ID||"",organizationSlug:e.ORGANIZATION_SLUG||"",projectId:e.PROJECT_ID||"",projectSlug:e.PROJECT_SLUG||"",origin:"realmApi",actor:{id:"Anonymous",object:"user",uri:""},source:"server",env:e.redoclyEnv}))}initialize(r=!1){this.init({otel:{serviceName:"realm-server",serviceVersion:`${t}@${e.REDOCLY_PORTAL_VERSION||""}`,collectorTraceUrl:r?i:e.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",isProd:e.isProductionEnv,version:"1.0",tracerName:"server-telemetry",delayMillis:100},disabled:r?e.TELEMETRY_DEV_DEBUG!=="true":!s})}}const A=new l;export{A as telemetry};
1
+ import{AsyncApiRealmAPI as o}from"@redocly/realm-asyncapi-sdk";import{envConfig as e}from"../config/env-config.js";import{PACKAGE_NAME as t}from"../../config/product-gates.js";import{OTEL_TRACES_DEV_URL as i,TELEMETRY_ENABLED as s}from"../constants/common.js";class E extends o.Telemetry{constructor(){super(),this.updateCloudEventData(()=>({organizationId:e.ORGANIZATION_ID||"",organizationSlug:e.ORGANIZATION_SLUG||"",projectId:e.PROJECT_ID||"",projectSlug:e.PROJECT_SLUG||"",origin:"realmApi",actor:{id:"Anonymous",object:"user",uri:""},source:"server",env:e.REDOCLY_ENV}))}initialize(r=!1){this.init({otel:{serviceName:"realm-server",serviceVersion:`${t}@${e.REDOCLY_PORTAL_VERSION||""}`,collectorTraceUrl:r?i:e.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces",isProd:e.isProductionEnv,version:"1.0",tracerName:"server-telemetry",delayMillis:100},disabled:r?!e.TELEMETRY_DEV_DEBUG:!s})}}const A=new E;export{A as telemetry};
@@ -1,3 +1,3 @@
1
- import*as O from"node:path";import{envConfig as S}from"../../config/env-config.js";import{maskEmail as E}from"./helpers/privacy/mask-email.js";import{maskSubject as T}from"./helpers/privacy/mask-subject.js";import{removePii as C}from"./helpers/privacy/remove-pii.js";import{removePiiFromUrl as $}from"./helpers/privacy/remove-pii-from-url.js";import{red as x,green as A,bold as j,blue as p,gray as i,yellow as P,cyan as w}from"./helpers/colors.js";var n;(function(e){e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.SUCCESS="SUCCESS",e.VERBOSE="VERBOSE",e.HTTP="HTTP"})(n||(n={}));const b={[n.VERBOSE]:0,[n.HTTP]:1,[n.INFO]:2,[n.SUCCESS]:2,[n.WARN]:3,[n.ERROR]:4};function _(e,s){return b[e]>=b[s]}function z(e){if(!e)return;const s=e.toUpperCase();if(s in n)return s}const F={[n.INFO]:p,[n.SUCCESS]:A,[n.WARN]:P,[n.ERROR]:x,[n.HTTP]:w,[n.VERBOSE]:i},I={"%ap":e=>p(O.resolve(e)),"%rp":e=>p(O.relative(process.cwd(),e)),"%s":e=>e?.toString(),"%c":e=>p(e)},v={format(e){switch(S.logFormat){case"JSON":return U(e);default:return H(e)}},interpolate(e,...s){const a=Object.keys(I).map(t=>`(${t})`).join("|"),m=new RegExp(a,"g");let o,u=e;for(;(o=m.exec(e))!==null;){o.index===m.lastIndex&&m.lastIndex++;const t=s.shift();if(t===void 0)break;const r=o[0];u=u.replace(r,I[r](t))}return u}};var G=v;const H=e=>{const{level:s,message:a,duration:m,context:o}=e,u=S.isRuntimeMode,t=[F[s](j(`[${s.toLowerCase()}]`))];if(u&&t.push(i(`time="${N()}"`)),o){const{email:r,ipAddress:f,subject:l,method:d,pathname:c,statusCode:R,teams:h,apiFunction:g}=o;g&&t.push(p(`fn="${g}"`)),R&&t.push(y(R)),e.level===n.HTTP&&(d&&t.push(i(`method="${d}"`)),c&&t.push(i(`path="${$(c)}"`))),f&&t.push(i(`ip="${f}"`)),r&&t.push(i(`email="${E(r)}"`)),l&&t.push(i(`sub="${T(l)}"`)),h?.length&&t.push(i(`teams="${h.join(", ")}"`))}if(a){const r=u?`msg="${String(C(a)).replaceAll?.('"','\\"')}"`:String(a);t.push(r)}return e.level===n.HTTP&&o?.userAgent&&t.push(i(`agent="${o.userAgent}"`)),m&&t.push(M(m)),t.join(" ")+`
2
- `},U=({context:e,message:s,...a})=>{const{method:m,pathname:o,statusCode:u,userAgent:t,subject:r,email:f,teams:l,apiFunction:d}=e||{},c={...a,email:f&&E(f),subject:r&&T(r),teams:l,apiFunction:d,...a.level===n.HTTP?{method:m,pathname:String($(o)),statusCode:u,userAgent:t}:{message:String(C(s))}};return S.isRuntimeMode&&(c.time=N()),JSON.stringify(c,["time","level","scope","message","duration","method","pathname","statusCode","userAgent","subject","ipAddress","email","apiFunction"])+`
3
- `},y=e=>(e%500<100?x:e%400<100?P:A)(`status="${e}"`),N=()=>{let e=new Date().getTimezoneOffset()*6e4;return new Date(Date.now()-e).toISOString().slice(0,-1)},M=e=>i(`dur="${Math.round(e)}ms"`);export{n as LogLevel,G as default,z as parseLogLevel,_ as shouldLog};
1
+ import*as g from"node:path";import{envConfig as R}from"../../config/env-config.js";import{maskEmail as E}from"./helpers/privacy/mask-email.js";import{maskSubject as T}from"./helpers/privacy/mask-subject.js";import{removePii as C}from"./helpers/privacy/remove-pii.js";import{removePiiFromUrl as $}from"./helpers/privacy/remove-pii-from-url.js";import{red as x,green as A,bold as j,blue as p,gray as i,yellow as P,cyan as w}from"./helpers/colors.js";var n;(function(e){e.INFO="INFO",e.WARN="WARN",e.ERROR="ERROR",e.SUCCESS="SUCCESS",e.VERBOSE="VERBOSE",e.HTTP="HTTP"})(n||(n={}));const b={[n.VERBOSE]:0,[n.HTTP]:1,[n.INFO]:2,[n.SUCCESS]:2,[n.WARN]:3,[n.ERROR]:4};function W(e,s){return b[e]>=b[s]}function L(e){if(!e)return;const s=e.toUpperCase();if(s in n)return s}const F={[n.INFO]:p,[n.SUCCESS]:A,[n.WARN]:P,[n.ERROR]:x,[n.HTTP]:w,[n.VERBOSE]:i},I={"%ap":e=>p(g.resolve(e)),"%rp":e=>p(g.relative(process.cwd(),e)),"%s":e=>e?.toString(),"%c":e=>p(e)},v={format(e){switch(R.REDOCLY_LOG_FORMAT){case"JSON":return M(e);default:return H(e)}},interpolate(e,...s){const a=Object.keys(I).map(t=>`(${t})`).join("|"),m=new RegExp(a,"g");let o,u=e;for(;(o=m.exec(e))!==null;){o.index===m.lastIndex&&m.lastIndex++;const t=s.shift();if(t===void 0)break;const r=o[0];u=u.replace(r,I[r](t))}return u}};var z=v;const H=e=>{const{level:s,message:a,duration:m,context:o}=e,u=R.isRuntimeMode,t=[F[s](j(`[${s.toLowerCase()}]`))];if(u&&t.push(i(`time="${N()}"`)),o){const{email:r,ipAddress:f,subject:l,method:d,pathname:c,statusCode:S,teams:h,apiFunction:O}=o;O&&t.push(p(`fn="${O}"`)),S&&t.push(U(S)),e.level===n.HTTP&&(d&&t.push(i(`method="${d}"`)),c&&t.push(i(`path="${$(c)}"`))),f&&t.push(i(`ip="${f}"`)),r&&t.push(i(`email="${E(r)}"`)),l&&t.push(i(`sub="${T(l)}"`)),h?.length&&t.push(i(`teams="${h.join(", ")}"`))}if(a){const r=u?`msg="${String(C(a)).replaceAll?.('"','\\"')}"`:String(a);t.push(r)}return e.level===n.HTTP&&o?.userAgent&&t.push(i(`agent="${o.userAgent}"`)),m&&t.push(y(m)),t.join(" ")+`
2
+ `},M=({context:e,message:s,...a})=>{const{method:m,pathname:o,statusCode:u,userAgent:t,subject:r,email:f,teams:l,apiFunction:d}=e||{},c={...a,email:f&&E(f),subject:r&&T(r),teams:l,apiFunction:d,...a.level===n.HTTP?{method:m,pathname:String($(o)),statusCode:u,userAgent:t}:{message:String(C(s))}};return R.isRuntimeMode&&(c.time=N()),JSON.stringify(c,["time","level","scope","message","duration","method","pathname","statusCode","userAgent","subject","ipAddress","email","apiFunction"])+`
3
+ `},U=e=>(e%500<100?x:e%400<100?P:A)(`status="${e}"`),N=()=>{let e=new Date().getTimezoneOffset()*6e4;return new Date(Date.now()-e).toISOString().slice(0,-1)},y=e=>i(`dur="${Math.round(e)}ms"`);export{n as LogLevel,z as default,L as parseLogLevel,W as shouldLog};
@@ -1 +1 @@
1
- import{createColors as e}from"colorette";import{envConfig as l}from"../../../config/env-config.js";const r=l.logFormat!=="JSON",{red:s,green:t,bold:c,blue:n,gray:a,yellow:g,cyan:m}=e({useColor:r}),d=o=>typeof o=="string"?o.replace(/\x1B[[(?);]{0,2}(;?\d)*./g,""):o;export{n as blue,c as bold,r as colorsAreEnabled,m as cyan,a as gray,t as green,s as red,d as stripColors,g as yellow};
1
+ import{createColors as e}from"colorette";import{envConfig as l}from"../../../config/env-config.js";const r=l.REDOCLY_LOG_FORMAT!=="JSON",{red:s,green:t,bold:c,blue:n,gray:a,yellow:g,cyan:C}=e({useColor:r}),d=o=>typeof o=="string"?o.replace(/\x1B[[(?);]{0,2}(;?\d)*./g,""):o;export{n as blue,c as bold,r as colorsAreEnabled,C as cyan,a as gray,t as green,s as red,d as stripColors,g as yellow};
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Env vars that are set as the strings `"true"` or `"false"`, parsed to booleans.
4
+ * Any other value fails validation.
5
+ */
6
+ export declare function envBooleanStringOptional(): z.ZodEffects<z.ZodOptional<z.ZodEnum<["true", "false"]>>, boolean | undefined, "true" | "false" | undefined>;
7
+ export declare function envBooleanStringDefaultFalse(): z.ZodEffects<z.ZodDefault<z.ZodEnum<["true", "false"]>>, boolean, "true" | "false" | undefined>;
8
+ /**
9
+ * Like {@link envBooleanStringOptional}, but also accepts `"1"` as true (common for `CI`).
10
+ */
11
+ export declare function envCiBooleanOptional(): z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"true">, z.ZodLiteral<"false">, z.ZodLiteral<"1">]>>, boolean | undefined, "1" | "true" | "false" | undefined>;
12
+ //# sourceMappingURL=env-boolean-string.d.ts.map
@@ -0,0 +1 @@
1
+ import{z as n}from"zod";const t=n.enum(["true","false"]);function o(){return t.optional().transform(e=>e===void 0?void 0:e==="true")}function a(){return t.default("false").transform(e=>e==="true")}function l(){return n.union([n.literal("true"),n.literal("false"),n.literal("1")]).optional().transform(e=>e===void 0?void 0:e==="true"||e==="1")}export{a as envBooleanStringDefaultFalse,o as envBooleanStringOptional,l as envCiBooleanOptional};
@@ -1 +1 @@
1
- import*as n from"dotenv";import*as a from"path";import{simpleGit as s}from"simple-git";import{envConfig as o}from"../../config/env-config.js";import{sanitizeBranchName as v}from"../../utils/envs/sanitize-branch-name.js";async function p(e){try{return(await s(e??process.cwd()).revparse(["--abbrev-ref","HEAD"])).trim()}catch{return""}}async function h(e){n.config({path:a.resolve(e??"",".env")});const t=o.PUBLIC_REDOCLY_BRANCH_NAME||await p(e);if(t){const c=v(t);n.config({path:a.resolve(e??"",`.env.branch.${c}`),override:!0})}const i=o.redoclyEnv;let r;switch(i){case"production":r=".env.production";break;case"preview":r=".env.preview";break;case"development":default:r=".env.development";break}n.config({path:a.resolve(e??"",r),override:!0})}export{h as loadEnvVariables};
1
+ import*as n from"dotenv";import*as a from"path";import{simpleGit as v}from"simple-git";import{envConfig as i,reloadEnvConfig as o}from"../../config/env-config.js";import{sanitizeBranchName as p}from"../../utils/envs/sanitize-branch-name.js";async function m(e){try{return(await v(e??process.cwd()).revparse(["--abbrev-ref","HEAD"])).trim()}catch{return""}}async function d(e){n.config({path:a.resolve(e??"",".env")}),o();const t=i.PUBLIC_REDOCLY_BRANCH_NAME||await m(e);if(t){const s=p(t);n.config({path:a.resolve(e??"",`.env.branch.${s}`),override:!0}),o()}const c=i.REDOCLY_ENV;let r;switch(c){case"production":r=".env.production";break;case"preview":r=".env.preview";break;case"development":default:r=".env.development";break}n.config({path:a.resolve(e??"",r),override:!0}),o()}export{d as loadEnvVariables};
@@ -1 +1 @@
1
- import{envConfig as t}from"../config/env-config.js";function e(){return t.NEW_CATALOG_ENABLED==="true"}export{e as isCatalogEntitiesEnabled};
1
+ import{envConfig as n}from"../config/env-config.js";function e(){return n.NEW_CATALOG_ENABLED??!1}export{e as isCatalogEntitiesEnabled};
@@ -1 +1 @@
1
- import{envConfig as e}from"../config/env-config.js";import{isCatalogEntitiesEnabled as o}from"./is-catalog-entities-enabled.js";function s(r){return o()&&e.NEW_SCORECARDS_ENABLED==="true"&&Array.isArray(r.scorecards)&&r.scorecards.length>0}export{s as isScorecardsEnabled};
1
+ import{envConfig as e}from"../config/env-config.js";import{isCatalogEntitiesEnabled as a}from"./is-catalog-entities-enabled.js";function t(r){return a()&&(e.NEW_SCORECARDS_ENABLED??!1)&&Array.isArray(r.scorecards)&&r.scorecards.length>0}export{t as isScorecardsEnabled};
@@ -1 +1 @@
1
- import*as i from"path";import{cliCommandNames as r}from"../../constants/common.js";import{PUBLIC_STATIC_FOLDER as t}from"../constants/common.js";import{logger as n}from"../tools/notifiers/logger.js";import{blue as a,gray as c}from"../tools/notifiers/helpers/colors.js";import{loadEnvVariables as f}from"./envs/load-env-variables.js";import{copyFolderRecursiveSync as l}from"./fs.js";import{validateInstalledVersion as s}from"./validate-installed-version.js";import{PACKAGE_NAME as E}from"../../config/product-gates.js";import{PORTAL_VERSION as P}from"../version.js";function u(e){return e?"true":"false"}function v(e){e["log-level"]&&(process.env.REDOCLY_LOG_LEVEL=String(e["log-level"])),process.env.INSPECT_MODE="inspect"in e?u(e.inspect):"false",e.pathPrefix&&(process.env.REDOCLY_PREFIX_PATHS=e.pathPrefix)}function L({contentDir:e,outdir:o}){l(i.join(e,t),i.join(o,t))}async function h(e,o,m){await f(o["project-dir"]);const p=e===r.DEVELOP?" Previewing with":"Building with";switch(n.logInFooter("product",`${p} ${a(`${E}@${P}`)}`),n.logInFooter("server",` \u{1F310} Preview URL: ${c("server starting...")}`),e){case r.DEVELOP:case r.BUILD:case r.PREPARE:v(o);break;default:break}await s(),L(m)}export{h as beforeCommand};
1
+ import*as t from"path";import{cliCommandNames as r}from"../../constants/common.js";import{PUBLIC_STATIC_FOLDER as i}from"../constants/common.js";import{logger as n}from"../tools/notifiers/logger.js";import{blue as f,gray as l}from"../tools/notifiers/helpers/colors.js";import{loadEnvVariables as p}from"./envs/load-env-variables.js";import{copyFolderRecursiveSync as c}from"./fs.js";import{validateInstalledVersion as s}from"./validate-installed-version.js";import{PACKAGE_NAME as E}from"../../config/product-gates.js";import{PORTAL_VERSION as P}from"../version.js";import{setEnv as u}from"../config/env-config.js";function L(o){return o?"true":"false"}function d(o){const e={};o["log-level"]&&(e.REDOCLY_LOG_LEVEL=String(o["log-level"])),e.INSPECT_MODE="inspect"in o?L(o.inspect):"false",o.pathPrefix&&(e.REDOCLY_PREFIX_PATHS=o.pathPrefix),u(e)}function v({contentDir:o,outdir:e}){c(t.join(o,i),t.join(e,i))}async function S(o,e,m){await p(e["project-dir"]);const a=o===r.DEVELOP?" Previewing with":"Building with";switch(n.logInFooter("product",`${a} ${f(`${E}@${P}`)}`),n.logInFooter("server",` \u{1F310} Preview URL: ${l("server starting...")}`),o){case r.DEVELOP:case r.BUILD:case r.PREPARE:d(e);break;default:break}await s(),v(m)}export{S as beforeCommand};
@@ -1 +1 @@
1
- import{createRequire as o}from"module";import{envConfig as r}from"./config/env-config.js";const i=r.REDOCLY_INTERNAL_DEV==="true"?"local":o(import.meta.url)("../../package.json").version;export{i as PORTAL_VERSION};
1
+ import{createRequire as o}from"module";import{envConfig as r}from"./config/env-config.js";const i=r.REDOCLY_INTERNAL_DEV?"local":o(import.meta.url)("../../package.json").version;export{i as PORTAL_VERSION};
@@ -1 +1 @@
1
- import{telemetryTraceStep as a}from"../../../telemetry/helpers/trace-step.js";import{CATALOG_ENTITY_KEY as y}from"../../../../constants/common.js";import{CatalogEntitiesService as g}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";function l(n){return async t=>a("catalog_entities.bff.revisions.get_entity_revisions",async e=>{const o=await g.getInstance({baseDbDir:n.serverOutDir}),i=t.req.param(y);if(!i)return e?.error(new Error("Missing entityKey")),t.json({message:"Missing entityKey"},400);e?.setAttribute("pathParams",JSON.stringify({entityKey:i}));const r=t.req.query("version")??null;e?.setAttribute("queryParams",JSON.stringify({version:r}));const s=await o.listEntityRevisions(i,r);return e?.setAttribute("totalRevisions",s.length),t.json({items:s})})}export{l as bffCatalogRevisionsHandler};
1
+ import{telemetryTraceStep as y}from"../../../telemetry/helpers/trace-step.js";import{parseFilterQuery as u}from"../../../providers/database/pagination/filter.js";import{extractEqualFilterClauseValue as f}from"../../../providers/database/pagination/utils/extract-equal-filter-clause-value.js";import{CatalogEntitiesService as c}from"../../../plugins/catalog-entities/database/catalog-entities-service.js";function p(o){return async e=>y("catalog_entities.bff.revisions.get_entity_revisions",async t=>{const l=await c.getInstance({baseDbDir:o.serverOutDir}),r=e.req.query("filter");let i;try{i=u(typeof r=="string"?r:"",["catalogEntityKey"])}catch{return t?.error(new Error("Invalid filter")),e.json({message:"Invalid filter"},400)}const n=f(i,"catalogEntityKey");if(!n)return t?.error(new Error("Missing catalogEntityKey in filter")),e.json({message:"The filter query must include a non-empty catalogEntityKey clause, for example filter=catalogEntityKey:my-entity."},400);const s=e.req.query("version")??null;t?.setAttribute("queryParams",JSON.stringify({version:s,filter:r}));const a=await l.listEntityRevisions(n,s);return t?.setAttribute("totalRevisions",a.length),e.json({items:a})})}export{p as bffCatalogRevisionsHandler};
@@ -1 +1 @@
1
- import l from"path";import{REDOCLY_ROUTE_RBAC as y,REDOCLY_TEAMS_RBAC as I}from"@redocly/config";import{withoutPathPrefix as G,withPathPrefix as Y}from"@redocly/theme/core/utils";import{CACHE_CONTROL_NO_CACHE_HEADER_VALUE as S,DEFAULT_IMMUTABLE_CACHE_MAX_AGE as $}from"../../constants/common.js";import{removeTrailingSlash as k}from"../../../utils/url/remove-trailing-slash.js";import{findInIterable as N}from"../../../utils/collection/find-in-iterable.js";import{sanitizeRedirectPathname as W}from"../../../utils/url/sanitize-redirect-pathname.js";import{envConfig as X}from"../../config/env-config.js";import{sanitizePath as j}from"../../../utils/path/sanitize-path.js";import{normalizeRouteSlug as V}from"../../../utils/path/normalize-route-slug.js";import{isPathInFolder as Z}from"../../../utils/path/is-path-in-folder.js";import{getLlmsTxtMdPathBySlug as J}from"../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{removeLeadingSlash as T}from"../../../utils/url/remove-leading-slash.js";import{processRedirects as K}from"./helpers/process-redirects.js";import{renderPage as Q,getServerProps as x}from"../../ssr/index.js";import{canAccessAsset as ee,canAccessResource as U}from"../../utils/rbac.js";import{handleErrorPageRender as M,handleUnauthorized as b,handleUnauthorizedAsset as q}from"../utils.js";import{DEFAULT_MAX_AGE_FOR_MIME_TYPE as te,MIME_TYPES as ne}from"../mime-types.js";import{fileExistsAsync as v}from"../../utils/index.js";import{isAiAgentRequest as oe}from"../../utils/ai-agent-detection.js";import{getRedirectRoute as re}from"../utils/legacy-openapi-redirects.js";import{telemetry as ae}from"../../../cli/telemetry/index.js";import{telemetry as ie}from"../../telemetry/index.js";function qe(e,D,O){return async n=>{const A=n.get("logger"),a=n.req,i=new URL(a.url),r=G(j(decodeURIComponent(i.pathname))),R=l.parse(r).ext===".md",C=oe({accept:a.header("accept"),signatureAgent:a.header("signature-agent"),signature:a.header("signature"),signatureInput:a.header("signature-input"),userAgent:a.header("user-agent")}),m=V(r),o=(a.method==="GET"||a.method==="HEAD")&&!R?e.getRouteBySlug(m,{followRedirect:!1})||N(e.routesBySlug?.values(),t=>t.hasClientRoutes&&(r===t.slug||r.startsWith(t.slug+"/"))):void 0,E=e.getRedirect(m);if(E){const t=K({redirect:E,reqUrlSearch:i.search});return ie.sendRedirectMessage([{object:"redirect",from:m,templateId:t.type.toString()}]),n.newResponse(null,t.type,{Location:t.location})}const f=X.isProductionEnv?301:302;if(o?.metadata?.type==="openapi"){const t=re(i.pathname);if(t)return A.info("Legacy OpenAPI docs redirect from "+i.pathname),n.newResponse(null,f,{Location:encodeURI(t)});if(i.pathname.match(/[A-Z]/))return A.warn("Redirect to lowercase route to avoid 404 error"),n.newResponse(null,f,{Location:encodeURI(i.pathname.toLowerCase())})}if(r.endsWith("/")&&r!=="/"){const t=W(new URL(m||"/",n.req.url).pathname);return n.newResponse(null,f,{Location:encodeURI(Y((t==="/"?"/":k(t))+i.search))})}const u=o&&C?J(o.slug):void 0,w=u?await v(l.resolve(e.outdir,T(u))):!1,{isAuthenticated:d,teams:g,claims:{email:p}}=n.get("auth");if(o&&!U(o,{isAuthenticated:d,email:p,teams:g},e.config.access?.rbac,e.config.access?.requiresLogin))return d?M(n,e,{slug:o.slug,[I]:o[I],[y]:o[y]},403):b(n,e,o.slug);if(o&&(!C||!w)){const t=await D(o),c=await x(o,n,t,e),{html:H,statusCode:z}=await Q(o,c,n,e,ae);return n.html(H,z,{"Cache-Control":S})}const L=u&&w?u:r,F=T(L),s=l.resolve(e.outdir,F);if(!Z(s,e.outdir))return q(n);if(R){const t=r==="index.html.md"?"/":r.replace(/\.md$/,""),c=e.getRouteBySlug(t,{followRedirect:!1});if(c&&!U(c,{isAuthenticated:d,email:p,teams:g},e.config.access?.rbac,e.config.access?.requiresLogin))return b(n,e,r)}const P=e.getGlobalConfig("access");if(!ee(L,P?.rbac||{},P?.requiresLogin||!1,e.getGlobalConfig("directoryPaths"),{isAuthenticated:d,email:p,teams:g}))return q(n);const _=ne[l.extname(s)]||"text/plain",h=s.match(/assets\/.*\.[a-f0-9]{8,}\..+/)||s.match(/runtime\/chunks\/.*/)?$:te[_],B=h?{"Cache-Control":`public, max-age=${h}, immutable`,Expires:new Date(Date.now()+h*1e3).toUTCString()}:{"Cache-Control":S};if(await v(s)){const t=a.query("download")!=null,c=await O(s);return n.newResponse(c,200,{"Content-Type":_,"Access-Control-Allow-Origin":"*",...B,...t&&{"Content-Disposition":`attachment; filename="${l.basename(s)}"`}})}else return M(n,e,{slug:m},404)}}export{qe as dynamicRouteHandler};
1
+ import l from"path";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as T}from"@redocly/config";import{withoutPathPrefix as G,withPathPrefix as Y}from"@redocly/theme/core/utils";import{CACHE_CONTROL_NO_CACHE_HEADER_VALUE as I,DEFAULT_IMMUTABLE_CACHE_MAX_AGE as $}from"../../constants/common.js";import{removeTrailingSlash as k}from"../../../utils/url/remove-trailing-slash.js";import{findInIterable as N}from"../../../utils/collection/find-in-iterable.js";import{sanitizeRedirectPathname as V}from"../../../utils/url/sanitize-redirect-pathname.js";import{envConfig as W}from"../../config/env-config.js";import{sanitizePath as X}from"../../../utils/path/sanitize-path.js";import{normalizeRouteSlug as j}from"../../../utils/path/normalize-route-slug.js";import{isPathInFolder as Z}from"../../../utils/path/is-path-in-folder.js";import{getLlmsTxtMdPathBySlug as J}from"../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{removeLeadingSlash as S}from"../../../utils/url/remove-leading-slash.js";import{processRedirects as K}from"./helpers/process-redirects.js";import{renderPage as Q,getServerProps as x}from"../../ssr/index.js";import{canAccessAsset as ee,canAccessResource as U}from"../../utils/rbac.js";import{handleErrorPageRender as M,handleUnauthorized as b,handleUnauthorizedAsset as q}from"../utils.js";import{DEFAULT_MAX_AGE_FOR_MIME_TYPE as te,MIME_TYPES as ne}from"../mime-types.js";import{fileExistsAsync as v}from"../../utils/index.js";import{isAiAgentRequest as oe}from"../../utils/ai-agent-detection.js";import{getRedirectRoute as re}from"../utils/legacy-openapi-redirects.js";import{getContentTypeHeaderValue as ae}from"../utils/content-type.js";import{telemetry as ie}from"../../../cli/telemetry/index.js";import{telemetry as se}from"../../telemetry/index.js";function De(e,D,O){return async n=>{const A=n.get("logger"),a=n.req,i=new URL(a.url),r=G(X(decodeURIComponent(i.pathname))),R=l.parse(r).ext===".md",C=oe({accept:a.header("accept"),signatureAgent:a.header("signature-agent"),signature:a.header("signature"),signatureInput:a.header("signature-input"),userAgent:a.header("user-agent")}),m=j(r),o=(a.method==="GET"||a.method==="HEAD")&&!R?e.getRouteBySlug(m,{followRedirect:!1})||N(e.routesBySlug?.values(),t=>t.hasClientRoutes&&(r===t.slug||r.startsWith(t.slug+"/"))):void 0,E=e.getRedirect(m);if(E){const t=K({redirect:E,reqUrlSearch:i.search});return se.sendRedirectMessage([{object:"redirect",from:m,templateId:t.type.toString()}]),n.newResponse(null,t.type,{Location:t.location})}const f=W.isProductionEnv?301:302;if(o?.metadata?.type==="openapi"){const t=re(i.pathname);if(t)return A.info("Legacy OpenAPI docs redirect from "+i.pathname),n.newResponse(null,f,{Location:encodeURI(t)});if(i.pathname.match(/[A-Z]/))return A.warn("Redirect to lowercase route to avoid 404 error"),n.newResponse(null,f,{Location:encodeURI(i.pathname.toLowerCase())})}if(r.endsWith("/")&&r!=="/"){const t=V(new URL(m||"/",n.req.url).pathname);return n.newResponse(null,f,{Location:encodeURI(Y((t==="/"?"/":k(t))+i.search))})}const u=o&&C?J(o.slug):void 0,w=u?await v(l.resolve(e.outdir,S(u))):!1,{isAuthenticated:d,teams:g,claims:{email:p}}=n.get("auth");if(o&&!U(o,{isAuthenticated:d,email:p,teams:g},e.config.access?.rbac,e.config.access?.requiresLogin))return d?M(n,e,{slug:o.slug,[T]:o[T],[_]:o[_]},403):b(n,e,o.slug);if(o&&(!C||!w)){const t=await D(o),c=await x(o,n,t,e),{html:B,statusCode:z}=await Q(o,c,n,e,ie);return n.html(B,z,{"Cache-Control":I})}const L=u&&w?u:r,F=S(L),s=l.resolve(e.outdir,F);if(!Z(s,e.outdir))return q(n);if(R){const t=r==="index.html.md"?"/":r.replace(/\.md$/,""),c=e.getRouteBySlug(t,{followRedirect:!1});if(c&&!U(c,{isAuthenticated:d,email:p,teams:g},e.config.access?.rbac,e.config.access?.requiresLogin))return b(n,e,r)}const P=e.getGlobalConfig("access");if(!ee(L,P?.rbac||{},P?.requiresLogin||!1,e.getGlobalConfig("directoryPaths"),{isAuthenticated:d,email:p,teams:g}))return q(n);const y=ne[l.extname(s)]||"text/plain",h=s.match(/assets\/.*\.[a-f0-9]{8,}\..+/)||s.match(/runtime\/chunks\/.*/)?$:te[y],H=h?{"Cache-Control":`public, max-age=${h}, immutable`,Expires:new Date(Date.now()+h*1e3).toUTCString()}:{"Cache-Control":I};if(await v(s)){const t=a.query("download")!=null,c=await O(s);return n.newResponse(c,200,{"Content-Type":ae(y),"Access-Control-Allow-Origin":"*",...H,...t&&{"Content-Disposition":`attachment; filename="${l.basename(s)}"`}})}else return M(n,e,{slug:m},404)}}export{De as dynamicRouteHandler};
@@ -1 +1 @@
1
- import{FEEDBACK_API_URL as _}from"../../constants/common.js";import{MAX_CONTEXT_LENGTH as g,MAX_EMAIL_LENGTH as C,MAX_LANG_LENGTH as j,MAX_PATH_LENGTH as E,MAX_REASONS_COUNT as N}from"../../constants/feedback.js";import{mapObject as T}from"../../../utils/object/map-object.js";import{getClientIp as q}from"../utils/get-client-ip.js";import{canAccessResource as w}from"../../utils/rbac.js";function a(e,n){if(e!=null)return String(e).replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"").trim().slice(0,n)||void 0}function S(e){if(!e)return e;const n=["userAgent","firstName","lastName","auth_time","platform","id","email","ipAddress"];return T(e,(o,r)=>n.includes(r)?o:"*****")}function L({component:e,path:n,location:o,lang:r,score:u,max:s,reasons:i,comment:m,metadata:t,email:l}){const c=Array.isArray(i)?i.map(d=>a(String(d),g)).filter(d=>!!d).slice(0,N):void 0;return{feedbackComponent:e.toUpperCase(),path:a(n,E),location:a(o,g),lang:a(r,j),score:typeof u=="number"?u:void 0,maxScore:typeof s=="number"?s:void 0,reasons:c?.length?c:void 0,comment:a(m,g),email:a(l,C),metadata:S(t)}}async function R(e,n){return(await fetch(_,{method:"POST",body:JSON.stringify(L(e)),headers:n})).json()}function G(e){return async n=>{const o=n.get("logger"),r=await n.req.json(),u=n.req.header("user-agent"),s=q(n.req.raw),i=n.req.header("Sec-Ch-Ua-Platform"),m={...r.metadata,userAgent:u,ipAddress:s,platform:i?i.replace(/"/g,""):"unknown"};o.info("Feedback IP diagnostics",I(n,s??void 0));const t=[];(!r.path||r.path==="")&&t.push("`path` is required");const l=["sentiment","rating","comment","problem","mood","scale"];if(l.includes(r.component)||t.push(`\`component\` field should be one of ${l.join(", ")}.`),t.length)return n.json({errors:t},400);const{claims:c,isAuthenticated:d,teams:A}=n.get("auth"),k={isAuthenticated:d,email:c?.email,teams:A};if(Object.keys(e.config.access?.rbac||{}).length>0){const f=r.path,F=new URL(f).pathname,b=e.getRouteBySlug(F);if(!b)return n.json({errors:["Resource not found"]},404);if(!w(b,k,e.config.access?.rbac,e.config.access?.requiresLogin))return n.json({errors:["Forbidden: no permission to send feedback for resource"]},403)}const y={"Content-Type":"application/json"},h=c?.email||r?.email||m?.email;try{const f=await R({...r,email:h,metadata:{email:h,...m}},y);return n.json({message:"Thanks for your feedback",...f},200,{})}catch(f){return n.json({errors:["Failed to send feedback",f.message]},500)}}}function I(e,n){return{extractedIpAddress:n,xForwardedFor:p(e.req.header("x-forwarded-for")),xRealIp:p(e.req.header("x-real-ip")),trueClientIp:p(e.req.header("true-client-ip")),cfConnectingIp:p(e.req.header("cf-connecting-ip"))}}function p(e){if(e)return e.slice(0,256)}export{G as feedbackHandler,S as normalizeFeedbackMetadata};
1
+ import{FEEDBACK_API_URL as _}from"../../constants/common.js";import{MAX_CONTEXT_LENGTH as g,MAX_EMAIL_LENGTH as C,MAX_LANG_LENGTH as N,MAX_PATH_LENGTH as j,MAX_REASONS_COUNT as E}from"../../constants/feedback.js";import{mapObject as S}from"../../../utils/object/map-object.js";import{getClientIp as T}from"../utils/get-client-ip.js";import{canAccessResource as q}from"../../utils/rbac.js";function a(e,n){if(e!=null)return String(e).replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g,"").trim().slice(0,n)||void 0}function w(e){if(!e)return e;const n=["userAgent","firstName","lastName","auth_time","platform","id","email","ipAddress"];return S(e,(t,r)=>n.includes(r)?t:"*****")}function I({component:e,path:n,location:t,lang:r,score:u,max:i,reasons:s,comment:m,metadata:o,email:l}){const c=Array.isArray(s)?s.map(d=>a(String(d),g)).filter(d=>!!d).slice(0,E):void 0;return{feedbackComponent:e.toUpperCase(),path:a(n,j),location:a(t,g),lang:a(r,N),score:typeof u=="number"?u:void 0,maxScore:typeof i=="number"?i:void 0,reasons:c?.length?c:void 0,comment:a(m,g),email:a(l,C),metadata:w(o)}}async function L(e,n){return(await fetch(_,{method:"POST",body:JSON.stringify(I(e)),headers:n})).json()}function G(e){return async n=>{const t=n.get("logger"),r=await n.req.json(),u=n.req.header("user-agent"),i=T(n.req.raw),s=n.req.header("Sec-Ch-Ua-Platform"),m={...r.metadata,userAgent:u,ipAddress:i,platform:s?s.replace(/"/g,""):"unknown"};t.info(`Feedback IP diagnostics ${O(R(n,i??void 0))}`);const o=[];(!r.path||r.path==="")&&o.push("`path` is required");const l=["sentiment","rating","comment","problem","mood","scale"];if(l.includes(r.component)||o.push(`\`component\` field should be one of ${l.join(", ")}.`),o.length)return n.json({errors:o},400);const{claims:c,isAuthenticated:d,teams:A}=n.get("auth"),k={isAuthenticated:d,email:c?.email,teams:A};if(Object.keys(e.config.access?.rbac||{}).length>0){const f=r.path,F=new URL(f).pathname,b=e.getRouteBySlug(F);if(!b)return n.json({errors:["Resource not found"]},404);if(!q(b,k,e.config.access?.rbac,e.config.access?.requiresLogin))return n.json({errors:["Forbidden: no permission to send feedback for resource"]},403)}const y={"Content-Type":"application/json"},h=c?.email||r?.email||m?.email;try{const f=await L({...r,email:h,metadata:{email:h,...m}},y);return n.json({message:"Thanks for your feedback",...f},200,{})}catch(f){return n.json({errors:["Failed to send feedback",f.message]},500)}}}function R(e,n){return{extractedIpAddress:n,xForwardedFor:p(e.req.header("x-forwarded-for")),xRealIp:p(e.req.header("x-real-ip")),trueClientIp:p(e.req.header("true-client-ip")),cfConnectingIp:p(e.req.header("cf-connecting-ip"))}}function O(e){return JSON.stringify(e,(n,t)=>t===void 0?null:t)}function p(e){if(e)return e.slice(0,256)}export{G as feedbackHandler,w as normalizeFeedbackMetadata};
@@ -1 +1 @@
1
- import{serveStatic as C}from"hono/serve-static";import{withPathPrefix as e,withoutPathPrefix as H}from"@redocly/theme/core/utils";import{ServerRoutes as i}from"../../../constants/common.js";import{PUBLIC_STATIC_FOLDER as c}from"../../constants/common.js";import{envConfig as L}from"../../config/env-config.js";import{authMiddleware as S}from"../middleware/authMiddleware.js";import{ensureSearchData as g}from"../middleware/ensureSearchData.js";import{dynamicMiddleware as P}from"../middleware/dynamic-middleware/dynamic-middleware.js";import{installRoutes as I}from"../../plugins/dev-onboarding/api/routes/index.js";import{authorizeHandler as D,oidcCallbackHandler as h,logoutHandler as O,postLogoutHandler as M,idpLoginHandler as N,redoclyLoginCallbackHandler as v,samlCallbackHandler as B,redoclyTokenLoginHandler as w,inviteHandler as U}from"./auth.js";import{appDataHandler as G}from"./app-data.js";import{searchFacetsHandler as F,searchHandler as y}from"./search.js";import{dynamicRouteHandler as K}from"./dynamic-route.js";import{pageDataHandler as Y,sharedPageDataHandler as k}from"./page-data.js";import{pathPrefixRedirectHandler as b}from"./path-prefix-redirect.js";import{getRoutesByLineHandler as _,resolvePathHandler as E,resolvePathsHandler as V,resolveSlugHandler as T}from"./resolve-route.js";import{feedbackHandler as x}from"./feedback.js";import{loggerMiddleware as $}from"../middleware/loggerMiddleware.js";import{responseHeadersMiddleware as z}from"../middleware/responseHeadersMiddleware.js";import{idleTimeoutMiddleware as Z}from"../middleware/idleTimeoutMiddleware.js";import{otelTracesHandler as X}from"./otel/otel.js";import{healthCheckHandler as q}from"./health.js";import{askAiHandler as W}from"./ask-ai.js";import{semanticSearchHandler as j}from"./semantic-search.js";import{replayOauth2RedirectCallbackHandler as J}from"./replay-oauth2-redirect.js";import{corsProxyHandler as r}from"./cors-proxy.js";import{mcpOAuthProtectedResourceHandler as Q,mcpOAuthAuthorizationServerHandler as u,mcpDynamicClientRegistrationHandler as aa,mcpAuthorizationHandler as ea,mcpTokenPortalHandler as ia,mcpCallbackHandler as f}from"./mcp-oauth.js";import{corsMiddleware as d}from"../middleware/corsMiddleware.js";import{installApiRoutes as la}from"./api-routes/api-routes.js";import{cookieMiddleware as ta}from"../middleware/cookieMiddleware.js";import{staticContentHandler as ma}from"../routes/static-content.js";import{infoHandler as R}from"./info.js";import{catalogHandler as na}from"./catalog/catalog.js";import{catalogRelationsHandler as da}from"./catalog/catalog-relations.js";import{bffCatalogHandler as oa}from"./catalog/bff-catalog.js";import{bffCatalogRevisionsHandler as pa}from"./catalog/bff-catalog-revisions.js";import{bffCatalogRelatedEntitiesHandler as Aa}from"./catalog/bff-catalog-related-entities.js";import{catalogAuthMiddleware as t}from"../middleware/catalogAuthMiddleware.js";import{telemetryMiddleware as Oa}from"../middleware/telemetry-middleware.js";import{errorHandler as _a}from"./error.js";function ae(a,l,m){const{resolveRouteData:o,readStaticAsset:p}=m;a.use("*",Z()),a.use("*",ta()),a.use("*",P(l)),a.use("*",S(l)),a.use("*",$()),a.use("*",z(l)),a.use("*",Oa()),a.use(e("*"),C({root:`./${c}`,getContent:(n,s)=>ma(n,s,l,p),rewriteRequestPath:n=>H(n)})),a.use(e(i.FEEDBACK),d({allowMethods:["POST"]})),a.use(e(i.ASK_AI),d({allowMethods:["POST"]})),a.use(e(i.SEMANTIC_SEARCH),d({allowMethods:["POST"]})),a.use("*",Ea(l));const A=g(l);a.use(e(i.INFO),R()),L.NEW_CATALOG_ENABLED==="true"&&(a.use(e(i.CATALOG_ENTITIES),t({serverOutDir:l.serverOutDir}),na(l)),a.use(e(i.CATALOG_ENTITIES_RELATIONS),t({serverOutDir:l.serverOutDir}),da(l)),a.get(e(i.BFF_CATALOG_ENTITIES),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),oa(l)),a.get(e(i.BFF_CATALOG_RELATED_ENTITIES),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),Aa(l)),a.get(e(i.BFF_CATALOG_REVISIONS),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),pa(l))),a.get(e(i.SHARED_PAGE_DATA),k(l)),a.get(e(i.PAGE_DATA),Y(l,o)),a.get(e(i.APP_DATA),G(l)),a.post(e(i.SEARCH),A,y(l)),a.post(e(i.SEARCH_FACETS),A,F(l)),a.post(e(i.AUTHORIZATION),D),a.post(e(i.LOGOUT),O(l)),a.get(e(i.LOGOUT),O(l)),a.get(e(i.POST_LOGOUT),M(l)),a.get(e(i.OIDC_CALLBACK),h(l)),a.get(e(i.REDOCLY_TOKEN_LOGIN),w(l)),a.get(e(i.REDOCLY_LOGIN_CALLBACK),v()),a.get(e(i.IDP_LOGIN),N(l)),a.post(e(i.SAML_CALLBACK),B(l)),a.get(e(i.INVITE),U(l)),a.get(e(i.HEALTH),q),a.get(`${i.MCP_OAUTH_PROTECTED_RESOURCE}${e("/mcp")}`,Q()),a.get(i.MCP_OAUTH_AUTHORIZATION_SERVER,u()),a.post(e(i.MCP_DYNAMIC_CLIENT_REGISTRATION),aa()),a.get(e(i.MCP_AUTHORIZATION),ea()),a.post(e(i.MCP_TOKEN_PORTAL),ia()),a.get(e(i.MCP_CALLBACK),f()),a.get(e(`${i.MCP_CALLBACK}/*`),f()),I(a,l),a.all(e(i.CORS_PROXY),r(l)),a.all(e(`${i.CORS_PROXY}/*`),r(l)),la(a,l),a.post(e(i.FEEDBACK),x(l)),a.post(e(i.RESOLVE_ROUTE_BY_PATH),E(l)),a.post(e(i.RESOLVE_ROUTES_BY_PATHS),V(l)),a.post(e(i.RESOLVE_ROUTE_BY_SLUG),T(l)),a.post(e(i.ASK_AI),W(l)),a.post(e(i.SEMANTIC_SEARCH),j(l)),a.get(e(i.GET_ROUTES_BY_LINE),_(l)),a.post(e(i.OTEL_TRACES),X),a.get(e(i.REPLAY_OAUTH2_CALLBACK),J),a.all(e("/*"),K(l,o,p)),a.get("*",b),a.onError(_a)}function Ea(a){return async(l,m)=>{await a.waitForPluginsLifecycle(),await m()}}function ee(a,l){a.get(e(i.INFO),R()),a.post(e(i.RESOLVE_ROUTE_BY_PATH),E(l)),a.post(e(i.RESOLVE_ROUTE_BY_SLUG),T(l)),a.get(e(i.GET_ROUTES_BY_LINE),_(l))}export{ee as installDevRoutes,ae as installProdRoutes,Ea as waitForPluginsLifecycle};
1
+ import{serveStatic as C}from"hono/serve-static";import{withPathPrefix as e,withoutPathPrefix as H}from"@redocly/theme/core/utils";import{ServerRoutes as i}from"../../../constants/common.js";import{PUBLIC_STATIC_FOLDER as c}from"../../constants/common.js";import{envConfig as L}from"../../config/env-config.js";import{authMiddleware as S}from"../middleware/authMiddleware.js";import{ensureSearchData as g}from"../middleware/ensureSearchData.js";import{dynamicMiddleware as P}from"../middleware/dynamic-middleware/dynamic-middleware.js";import{installRoutes as I}from"../../plugins/dev-onboarding/api/routes/index.js";import{authorizeHandler as D,oidcCallbackHandler as h,logoutHandler as O,postLogoutHandler as M,idpLoginHandler as N,redoclyLoginCallbackHandler as v,samlCallbackHandler as B,redoclyTokenLoginHandler as w,inviteHandler as U}from"./auth.js";import{appDataHandler as G}from"./app-data.js";import{searchFacetsHandler as F,searchHandler as y}from"./search.js";import{dynamicRouteHandler as K}from"./dynamic-route.js";import{pageDataHandler as Y,sharedPageDataHandler as k}from"./page-data.js";import{pathPrefixRedirectHandler as b}from"./path-prefix-redirect.js";import{getRoutesByLineHandler as _,resolvePathHandler as E,resolvePathsHandler as V,resolveSlugHandler as T}from"./resolve-route.js";import{feedbackHandler as x}from"./feedback.js";import{loggerMiddleware as $}from"../middleware/loggerMiddleware.js";import{responseHeadersMiddleware as z}from"../middleware/responseHeadersMiddleware.js";import{idleTimeoutMiddleware as Z}from"../middleware/idleTimeoutMiddleware.js";import{otelTracesHandler as X}from"./otel/otel.js";import{healthCheckHandler as q}from"./health.js";import{askAiHandler as W}from"./ask-ai.js";import{semanticSearchHandler as j}from"./semantic-search.js";import{replayOauth2RedirectCallbackHandler as J}from"./replay-oauth2-redirect.js";import{corsProxyHandler as r}from"./cors-proxy.js";import{mcpOAuthProtectedResourceHandler as Q,mcpOAuthAuthorizationServerHandler as u,mcpDynamicClientRegistrationHandler as aa,mcpAuthorizationHandler as ea,mcpTokenPortalHandler as ia,mcpCallbackHandler as f}from"./mcp-oauth.js";import{corsMiddleware as d}from"../middleware/corsMiddleware.js";import{installApiRoutes as la}from"./api-routes/api-routes.js";import{cookieMiddleware as ta}from"../middleware/cookieMiddleware.js";import{staticContentHandler as ma}from"../routes/static-content.js";import{infoHandler as R}from"./info.js";import{catalogHandler as na}from"./catalog/catalog.js";import{catalogRelationsHandler as da}from"./catalog/catalog-relations.js";import{bffCatalogHandler as oa}from"./catalog/bff-catalog.js";import{bffCatalogRevisionsHandler as pa}from"./catalog/bff-catalog-revisions.js";import{bffCatalogRelatedEntitiesHandler as Aa}from"./catalog/bff-catalog-related-entities.js";import{catalogAuthMiddleware as t}from"../middleware/catalogAuthMiddleware.js";import{telemetryMiddleware as Oa}from"../middleware/telemetry-middleware.js";import{errorHandler as _a}from"./error.js";function ae(a,l,m){const{resolveRouteData:o,readStaticAsset:p}=m;a.use("*",Z()),a.use("*",ta()),a.use("*",P(l)),a.use("*",S(l)),a.use("*",$()),a.use("*",z(l)),a.use("*",Oa()),a.use(e("*"),C({root:`./${c}`,getContent:(n,s)=>ma(n,s,l,p),rewriteRequestPath:n=>H(n)})),a.use(e(i.FEEDBACK),d({allowMethods:["POST"]})),a.use(e(i.ASK_AI),d({allowMethods:["POST"]})),a.use(e(i.SEMANTIC_SEARCH),d({allowMethods:["POST"]})),a.use("*",Ea(l));const A=g(l);a.use(e(i.INFO),R()),L.NEW_CATALOG_ENABLED&&(a.use(e(i.CATALOG_ENTITIES),t({serverOutDir:l.serverOutDir}),na(l)),a.use(e(i.CATALOG_ENTITIES_RELATIONS),t({serverOutDir:l.serverOutDir}),da(l)),a.get(e(i.BFF_CATALOG_ENTITIES),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),oa(l)),a.get(e(i.BFF_CATALOG_RELATED_ENTITIES),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),Aa(l)),a.get(e(i.BFF_CATALOG_REVISIONS),t({serverOutDir:l.serverOutDir,protectReadMethods:!1}),pa(l))),a.get(e(i.SHARED_PAGE_DATA),k(l)),a.get(e(i.PAGE_DATA),Y(l,o)),a.get(e(i.APP_DATA),G(l)),a.post(e(i.SEARCH),A,y(l)),a.post(e(i.SEARCH_FACETS),A,F(l)),a.post(e(i.AUTHORIZATION),D),a.post(e(i.LOGOUT),O(l)),a.get(e(i.LOGOUT),O(l)),a.get(e(i.POST_LOGOUT),M(l)),a.get(e(i.OIDC_CALLBACK),h(l)),a.get(e(i.REDOCLY_TOKEN_LOGIN),w(l)),a.get(e(i.REDOCLY_LOGIN_CALLBACK),v()),a.get(e(i.IDP_LOGIN),N(l)),a.post(e(i.SAML_CALLBACK),B(l)),a.get(e(i.INVITE),U(l)),a.get(e(i.HEALTH),q),a.get(`${i.MCP_OAUTH_PROTECTED_RESOURCE}${e("/mcp")}`,Q()),a.get(i.MCP_OAUTH_AUTHORIZATION_SERVER,u()),a.post(e(i.MCP_DYNAMIC_CLIENT_REGISTRATION),aa()),a.get(e(i.MCP_AUTHORIZATION),ea()),a.post(e(i.MCP_TOKEN_PORTAL),ia()),a.get(e(i.MCP_CALLBACK),f()),a.get(e(`${i.MCP_CALLBACK}/*`),f()),I(a,l),a.all(e(i.CORS_PROXY),r(l)),a.all(e(`${i.CORS_PROXY}/*`),r(l)),la(a,l),a.post(e(i.FEEDBACK),x(l)),a.post(e(i.RESOLVE_ROUTE_BY_PATH),E(l)),a.post(e(i.RESOLVE_ROUTES_BY_PATHS),V(l)),a.post(e(i.RESOLVE_ROUTE_BY_SLUG),T(l)),a.post(e(i.ASK_AI),W(l)),a.post(e(i.SEMANTIC_SEARCH),j(l)),a.get(e(i.GET_ROUTES_BY_LINE),_(l)),a.post(e(i.OTEL_TRACES),X),a.get(e(i.REPLAY_OAUTH2_CALLBACK),J),a.all(e("/*"),K(l,o,p)),a.get("*",b),a.onError(_a)}function Ea(a){return async(l,m)=>{await a.waitForPluginsLifecycle(),await m()}}function ee(a,l){a.get(e(i.INFO),R()),a.post(e(i.RESOLVE_ROUTE_BY_PATH),E(l)),a.post(e(i.RESOLVE_ROUTE_BY_SLUG),T(l)),a.get(e(i.GET_ROUTES_BY_LINE),_(l))}export{ee as installDevRoutes,ae as installProdRoutes,Ea as waitForPluginsLifecycle};
@@ -1,19 +1,5 @@
1
+ import { AsyncApiRealmAPI } from '@redocly/realm-asyncapi-sdk';
1
2
  import type { Context } from 'hono';
2
- import type { Attribute, Span } from './otlp.js';
3
3
  export declare function otelTracesHandler(ctx: Context): Promise<Response>;
4
- export declare function toCloudEventAttributes(span: Span, clientContext: ClientContext, sessionId: string): Attribute[];
5
- export declare function toSource(userId: string | undefined, sessionId: string): Source;
6
- type ClientContext = {
7
- userId: string | undefined;
8
- clientIp: string | undefined;
9
- userAgent: string | undefined;
10
- acceptLanguage: string | undefined;
11
- locale: string | undefined;
12
- };
13
- type Source = {
14
- id: string;
15
- object: 'user' | 'anonymous';
16
- uri: string;
17
- };
18
- export {};
4
+ export declare function toActor(userId: string | undefined, sessionId: string): AsyncApiRealmAPI.cloudEvents.CloudEventActor;
19
5
  //# sourceMappingURL=otel.d.ts.map
@@ -1 +1 @@
1
- import{envConfig as c}from"../../../config/env-config.js";import{getClientIp as v}from"../../utils/get-client-ip.js";import{toAttribute as t,getAttributesStringValue as _}from"./otlp.js";const g=c.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces";async function h(e){const s=await e.req.json(),u=m(e),o={resourceSpans:s.resourceSpans.map(n=>{const r=_(n.resource.attributes.find(i=>i.key==="session_id"));return r?{...n,resource:{...n.resource,attributes:[...n.resource.attributes]},scopeSpans:n.scopeSpans.map(i=>({...i,spans:i.spans.map(a=>({...a,attributes:a.name.startsWith("event.")&&a.name!=="event.undefined"?b(a,u,r):a.attributes}))}))}:n})};return await fetch(g,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}),e.newResponse(null,200,{})}function m(e){const s=e.get("auth")?.claims?.id||e.get("auth")?.claims?.sub,u=v(e.req.raw)||e.req.raw.context.remoteAddr?.hostname,o=e.req.raw.headers.get("user-agent"),n=e.req.raw.headers.get("accept-language"),r=n?.split(",")[0];return{userId:s,clientIp:u,userAgent:o||void 0,acceptLanguage:n||void 0,locale:r}}function p(e,s,u){const o=f(e.userId,s),n=new Date(Math.floor(Number(u.startTimeUnixNano)/1e6)).toISOString(),r=u.attributes.find(d=>d.key==="cloudevents.event_data.uri"),i=r&&"stringValue"in r.value?[t("cloudevents.event_data.page.uri",r.value.stringValue)]:[];return[t("cloudevents.event_spec_version","1.0"),t("cloudevents.event_object","event"),t("cloudevents.event_origin","realm-ui"),t("cloudevents.event_env",c.redoclyEnv),t("cloudevents.event_source",o.uri),t("cloudevents.event_source_details.id",o.id),t("cloudevents.event_source_details.object",o.object),t("cloudevents.event_source_details.uri",o.uri),t("cloudevents.event_actor.id",o.id),t("cloudevents.event_actor.object",o.object),t("cloudevents.event_actor.uri",o.uri),t("cloudevents.event_data_content_type","application/json; charset=utf-8"),t("cloudevents.event_organization_id",c.ORGANIZATION_ID),t("cloudevents.event_organization_slug",c.ORGANIZATION_SLUG),t("cloudevents.event_project_id",c.PROJECT_ID),t("cloudevents.event_project_slug",c.PROJECT_SLUG),t("cloudevents.event_session_id",s),t("cloudevents.event_time",n),t("cloudevents.event_client_ip",e.clientIp),t("cloudevents.event_user_agent",e.userAgent),...i]}function b(e,s,u){return[...e.attributes.filter(n=>{const r="stringValue"in n.value&&n.value.stringValue==="",i=/cloudevents\.event_source_details\..+/.test(n.key);return!(r||i)}),...p(s,u,e)].filter(n=>n!==void 0)}function f(e,s){return e?{id:e,object:"user",uri:`${c.MAIN_API_URL}/users/${e}`}:{id:l(s),object:"anonymous",uri:`${c.MAIN_API_URL}/anonymous/${l(s)}`}}function l(e){return e.replace("ses_","ann_")}export{h as otelTracesHandler,b as toCloudEventAttributes,f as toSource};
1
+ import{AsyncApiRealmAPI as T}from"@redocly/realm-asyncapi-sdk";import{envConfig as o}from"../../../config/env-config.js";import{getClientIp as R}from"../../utils/get-client-ip.js";import{getAttributesStringValue as v,mergeAttributes as S}from"./otlp.js";const C=o.OTEL_TRACES_URL||"https://otel.cloud.redocly.com/v1/traces";class O extends T.OtelClient{initTracer(){}}let a=null;function h(){return a||(a=new O,a.init({collectorTraceUrl:void 0,serviceName:"realm-ui",serviceVersion:"1.0",isProd:o.isProductionEnv,version:"1.0",tracerName:"attribute-processor"})),a}async function D(e){const n=await e.req.json();return n.resourceSpans?.length&&(w(n,P(e)),await fetch(C,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)})),e.newResponse(null,200)}function w(e,n){for(const r of e.resourceSpans){const c=r.resource.attributes.find(i=>i.key==="session_id");if(!c)continue;const d=v(c);if(!d)continue;const l=j(n.userId,d),A=new Date,_={organizationId:o.ORGANIZATION_ID||"",organizationSlug:o.ORGANIZATION_SLUG||"",projectId:o.PROJECT_ID||"",projectSlug:o.PROJECT_SLUG||"",env:o.REDOCLY_ENV||"",source:"urn:redocly:realm:ui",actor:{id:l.id,object:l.object,uri:l.uri},clientIp:n.clientIp,userAgent:n.userAgent,sessionId:d},s=(i,t)=>{const u=i.attributes.find(p=>p.key===t);return u?v(u):""};for(const i of r.scopeSpans)for(const t of i.spans){if(!t.name.startsWith("event.")||t.name==="event.undefined")continue;const u=s(t,"cloudevents.event_spec_version"),p=s(t,"cloudevents.event_object"),g=s(t,"cloudevents.event_data_content_type"),I=s(t,"cloudevents.event_origin"),m=s(t,"cloudevents.event_time"),f=m?new Date(m):A,b={..._,id:s(t,"cloudevents.event_id"),specversion:u,type:t.name.slice(6),object:p,datacontenttype:g,time:f,origin:I},y=h().processAttributes(b,f);S(t,y,{overwrite:!0})}}}function P(e){const n=e.get("auth")?.claims?.id||e.get("auth")?.claims?.sub,r=R(e.req.raw)||e.req.raw.context?.remoteAddr?.hostname,c=e.req.raw.headers.get("user-agent");return{userId:n,clientIp:r??void 0,userAgent:c??void 0}}function j(e,n){if(e)return{id:e,object:"user",uri:`${o.MAIN_API_URL}/users/${e}`};const r=n.replace("ses_","ann_");return{id:r,object:"anonymous",uri:`${o.MAIN_API_URL}/anonymous/${r}`}}export{D as otelTracesHandler,j as toActor};
@@ -33,6 +33,9 @@ export type IntAttribute = {
33
33
  export type OptionalAttribute = Attribute | undefined;
34
34
  export type EventAttribute = Map<string, Attribute>;
35
35
  export declare function toAttribute(key: string, value: number | string | undefined | null): OptionalAttribute;
36
- export declare function getAttributesStringValue(attr?: Attribute): string | undefined;
36
+ export declare function mergeAttributes(span: Span, attrs: Record<string, string | number | null | undefined>, { overwrite }?: {
37
+ overwrite?: boolean;
38
+ }): void;
39
+ export declare function getAttributesStringValue(attr: Attribute): string;
37
40
  export declare function getAttributesIntValue(attr?: Attribute): number | undefined;
38
41
  //# sourceMappingURL=otlp.d.ts.map
@@ -1 +1 @@
1
- function n(e,u){if(u!=null)return typeof u=="number"?{key:e,value:{intValue:u}}:{key:e,value:{stringValue:u}}}function t(e){if(e?.value&&typeof e.value=="object"&&"stringValue"in e.value)return e.value.stringValue}function i(e){if(e?.value&&typeof e.value=="object"&&"intValue"in e.value)return e.value.intValue}export{i as getAttributesIntValue,t as getAttributesStringValue,n as toAttribute};
1
+ function f(e,n){if(n!=null)return typeof n=="number"?{key:e,value:{intValue:n}}:{key:e,value:{stringValue:n}}}function l(e,n,{overwrite:o=!1}={}){for(const[u,i]of Object.entries(n)){const r=e.attributes.findIndex(t=>t.key===u);if(r!==-1){if(!o)continue;const t=f(u,i);t&&(e.attributes[r]=t)}else{const t=f(u,i);t&&e.attributes.push(t)}}}function s(e){return"stringValue"in e.value?e.value.stringValue:""}function a(e){if(e?.value&&typeof e.value=="object"&&"intValue"in e.value)return e.value.intValue}export{a as getAttributesIntValue,s as getAttributesStringValue,l as mergeAttributes,f as toAttribute};
@@ -1 +1 @@
1
- import s from"path";import{REDOCLY_ROUTE_RBAC as C}from"@redocly/config";import{PUBLIC_STATIC_FOLDER as r}from"../../constants/common.js";import{isPathInFolder as g}from"../../../utils/path/is-path-in-folder.js";import{fileExistsAsync as h}from"../../utils/index.js";import{handleUnauthorizedAsset as w}from"../utils.js";import{MIME_TYPES as E}from"../mime-types.js";import{canAccessResource as R}from"../../utils/rbac.js";const O=async(t,n,o,c)=>{const a=n.req,{isAuthenticated:m,teams:l,claims:{email:u}}=n.get("auth"),i=s.join(r,r);t.startsWith(i)&&(t=t.replace(i,r));const e=s.resolve(o.outdir,t);if(!g(e,o.outdir))return null;if(await h(e)){const p={[C]:{slug:t,fsPath:e},slug:t};if(!R(p,{isAuthenticated:m,email:u,teams:l},o.config.access?.rbac,o.config.access?.requiresLogin))return w(n);const f=a.query("download")!=null,d=E[s.extname(e)]||"text/plain",A=await c(e);return n.newResponse(A,200,{"Content-Type":d,"Access-Control-Allow-Origin":"*",...f&&{"Content-Disposition":`attachment; filename="${s.basename(e)}"`}})}else return null};export{O as staticContentHandler};
1
+ import s from"path";import{REDOCLY_ROUTE_RBAC as C}from"@redocly/config";import{PUBLIC_STATIC_FOLDER as r}from"../../constants/common.js";import{isPathInFolder as g}from"../../../utils/path/is-path-in-folder.js";import{fileExistsAsync as T}from"../../utils/index.js";import{handleUnauthorizedAsset as h}from"../utils.js";import{MIME_TYPES as w}from"../mime-types.js";import{getContentTypeHeaderValue as y}from"../utils/content-type.js";import{canAccessResource as E}from"../../utils/rbac.js";const U=async(e,o,n,a)=>{const c=o.req,{isAuthenticated:m,teams:l,claims:{email:u}}=o.get("auth"),i=s.join(r,r);e.startsWith(i)&&(e=e.replace(i,r));const t=s.resolve(n.outdir,e);if(!g(t,n.outdir))return null;if(await T(t)){const p={[C]:{slug:e,fsPath:t},slug:e};if(!E(p,{isAuthenticated:m,email:u,teams:l},n.config.access?.rbac,n.config.access?.requiresLogin))return h(o);const f=c.query("download")!=null,d=w[s.extname(t)]||"text/plain",A=await a(t);return o.newResponse(A,200,{"Content-Type":y(d),"Access-Control-Allow-Origin":"*",...f&&{"Content-Disposition":`attachment; filename="${s.basename(t)}"`}})}else return null};export{U as staticContentHandler};
@@ -0,0 +1,2 @@
1
+ export declare function getContentTypeHeaderValue(mimeType: string): string;
2
+ //# sourceMappingURL=content-type.d.ts.map
@@ -0,0 +1 @@
1
+ function r(t){return t.startsWith("text/")?`${t}; charset=utf-8`:t}export{r as getContentTypeHeaderValue};
@@ -33,6 +33,7 @@ export type PlanGates = {
33
33
  [FEATURE.advancedSearch]: boolean;
34
34
  [FEATURE.ssoDirect]: boolean;
35
35
  [FEATURE.aiSearchLimit]: number;
36
+ [FEATURE.kvStorageLimit]: number;
36
37
  [FEATURE.mcp]: boolean;
37
38
  };
38
39
  export type Entitlements = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/redoc",
3
- "version": "0.132.0",
3
+ "version": "0.133.0-next.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -29,7 +29,7 @@
29
29
  "@opentelemetry/sdk-trace-web": "2.0.1",
30
30
  "@opentelemetry/semantic-conventions": "1.34.0",
31
31
  "@redocly/ajv": "8.18.0",
32
- "@redocly/openapi-core": "2.25.2",
32
+ "@redocly/openapi-core": "2.29.0",
33
33
  "@shikijs/transformers": "3.21.0",
34
34
  "@tanstack/react-query": "5.62.3",
35
35
  "@tanstack/react-table": "8.21.3",
@@ -44,7 +44,7 @@
44
44
  "colorette": "2.0.20",
45
45
  "copy-to-clipboard": "3.3.3",
46
46
  "dotenv": "16.4.5",
47
- "drizzle-orm": "^0.44.2",
47
+ "drizzle-orm": "^0.45.0",
48
48
  "enquirer": "2.3.6",
49
49
  "esbuild": "0.27.0",
50
50
  "escape-carriage": "^1.3.1",
@@ -53,7 +53,7 @@
53
53
  "flexsearch": "0.7.43",
54
54
  "graphql": "16.12.0",
55
55
  "gray-matter": "4.0.3",
56
- "hono": "4.12.8",
56
+ "hono": "4.12.14",
57
57
  "htmlparser2": "8.0.2",
58
58
  "i18next": "22.4.15",
59
59
  "is-glob": "4.0.3",
@@ -86,18 +86,18 @@
86
86
  "web-vitals": "3.3.1",
87
87
  "workerpool": "9.2.0",
88
88
  "ws": "^8.17.1",
89
- "xml-crypto": "6.0.1",
89
+ "xml-crypto": "6.1.0",
90
90
  "xpath": "0.0.34",
91
91
  "yaml-ast-parser": "0.0.43",
92
92
  "zod": "^3.25.76",
93
+ "@redocly/asyncapi-docs": "1.10.0-next.0",
93
94
  "@redocly/config": "0.48.0",
94
- "@redocly/graphql-docs": "1.9.0",
95
- "@redocly/openapi-docs": "3.20.0",
96
- "@redocly/portal-legacy-ui": "0.15.0",
97
- "@redocly/portal-plugin-mock-server": "0.17.0",
98
- "@redocly/realm-asyncapi-sdk": "0.10.0",
99
- "@redocly/theme": "0.64.0",
100
- "@redocly/asyncapi-docs": "1.9.0"
95
+ "@redocly/graphql-docs": "1.10.0-next.0",
96
+ "@redocly/openapi-docs": "3.21.0-next.0",
97
+ "@redocly/portal-legacy-ui": "0.16.0-next.0",
98
+ "@redocly/portal-plugin-mock-server": "0.18.0-next.0",
99
+ "@redocly/realm-asyncapi-sdk": "0.11.0-next.0",
100
+ "@redocly/theme": "0.65.0-next.0"
101
101
  },
102
102
  "peerDependencies": {
103
103
  "react": "^19.2.4",
@@ -1,22 +0,0 @@
1
- import { z } from 'zod';
2
- /**
3
- * Schema for test-related environment variables.
4
- * These are used only in testing scenarios.
5
- */
6
- export declare const testSchema: z.ZodObject<{
7
- TEST_API_KEY: z.ZodOptional<z.ZodString>;
8
- TEST_SERVER_URL: z.ZodOptional<z.ZodString>;
9
- DECORATOR_CONFIG: z.ZodOptional<z.ZodString>;
10
- SECRET_VALUE: z.ZodOptional<z.ZodString>;
11
- }, "strip", z.ZodTypeAny, {
12
- TEST_API_KEY?: string | undefined;
13
- TEST_SERVER_URL?: string | undefined;
14
- DECORATOR_CONFIG?: string | undefined;
15
- SECRET_VALUE?: string | undefined;
16
- }, {
17
- TEST_API_KEY?: string | undefined;
18
- TEST_SERVER_URL?: string | undefined;
19
- DECORATOR_CONFIG?: string | undefined;
20
- SECRET_VALUE?: string | undefined;
21
- }>;
22
- //# sourceMappingURL=test.d.ts.map
@@ -1 +0,0 @@
1
- import{z as t}from"zod";const i=t.object({TEST_API_KEY:t.string().optional(),TEST_SERVER_URL:t.string().url().optional(),DECORATOR_CONFIG:t.string().optional(),SECRET_VALUE:t.string().optional()});export{i as testSchema};
@@ -1,18 +0,0 @@
1
- /**
2
- * Sets or removes an environment variable at runtime.
3
- *
4
- * - If a `value` is provided (string, including empty string), it will be assigned to `process.env[name]`.
5
- * - If the `value` is `undefined` or `null`, the environment variable will be deleted.
6
- *
7
- * @param name - The name of the environment variable to modify.
8
- * @param value - The value to set. If `undefined` or `null`, the variable will be removed.
9
- *
10
- * @example
11
- * writeEnvVariable("API_KEY", "12345");
12
- * console.log(process.env.API_KEY); // "12345"
13
- *
14
- * writeEnvVariable("API_KEY", undefined);
15
- * console.log(process.env.API_KEY); // undefined
16
- */
17
- export declare function writeEnvVariable(name: string, value: string | undefined | null): void;
18
- //# sourceMappingURL=write-env-variable.d.ts.map
@@ -1 +0,0 @@
1
- function i(e,n){n==null?delete process.env[e]:process.env[e]=n}export{i as writeEnvVariable};