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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/bin.js +1 -1
  3. package/dist/cli/prepare/copy-env-files.js +1 -1
  4. package/dist/client/app/hooks/useTelemetry.d.ts +2 -2
  5. package/dist/client/app/telemetry/index.d.ts +11 -1
  6. package/dist/client/app/telemetry/index.js +1 -1
  7. package/dist/constants/common.d.ts +1 -0
  8. package/dist/constants/common.js +1 -1
  9. package/dist/server/api-routes/execute-api-route.js +1 -1
  10. package/dist/server/constants/plugins/catalog-entities.d.ts +1 -0
  11. package/dist/server/constants/plugins/catalog-entities.js +1 -1
  12. package/dist/server/esbuild/esbuild.js +3 -3
  13. package/dist/server/node-bundle-entry.js +1 -1
  14. package/dist/server/persistence/kv/repositories/kv-remote-repository.d.ts +1 -0
  15. package/dist/server/persistence/kv/repositories/kv-remote-repository.js +2 -1
  16. package/dist/server/plugins/catalog-entities/database/catalog-entities-service.d.ts +4 -4
  17. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-repository.d.ts +2 -2
  18. package/dist/server/plugins/catalog-entities/database/repositories/local/catalog-entities-local-write-repository.js +1 -1
  19. package/dist/server/plugins/catalog-entities/database/repositories/remote/catalog-entities-remote-repository.js +1 -1
  20. package/dist/server/plugins/catalog-entities/plugin.js +1 -1
  21. package/dist/server/plugins/config-parser/loaders/utils/read-and-validate-config.js +1 -1
  22. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.d.ts +54 -0
  23. package/dist/server/plugins/mcp/docs-mcp/tools/docs-mcp-tool.js +1 -0
  24. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.d.ts +9 -8
  25. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoint-info.js +1 -1
  26. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.d.ts +9 -8
  27. package/dist/server/plugins/mcp/docs-mcp/tools/get-endpoints.js +1 -1
  28. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.d.ts +9 -8
  29. package/dist/server/plugins/mcp/docs-mcp/tools/get-full-api-description.js +1 -1
  30. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.d.ts +9 -8
  31. package/dist/server/plugins/mcp/docs-mcp/tools/get-security-schemes.js +1 -1
  32. package/dist/server/plugins/mcp/docs-mcp/tools/index.d.ts +7 -13
  33. package/dist/server/plugins/mcp/docs-mcp/tools/index.js +1 -1
  34. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.d.ts +9 -6
  35. package/dist/server/plugins/mcp/docs-mcp/tools/list-apis.js +1 -1
  36. package/dist/server/plugins/mcp/docs-mcp/tools/search.d.ts +9 -2
  37. package/dist/server/plugins/mcp/docs-mcp/tools/search.js +1 -1
  38. package/dist/server/plugins/mcp/docs-mcp/tools/utils.d.ts +2 -1
  39. package/dist/server/plugins/mcp/docs-mcp/tools/utils.js +6 -6
  40. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.d.ts +9 -2
  41. package/dist/server/plugins/mcp/docs-mcp/tools/whoami.js +1 -1
  42. package/dist/server/plugins/mcp/handlers/handle-mcp-request.d.ts +5 -0
  43. package/dist/server/plugins/mcp/handlers/handle-mcp-request.js +1 -0
  44. package/dist/server/plugins/mcp/handlers/mcp-request-handler.d.ts +0 -1
  45. package/dist/server/plugins/mcp/handlers/mcp-request-handler.js +1 -1
  46. package/dist/server/plugins/mcp/types.d.ts +40 -0
  47. package/dist/server/plugins/mcp/workers/execute-mcp-tool.d.ts +3 -0
  48. package/dist/server/plugins/mcp/workers/execute-mcp-tool.js +1 -0
  49. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.d.ts +12 -0
  50. package/dist/server/plugins/scorecards/database/repositories/local/scorecards-config-local-repository.js +1 -0
  51. package/dist/server/plugins/scorecards/database/scorecards-config-service.d.ts +11 -0
  52. package/dist/server/plugins/scorecards/database/scorecards-config-service.js +1 -0
  53. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.d.ts +2 -1
  54. package/dist/server/plugins/scorecards/workers/run-scorecards-worker.js +1 -1
  55. package/dist/server/plugins/scorecards/workers/scorecards.d.ts +2 -0
  56. package/dist/server/plugins/scorecards/workers/scorecards.js +1 -1
  57. package/dist/server/plugins/sso/index.js +1 -1
  58. package/dist/server/providers/database/base-repository.d.ts +1 -0
  59. package/dist/server/providers/database/base-repository.js +1 -1
  60. package/dist/server/providers/database/database-connection-factory.js +1 -1
  61. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.d.ts +24 -18
  62. package/dist/server/providers/database/databases/main-sqlite/schemas/scorecards-config-table.js +1 -1
  63. package/dist/server/ssr/server-side-props/get-server-props-from-user-handler.js +1 -1
  64. package/dist/server/store.d.ts +3 -1
  65. package/dist/server/store.js +1 -1
  66. package/dist/server/types/plugins/common.d.ts +3 -1
  67. package/dist/server/utils/envs/load-env-variables.d.ts +1 -1
  68. package/dist/server/utils/envs/load-env-variables.js +1 -1
  69. package/dist/server/utils/envs/sanitize-branch-name.d.ts +6 -0
  70. package/dist/server/utils/envs/sanitize-branch-name.js +1 -0
  71. package/dist/server/utils/lifecycle-hooks.js +1 -1
  72. package/dist/server/utils/time/with-timestamp.d.ts +42 -10
  73. package/dist/server/utils/time/with-timestamp.js +1 -1
  74. package/dist/server/web-server/dev-server.js +1 -1
  75. package/dist/server/web-server/handle-api-route-request.js +1 -1
  76. package/dist/server/workers/mcp-tool-worker-pool.d.ts +4 -0
  77. package/dist/server/workers/mcp-tool-worker-pool.js +1 -0
  78. package/dist/server/workers/mcp-tool-worker.d.ts +2 -0
  79. package/dist/server/workers/mcp-tool-worker.js +1 -0
  80. package/dist/server/workers/types.d.ts +6 -0
  81. package/dist/utils/env/is-local-development.js +1 -1
  82. package/package.json +7 -7
  83. package/dist/server/plugins/mcp/workers/run-api-routes-worker.d.ts +0 -5
  84. package/dist/server/plugins/mcp/workers/run-api-routes-worker.js +0 -1
  85. package/dist/server/workers/mcp-worker-pool.d.ts +0 -4
  86. package/dist/server/workers/mcp-worker-pool.js +0 -1
@@ -1 +1 @@
1
- import b from"@markdoc/markdoc";import{getPathnameForLocale as C}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as A}from"./constants/common.js";import{GATED_MARKDOC_TAGS as D}from"./constants/entitlements.js";import{isObject as T}from"../utils/guards/is-object.js";import{mapObject as M}from"../utils/object/map-object.js";import{getValueDeep as w}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as O}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as k}from"../utils/path/is-local-link.js";import{reporter as S}from"./tools/notifiers/reporter.js";import{logger as p}from"./tools/notifiers/logger.js";import{sha1 as L}from"./utils/crypto/sha1.js";import{writeEnvVariable as _}from"./utils/envs/write-env-variable.js";import{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{writeSharedData as B}from"./utils/index.js";import{renderComponents as G}from"./ssr/render.js";import{readStaticData as I,writeStaticData as N}from"./utils/static-data.js";import{parseAndResolveMarkdoc as V}from"./plugins/markdown/compiler.js";import{getMarkdocOptions as j}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as y}from"./entitlements/entitlements-provider.js";import{isL10nPath as H}from"./fs/utils/is-l10n-path.js";import{resolveMetadataGlobs as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as U}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as K}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as q}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",Et="markdown/partials-deps",v="PLAN_GATES",$=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORG_ID"],Pt="userDefinedApiFunctions";class E{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;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},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:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};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 q("build.reload_markdoc_options",async()=>{const t=y.instance(),e=await j(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await V(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};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 e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=w(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=U(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!y.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&K(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??L(r);return this.#t[t]===a||(this.#t[t]=a,await B(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=O(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...J(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=C(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!k(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!H(r.fsPath):r.slug.startsWith(`/${s}`))};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,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&N(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return I(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:A,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):G(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}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[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=F("PLAN_GATES"),e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=W(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=w(t,r);if(c||!T(o)&&!Array.isArray(o)){await S.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!$.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await S.panicOnBuildContentError(e)}}function W(P){return M(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,Et as MARKDOC_PARTIALS_DEPS_KEY,E as Store,Pt as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
1
+ import b from"@markdoc/markdoc";import{getPathnameForLocale as A}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as u}from"../constants/common.js";import{DEFAULT_TITLE as C}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 T}from"../utils/object/map-object.js";import{getValueDeep as S}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as M}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as f}from"../utils/path/normalize-route-slug.js";import{isLocalLink as L}from"../utils/path/is-local-link.js";import{reporter as w}from"./tools/notifiers/reporter.js";import{logger as p}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{readEnvVariable as F}from"./utils/envs/read-env-variable.js";import{KvService as G}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 y}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 x}from"./utils/redirects/find-redirect.js";import{addWildcardRedirectToTree as q}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as $}from"../cli/telemetry/helpers/trace-step.js";const R={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map"},g="markdown/partials",bt="markdown/partials-deps",v="PLAN_GATES",W=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORG_ID"],At="userDefinedApiFunctions";class E{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;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};#s=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},rbac:{},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:e,serverMode:s=!1,serverOutDir:r}){this.#r=e,this.outdir=t,this.serverMode=s,this.serverOutDir=r,this.userCodeReady=new Promise(a=>{this.#a=a})}on(t,e){const s=this.listeners.get(t);s?s.add(e):this.listeners.set(t,new Set([e]))}queueEvent=(t,e,...s)=>{this.#e.set(t+String(e),[t,e,...s])};runListeners=(t,e,...s)=>{for(const r of this.listeners.get(t)||new Set)e?r(e,...s):r(...s)};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=y.instance(),e=await H(this.serverOutDir),s=Object.fromEntries(Object.entries(e.tags).filter(([r])=>D[r]!=null?t.canAccessFeature(D[r]):!0));this.#s={...e,tags:s}})}get markdocOptions(){return{...this.#s,partials:this.getGlobalConfig(g),themeConfig:this.config.markdown}}setGlobalData=t=>{const e=this.globalData,s={...this.globalData,...t};this.globalData=s,JSON.stringify(s)!==JSON.stringify(e)&&this.queueEvent("global-data-updated",void 0,s)};getGlobalData=()=>this.globalData;getKv=async()=>G.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async(t,e,s)=>{const{data:{info:r,ast:a},compoundHash:c}=await j(t,this.markdocOptions,{actions:this,context:e});for(const o of r.sharedDataDeps||[]){for(const i of s?.routeSlugs||[])this.addRouteSharedData(i,o,o);for(const i of s?.sharedDataIds||[]){const n=this.sharedDataDeps.get(i)||new Set;n.add(o),this.sharedDataDeps.set(i,n)}}for(const o of r.dynamicMarkdocComponents||[]){for(const i of s?.routeSlugs||[]){const n=this.routesDynamicComponents.get(i)||new Set;n.add(o),this.routesDynamicComponents.set(i,n)}for(const i of s?.sharedDataIds||[]){const n=this.sharedDataMarkdocComponents.get(i)||new Set;n.add(o),this.sharedDataMarkdocComponents.set(i,n)}}if(s?.routeSlugs&&r.partials?.length)for(const o of s.routeSlugs){const i=this.routesPartials.get(o)||[];for(const n of r.partials)i.includes(n)||i.push(n);this.routesPartials.set(o,i)}return{info:r,ast:a,compoundHash:c}};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 e=Object.keys(t);for(const c of e)for(const o in this.replacedEnvVars)if(o===c||o.startsWith(`${c}:`)){const i=o.split(":"),{error:n,value:l}=S(t,i);(n||l!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:s,unsetEnvVars:r,replacedValues:a}=J(t);for(const c of r)this.unsetEnvVars.add(c);Object.assign(this.replacedEnvVars,a),Object.assign(this.config,s)};getConfig=()=>this.config;getGlobalConfig=t=>this.config[t];getSearchFacets=()=>this.searchFacets;addRedirect=(t,e)=>{if(!y.instance().canAccessFeature("redirects")&&t!=="/")return;this.config.redirects||(this.config.redirects={});const a=f(t).toLowerCase();this.config.redirects[a]=e,a.endsWith("*")&&q(this.config.wildcardRedirectsTree,a)};getRedirect=t=>{const e=f(t).toLowerCase();return x(e,this.config.redirects,this.config.wildcardRedirectsTree)};createSharedData=async(t,e,s)=>{if(s&&this.#t[t]===s)return t;const r=JSON.stringify(e),a=s??k(r);return this.#t[t]===a||(this.#t[t]=a,await B(t,r,this.outdir),this.queueEvent("shared-data-updated",t)),t};addRouteSharedData=(t,e,s)=>{const r=M(t),a=this.routesSharedData.get(r)||{};a[e]=s,this.routesSharedData.set(r,a),p.verbose(`Adding shared data to ${t}, ${e}, ${s}`)};getRouteSharedDataByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.routesSharedData.get(e)||{}:{}};getPartialsForRoute=t=>{const e=this.getGlobalConfig(g)||{},s=this.routesPartials.get(t);if(!s||s.length===0)return{};const r={};for(const a of s)e[a]&&(r[a]=e[a]);return r};addRoute=t=>{const s={...U(t.fsPath,this.config.metadataGlobs),...t.metadata||{}};this.newRoutes.push({...t,metadata:s}),p.verbose("Created route %s",t.slug)};addRouteSharedDataToAllLocales=(t,e,s)=>{const r=[u,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const c=A(t,u,a.code,r);this.addRouteSharedData(c,e,s)}};addApiRoute=t=>{this.apiRoutes.push(t),p.verbose("Created API route %s",t.slug)};addMiddleware=t=>{this.middleware.push(t),p.verbose("Created middleware %s",t.id)};getRouteByFsPath=t=>{const e=this.routesByFsPath.get(t);return e?this.getRouteBySlug(e):void 0};getRouteBySlug=(t,e={})=>{const{followRedirect:s=!0}=e,r=this.getRedirect(t);return s&&r?this.routesBySlug.get(f(r.to)):this.routesBySlug.get(t)};slugHasRouteOrRedirect=t=>{if(this.routesBySlug.has(t))return!0;const e=this.getRedirect(t);if(!e)return!1;if(!L(e.to))return!0;const s=f(e.to);return this.routesBySlug.has(s)};getRoutesByTemplateId=t=>this.newRoutes.filter(e=>e.templateId===t);getAllRoutesForLocale=(t=u)=>{const e=Array.from(this.routesBySlug.values()),s=t.toLowerCase();return e.filter(r=>t===u?!K(r.fsPath):r.slug.startsWith(`/${s}`))};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,e)=>(this.templates.set(t,e),t);addBrowserPlugin=t=>{this.browserPlugins.add(t)};createRequestHandler=(t,e)=>(this.apiRoutesRequestHandlers.set(t,e),t);registerServerPropsGetter=(t,e)=>(this.serverPropsGetters.set(t,e),t);registerPagePropsGetter=(t,e)=>{this.pagePropsGetters.set(t,e)};async writeRouteStaticData(t,e){const s=await this.resolveRouteStaticData(t,e,!1);s&&V(t.slug,s,this.outdir)}async resolveRouteStaticData(t,e,s){if(this.serverMode)return N(t.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:(l,d)=>this.parseMarkdoc(l,d,{routeSlugs:[t.slug]})},a=await t.getStaticData?.(t,r)||{},c=new Set(this.routesDynamicComponents.get(t.slug)),o=this.routesSharedData.get(t.slug)||{};for(const l of Object.values(o)){const d=this.sharedDataMarkdocComponents.get(l);d&&d.forEach(h=>c.add(h));const m=this.sharedDataDeps.get(l);m&&m.forEach(h=>this.addRouteSharedData(t.slug,h,h))}const i=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await t.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(c),metadata:{...a?.props?.metadata,...t.metadata},seo:{title:C,...i,...a.props?.seo},compilationErrors:this.compilationErrors},lastModified:s||!t.fsPath?null:await this.lifecycleContext?.fs.getLastModified(t.fsPath)}}addSsrComponents(t,e){if(!t?.length)return;const s=typeof t[0]=="string"?t.join(""):I(t);s&&(e==="head"?this.ssr.headTags.push(s):e==="preBody"?this.ssr.preBodyTags.push(s):this.ssr.postBodyTags.push(s))}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[s,r]of Object.entries(R))switch(r){case"map":const a=Array.from(this[s].entries());t.push([s,a]);break;case"object":s==="config"&&t.push([s,await this.getConfigWithEnvPlaceholders()]),t.push([s,this[s]]);break;default:throw new Error("Invalid format")}const e=Object.fromEntries(t);return e[v]=F("PLAN_GATES"),e}static fromJson(t,e){const s=new E(e);for(const[a,c]of Object.entries(R))switch(c){case"map":s[a]=new Map(t[a]);break;case"object":if(a==="config"){s.setGlobalConfig(t[a]);break}s[a]=t[a];break;default:throw new Error("Invalid format")}s.config[g]=z(s.config[g]||{});const r=t[v];return r&&_("PLAN_GATES",r),s}async getConfigWithEnvPlaceholders(){const t=JSON.parse(JSON.stringify(this.config));for(const e in this.replacedEnvVars){const{original:s}=this.replacedEnvVars[e],r=e.split(":"),a=r.pop(),{error:c,value:o}=S(t,r);if(c||!O(o)&&!Array.isArray(o)){await w.panicOnBuild(`Failed to replace env var with env name for ${e}`);continue}o[a]=s}return t}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const t=Array.from(this.unsetEnvVars).filter(s=>!W.includes(s));if(t.length===0)return;const e=`Failed to resolve config. The following environment variables are not set: ${t.join(", ")}`;await w.panicOnBuildContentError(e)}}function z(P){return T(P,t=>b.Ast.fromJSON(JSON.stringify(t)))}export{g as MARKDOC_PARTIALS_DATA_KEY,bt as MARKDOC_PARTIALS_DEPS_KEY,E as Store,At as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
@@ -6,7 +6,7 @@ import type { ProductConfig } from '@redocly/theme/config';
6
6
  import type { SearchFacet } from '@redocly/theme/core/types';
7
7
  import type { GlobalData, Feature } from '../../../types/index.js';
8
8
  import type { SearchDocument } from '../../types';
9
- import type { RbacScopeItems, RedirectConfig, RedoclyConfig, ServerPropsContext, ServerPropsRequest, PageProps, PageStaticData, NavItem, ResolvedNavItem, Version, MdOptions } from '@redocly/config';
9
+ import type { RbacScopeItems, RedirectConfig, RedoclyConfig, ServerPropsContext, ServerPropsRequest, PageProps, PageStaticData, NavItem, ResolvedNavItem, Version, MdOptions, KvService } from '@redocly/config';
10
10
  import type { LoaderFn } from '../fs';
11
11
  import type { MarkdocDeps } from './markdown';
12
12
  import type { BundledDefinition } from '../../plugins/openapi-docs/load-definition';
@@ -148,6 +148,7 @@ export type ProcessContentActions = {
148
148
  registerServerPropsGetter: (id: string, importPath: string) => string;
149
149
  registerPagePropsGetter: (id: string, importPath: string) => void;
150
150
  addSsrComponents: (components: JSX.Element[] | string[], position: 'head' | 'preBody' | 'postBody') => void;
151
+ getKv: () => Promise<KvService>;
151
152
  serverOutDir: string;
152
153
  contentDir: string;
153
154
  outdir: string;
@@ -185,6 +186,7 @@ export type AfterRoutesCreatedActions = {
185
186
  addApiRoute: (route: ApiRoute) => void;
186
187
  loadOpenApiDefinitions(context: LifecycleContext): Promise<BundledDefinition[]>;
187
188
  getRouteSharedDataByFsPath: (routeFsPath: string) => Record<string, string> | undefined;
189
+ getKv: () => Promise<KvService>;
188
190
  };
189
191
  export type LifecycleContext = {
190
192
  fs: ContentFs;
@@ -1,2 +1,2 @@
1
- export declare function loadEnvVariables(pathToEnvFile?: string): void;
1
+ export declare function loadEnvVariables(cwd?: string): Promise<void>;
2
2
  //# sourceMappingURL=load-env-variables.d.ts.map
@@ -1 +1 @@
1
- import*as r from"dotenv";import*as a from"path";import{readEnvVariable as t}from"../../utils/envs/read-env-variable.js";function i(o){r.config({path:a.resolve(o??"",".env")});const n=t("REDOCLY_ENV");let e;switch(n){case"production":e=".env.production";break;case"preview":e=".env.preview";break;case"development":default:e=".env.development";break}r.config({path:a.resolve(o??"",e)})}export{i as loadEnvVariables};
1
+ import*as a from"dotenv";import*as n from"path";import{simpleGit as s}from"simple-git";import{readEnvVariable as o}from"../../utils/envs/read-env-variable.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){a.config({path:n.resolve(e??"",".env")});const t=o("PUBLIC_REDOCLY_BRANCH_NAME")||await p(e);if(t){const c=v(t);a.config({path:n.resolve(e??"",`.env.branch.${c}`),override:!0})}const i=o("REDOCLY_ENV");let r;switch(i){case"production":r=".env.production";break;case"preview":r=".env.preview";break;case"development":default:r=".env.development";break}a.config({path:n.resolve(e??"",r),override:!0})}export{h as loadEnvVariables};
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Sanitizes a branch name for use in env file names and config keys.
3
+ * Replaces `/` with `-` to support branches like `feature/my-branch`.
4
+ */
5
+ export declare function sanitizeBranchName(branchName: string): string;
6
+ //# sourceMappingURL=sanitize-branch-name.d.ts.map
@@ -0,0 +1 @@
1
+ function n(e){return e.replace(/\//g,"-")}export{n as sanitizeBranchName};
@@ -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 s,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 a}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 N(e,o,p){f(o["project-dir"]),process.env.REDOCLY_RUNNING_COMMAND=e;const m=e===r.DEVELOP?" Previewing with":"Building with";switch(n.logInFooter("product",`${m} ${s(`${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 a(),L(p)}export{N as beforeCommand};
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 s,gray as a}from"../tools/notifiers/helpers/colors.js";import{loadEnvVariables as c}from"./envs/load-env-variables.js";import{copyFolderRecursiveSync as f}from"./fs.js";import{validateInstalledVersion as l}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}){f(i.join(e,t),i.join(o,t))}async function N(e,o,p){await c(o["project-dir"]),process.env.REDOCLY_RUNNING_COMMAND=e;const m=e===r.DEVELOP?" Previewing with":"Building with";switch(n.logInFooter("product",`${m} ${s(`${E}@${P}`)}`),n.logInFooter("server",` \u{1F310} Preview URL: ${a("server starting...")}`),e){case r.DEVELOP:case r.BUILD:case r.PREPARE:v(o);break;default:break}await l(),L(p)}export{N as beforeCommand};
@@ -1,25 +1,57 @@
1
+ type TimestampField = 'createdAt' | 'updatedAt' | 'archivedAt';
2
+ type TimestampFieldsOptions = {
3
+ fields?: TimestampField[];
4
+ dates?: {
5
+ createdAt?: Date;
6
+ updatedAt?: Date;
7
+ archivedAt?: Date;
8
+ };
9
+ };
10
+ type TimestampFieldsMap = {
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ archivedAt: string;
14
+ };
15
+ type WithTimestampResult<T, F extends TimestampField[]> = T & Pick<TimestampFieldsMap, F[number]>;
1
16
  /**
2
- * Adds timestamp fields (createdAt and updatedAt) to an object.
17
+ * Adds timestamp fields (createdAt, updatedAt, and/or archivedAt) to an object.
3
18
  *
4
19
  * @param data - The object to add timestamps to
5
- * @param updatedAtDate - Optional custom date for the updatedAt field. Defaults to current date
6
- * @param createdAtDate - Optional custom date for the createdAt field. Defaults to current date
7
- * @returns A new object containing all properties from the input data plus updatedAt and createdAt fields in ISO format
20
+ * @param options - Optional configuration object
21
+ * @param options.fields - Array of timestamp fields to include. Defaults to ['createdAt', 'updatedAt']
22
+ * @param options.dates - Optional custom dates for specific timestamp fields
23
+ * @returns A new object containing all properties from the input data plus the specified timestamp fields in ISO format
8
24
  *
9
25
  * @example
10
26
  * ```ts
11
- * // Add current timestamps
27
+ * // Add current timestamps (default: createdAt and updatedAt)
12
28
  * const result = withTimestamp({ id: 1, name: 'Test' });
13
29
  * // Returns { id: 1, name: 'Test', updatedAt: '2025-10-21T10:00:00.000Z', createdAt: '2025-10-21T10:00:00.000Z' }
14
30
  *
31
+ * // Only add updatedAt when updating data
32
+ * const result = withTimestamp({ id: 1, name: 'Updated' }, { fields: ['updatedAt'] });
33
+ * // Returns { id: 1, name: 'Updated', updatedAt: '2025-10-21T10:00:00.000Z' }
34
+ *
35
+ * // Only add archivedAt when archiving data
36
+ * const result = withTimestamp({ id: 1 }, { fields: ['archivedAt'] });
37
+ * // Returns { id: 1, archivedAt: '2025-10-21T10:00:00.000Z' }
38
+ *
15
39
  * // Use custom dates
16
40
  * const customDate = new Date('2025-01-01');
17
- * const result = withTimestamp({ id: 1 }, customDate, customDate);
41
+ * const result = withTimestamp({ id: 1 }, {
42
+ * fields: ['createdAt', 'updatedAt'],
43
+ * dates: { createdAt: customDate, updatedAt: customDate }
44
+ * });
18
45
  * // Returns { id: 1, updatedAt: '2025-01-01T00:00:00.000Z', createdAt: '2025-01-01T00:00:00.000Z' }
46
+ *
47
+ * // Add all three timestamps
48
+ * const result = withTimestamp({ id: 1 }, { fields: ['createdAt', 'updatedAt', 'archivedAt'] });
49
+ * // Returns { id: 1, createdAt: '...', updatedAt: '...', archivedAt: '...' }
19
50
  * ```
20
51
  */
21
- export declare const withTimestamp: <T extends Record<string, unknown>>(data: T, updatedAtDate?: Date, createdAtDate?: Date) => T & {
22
- updatedAt: string;
23
- createdAt: string;
24
- };
52
+ export declare function withTimestamp<T extends Record<string, unknown>>(data: T, options?: TimestampFieldsOptions): WithTimestampResult<T, ['createdAt', 'updatedAt']>;
53
+ export declare function withTimestamp<T extends Record<string, unknown>, F extends TimestampField[]>(data: T, options: {
54
+ fields: F;
55
+ } & TimestampFieldsOptions): WithTimestampResult<T, F>;
56
+ export {};
25
57
  //# sourceMappingURL=with-timestamp.d.ts.map
@@ -1 +1 @@
1
- const s=(S,t,n)=>{const o=new Date,r=t?t.toISOString():o.toISOString(),i=n?n.toISOString():o.toISOString();return{...S,updatedAt:r,createdAt:i}};export{s as withTimestamp};
1
+ function s(i,n){const d=new Date,a=n?.fields??["createdAt","updatedAt"],c=n?.dates??{},e={...i};if(a.includes("createdAt")){const t=c.createdAt??d;e.createdAt=t.toISOString()}if(a.includes("updatedAt")){const t=c.updatedAt??d;e.updatedAt=t.toISOString()}if(a.includes("archivedAt")){const t=c.archivedAt??d;e.archivedAt=t.toISOString()}return e}export{s as withTimestamp};
@@ -1 +1 @@
1
- import{ServerRoutes as c}from"../../constants/common.js";import{reporter as n}from"../tools/notifiers/reporter.js";import{telemetry as s}from"../telemetry/index.js";import{installDevRoutes as p,installProdRoutes as f}from"./routes/index.js";import{createRouter as v}from"./router.js";import{readStaticAsset as l}from"./node-asset-reader.js";import{startHttpServer as u}from"./http.js";import{listenStore as S}from"./store-ws.js";import{ejectComponentDataHandler as D}from"./routes/eject.js";import{attachWsServer as d}from"./ws.js";import{DatabasePreconnectService as w}from"../providers/database/database-preconnect-service.js";import{KvService as E}from"../persistence/kv/services/kv-service.js";import{runScorecardsWorker as R}from"../plugins/scorecards/workers/run-scorecards-worker.js";import{isCatalogEntitiesEnabled as b}from"../utils/is-catalog-entities-enabled.js";import{isScorecardsEnabled as C}from"../utils/is-scorecards-enabled.js";async function J(r,o,i){s.initialize(!0);const{port:a=4e3}=i,e=v();if(e.get(c.EJECT_COMPONENT,D(r)),p(e,r),f(e,r,{readStaticAsset:l,resolveRouteData:t=>r.resolveRouteStaticData(t,o)}),b()){await w.init(r.serverOutDir);const t=await E.getInstance({baseDbDir:r.serverOutDir});setInterval(()=>t.clearExpired(),300*1e3)}try{await r.userCodeReady;const t=await u(e,a),m=d(t);S(r,m),C(r.config)&&await R(r.serverOutDir)}catch(t){await n.panic(t)}}export{J as startDevServer};
1
+ import{ServerRoutes as c}from"../../constants/common.js";import{reporter as n}from"../tools/notifiers/reporter.js";import{telemetry as s}from"../telemetry/index.js";import{installDevRoutes as p,installProdRoutes as f}from"./routes/index.js";import{createRouter as v}from"./router.js";import{readStaticAsset as l}from"./node-asset-reader.js";import{startHttpServer as u}from"./http.js";import{listenStore as S}from"./store-ws.js";import{ejectComponentDataHandler as d}from"./routes/eject.js";import{attachWsServer as D}from"./ws.js";import{DatabasePreconnectService as w}from"../providers/database/database-preconnect-service.js";import{KvService as E}from"../persistence/kv/services/kv-service.js";import{runScorecardsWorker as R}from"../plugins/scorecards/workers/run-scorecards-worker.js";import{isCatalogEntitiesEnabled as b}from"../utils/is-catalog-entities-enabled.js";import{isScorecardsEnabled as g}from"../utils/is-scorecards-enabled.js";async function J(r,o,i){s.initialize(!0);const{port:a=4e3}=i,e=v();if(e.get(c.EJECT_COMPONENT,d(r)),p(e,r),f(e,r,{readStaticAsset:l,resolveRouteData:t=>r.resolveRouteStaticData(t,o)}),b()){await w.init(r.serverOutDir);const t=await E.getInstance({baseDbDir:r.serverOutDir});setInterval(()=>t.clearExpired(),300*1e3)}try{await r.userCodeReady;const t=await u(e,a),m=D(t);S(r,m),g(r.config)&&await R(r.serverOutDir,r.config.scorecards)}catch(t){await n.panic(t)}}export{J as startDevServer};
@@ -1 +1 @@
1
- import{logger as n}from"../tools/notifiers/logger.js";import{runApiRoutesWorker as o}from"../api-routes/run-api-routes-worker.js";import{runMcpWorker as m}from"../plugins/mcp/workers/run-api-routes-worker.js";import{MCP_DOCS_SERVER_HANDLER_ID as i}from"../plugins/mcp/index.js";async function f(t,s,a){try{const e=n.startTiming(),r=t.requestHandlerId===i?await m(t,s,a):await o(t,s,a);return n.infoTime(e,`API request handled "${new URL(s.req.url).pathname}" with status "${r.status}" and content type "${r.headers?.get("content-type")}"`),r.headers.set("X-Source","REALM_API_FUNCTION"),r}catch(e){return n.error(`[${t.requestHandlerId}] ${e.stack}`),e.name==="RequestBodySizeLimitError"?s.json({message:e.message},{status:413}):e.name==="ResponseSizeLimitError"?s.json({message:e.message},{status:500}):e.name==="MemoryUsageLimitError"?s.json({message:e.message},{status:502}):e.name==="TimeoutExceededError"?s.json({message:e.message},{status:504}):process.env.NODE_ENV==="development"?s.json({message:e.message},{status:500}):s.json({message:"Internal server error"},{status:500})}}export{f as handleApiRouteRequest};
1
+ import{logger as n}from"../tools/notifiers/logger.js";import{runApiRoutesWorker as o}from"../api-routes/run-api-routes-worker.js";import{MCP_DOCS_SERVER_HANDLER_ID as m}from"../plugins/mcp/index.js";import{handleMcpRequest as i}from"../plugins/mcp/handlers/handle-mcp-request.js";async function f(t,s,a){try{const e=n.startTiming(),r=t.requestHandlerId===m?await i(t,s,a):await o(t,s,a);return n.infoTime(e,`API request handled "${new URL(s.req.url).pathname}" with status "${r.status}" and content type "${r.headers?.get("content-type")}"`),r.headers.set("X-Source","REALM_API_FUNCTION"),r}catch(e){return n.error(`[${t.requestHandlerId}] ${e.stack}`),e.name==="RequestBodySizeLimitError"?s.json({message:e.message},{status:413}):e.name==="ResponseSizeLimitError"?s.json({message:e.message},{status:500}):e.name==="MemoryUsageLimitError"?s.json({message:e.message},{status:502}):e.name==="TimeoutExceededError"?s.json({message:e.message},{status:504}):process.env.NODE_ENV==="development"?s.json({message:e.message},{status:500}):s.json({message:"Internal server error"},{status:500})}}export{f as handleApiRouteRequest};
@@ -0,0 +1,4 @@
1
+ import { WorkerPool } from './worker-pool.js';
2
+ export declare const MCP_TOOL_WORKER_KEY = "executeMcpTool";
3
+ export declare const mcpToolWorkers: WorkerPool;
4
+ //# sourceMappingURL=mcp-tool-worker-pool.d.ts.map
@@ -0,0 +1 @@
1
+ import{getAllowedEnvs as o}from"../utils/envs/get-api-route-allowed-env-variables.js";import{WorkerPool as r}from"./worker-pool.js";const s="executeMcpTool",e=5,c=new r({workerScript:"./mcp-tool-worker",minWorkers:1,maxWorkers:e,workerType:"process",forkOpts:{env:{...o()},stdio:"inherit"},lazy:!0});export{s as MCP_TOOL_WORKER_KEY,c as mcpToolWorkers};
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-tool-worker.d.ts.map
@@ -0,0 +1 @@
1
+ import o from"workerpool";import{executeMcpTool as r}from"../plugins/mcp/workers/execute-mcp-tool.js";import{MCP_TOOL_WORKER_KEY as m}from"./mcp-tool-worker-pool.js";o.worker({[m]:r});
@@ -1,9 +1,11 @@
1
1
  import type { ApiRoutesWorkerParams, ApiRoutesWorkerResponse } from '../types/plugins/api-routes.js';
2
2
  import type { RenderPayload } from '../../types/ssr.js';
3
3
  import type { ScorecardsWorkerParams, ScorecardsWorkerResponse } from '../plugins/scorecards/workers/scorecards.js';
4
+ import type { McpToolWorkerParams, McpToolWorkerResponse } from '../plugins/mcp/types.js';
4
5
  import type { SCORECARDS_WORKER_KEY } from './scorecards-worker-pool.js';
5
6
  import type { API_ROUTES_WORKER_KEY } from './api-routes-worker-pool.js';
6
7
  import type { SSR_WORKER_KEY } from './ssr-worker-pool.js';
8
+ import type { MCP_TOOL_WORKER_KEY } from './mcp-tool-worker-pool.js';
7
9
  export type SsrWorkerResponse = {
8
10
  html: string;
9
11
  statusCode: 200 | 500;
@@ -22,6 +24,10 @@ export type WorkerTypeMapping = {
22
24
  params: [ScorecardsWorkerParams];
23
25
  response: ScorecardsWorkerResponse;
24
26
  };
27
+ [MCP_TOOL_WORKER_KEY]: {
28
+ params: [McpToolWorkerParams];
29
+ response: McpToolWorkerResponse;
30
+ };
25
31
  };
26
32
  export type WorkerParams<T extends keyof WorkerTypeMapping> = WorkerTypeMapping[T]['params'];
27
33
  export type WorkerResponse<T extends keyof WorkerTypeMapping> = WorkerTypeMapping[T]['response'];
@@ -1 +1 @@
1
- const e=()=>process.env.REDOCLY_ENV==="local";export{e as isLocalDevelopment};
1
+ const e=()=>process.env.REDOCLY_ENV==="local"||process.env.REDOCLY_LOCAL_DEV==="true";export{e as isLocalDevelopment};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/revel",
3
- "version": "0.130.0-next.3",
3
+ "version": "0.130.0-next.5",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,8 +31,8 @@
31
31
  "@opentelemetry/sdk-trace-node": "2.0.1",
32
32
  "@opentelemetry/sdk-trace-web": "2.0.1",
33
33
  "@opentelemetry/semantic-conventions": "1.34.0",
34
- "@redocly/ajv": "8.17.1",
35
- "@redocly/openapi-core": "2.14.5",
34
+ "@redocly/ajv": "8.17.2",
35
+ "@redocly/openapi-core": "2.14.7",
36
36
  "@shikijs/transformers": "3.21.0",
37
37
  "@tanstack/react-query": "5.62.3",
38
38
  "@tanstack/react-table": "8.21.3",
@@ -93,14 +93,14 @@
93
93
  "xml-crypto": "6.0.1",
94
94
  "xpath": "0.0.34",
95
95
  "yaml-ast-parser": "0.0.43",
96
- "@redocly/asyncapi-docs": "1.7.0-next.2",
96
+ "@redocly/asyncapi-docs": "1.7.0-next.4",
97
97
  "@redocly/config": "0.41.2",
98
98
  "@redocly/graphql-docs": "1.7.0-next.0",
99
- "@redocly/openapi-docs": "3.18.0-next.2",
99
+ "@redocly/openapi-docs": "3.18.0-next.4",
100
100
  "@redocly/portal-legacy-ui": "0.13.0-next.0",
101
- "@redocly/portal-plugin-mock-server": "0.15.0-next.2",
101
+ "@redocly/portal-plugin-mock-server": "0.15.0-next.4",
102
102
  "@redocly/realm-asyncapi-sdk": "0.8.0-next.1",
103
- "@redocly/theme": "0.62.0-next.1"
103
+ "@redocly/theme": "0.62.0-next.3"
104
104
  },
105
105
  "peerDependencies": {
106
106
  "react": "19.2.3",
@@ -1,5 +0,0 @@
1
- import type { Context } from 'hono';
2
- import type { ApiRoute } from '../../../types';
3
- import type { Store } from '../../../store.js';
4
- export declare function runMcpWorker(route: ApiRoute, ctx: Context, store: Store): Promise<Response>;
5
- //# sourceMappingURL=run-api-routes-worker.d.ts.map
@@ -1 +0,0 @@
1
- import*as u from"workerpool";import{withPathPrefix as d}from"@redocly/theme/core/utils";import{TimeoutExceededError as p}from"../../../api-routes/errors/timeout-exceeded.js";import{serializeRequest as l}from"../../../api-routes/helpers/serialize-request.js";import{API_ROUTES_WORKER_KEY as f}from"../../../workers/api-routes-worker-pool.js";import{mcpWorkers as h}from"../../../workers/mcp-worker-pool.js";const w=15;async function A(o,a,t){const e=a.get("auth"),i=await t.resolveRouteStaticData(o)||{},s=d(o.slug);try{const{status:r,headers:m,body:c}=await h.exec(f,[{serverOutDir:t.serverOutDir,slug:s,requestHandlerId:o.requestHandlerId,maxResponseSizeMB:w,ctxData:{user:{teams:e.teams,email:e.claims.email,claims:e.claims,idpAccessToken:e.idpAccessToken,idpId:e.claims.idpId,isAuthenticated:e.isAuthenticated},config:t.config},staticData:{...i,props:{...i.props,routeSlug:s,outdir:t.outdir}},req:await l(a.req.raw)}]),n=c.data?Buffer.from(c.data):null;return new Response(n,{status:r,headers:m})}catch(r){throw r instanceof u.Promise.TimeoutError?new p("Timeout exceeded"):r}}export{A as runMcpWorker};
@@ -1,4 +0,0 @@
1
- import { WorkerPool } from './worker-pool.js';
2
- export declare const API_ROUTES_WORKER_KEY = "executeApiRoute";
3
- export declare const mcpWorkers: WorkerPool;
4
- //# sourceMappingURL=mcp-worker-pool.d.ts.map
@@ -1 +0,0 @@
1
- import{getAllowedEnvs as r}from"../utils/envs/get-api-route-allowed-env-variables.js";import{WorkerPool as o}from"./worker-pool.js";const p="executeApiRoute",e=5,i=new o({workerScript:"./api-routes-worker",minWorkers:1,maxWorkers:e,workerType:"process",forkOpts:{env:{...r()},stdio:"inherit"},lazy:!0});export{p as API_ROUTES_WORKER_KEY,i as mcpWorkers};