@redocly/redoc-reef 0.139.0-next.8 → 0.139.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.
- package/CHANGELOG.md +226 -0
- package/dist/cli/develop.js +1 -1
- package/dist/cli/eject/resolveEjectParams.js +1 -1
- package/dist/client/app/Sidebar/PoweredByRedocly.d.ts +14 -0
- package/dist/client/app/Sidebar/PoweredByRedocly.js +40 -0
- package/dist/client/app/Sidebar/Sidebar.js +3 -3
- package/dist/client/app/hooks/useL10nConfig.d.ts +1 -0
- package/dist/client/app/markdoc/custom-components/openapi/replay-openapi.js +1 -1
- package/dist/client/app/utils/programmatic-scroll.js +1 -1
- package/dist/client/app/webmcp/tools/api-tools.js +1 -1
- package/dist/client/app/webmcp/tools/site-tools.js +2 -2
- package/dist/client/app/webmcp/useWebMcpTools.js +1 -1
- package/dist/client/browser-entry.js +2 -2
- package/dist/client/templates/api-docs/template.js +5 -3
- package/dist/constants/common.d.ts +2 -0
- package/dist/constants/common.js +1 -1
- package/dist/constants/l10n/langs/ar.js +1 -1
- package/dist/constants/l10n/langs/de.js +1 -1
- package/dist/constants/l10n/langs/en.js +1 -1
- package/dist/constants/l10n/langs/es.js +1 -1
- package/dist/constants/l10n/langs/fr.js +1 -1
- package/dist/constants/l10n/langs/hi.js +1 -1
- package/dist/constants/l10n/langs/it.js +1 -1
- package/dist/constants/l10n/langs/ja.js +1 -1
- package/dist/constants/l10n/langs/ko.js +1 -1
- package/dist/constants/l10n/langs/pl.js +1 -1
- package/dist/constants/l10n/langs/pt-BR.js +1 -1
- package/dist/constants/l10n/langs/pt.js +1 -1
- package/dist/constants/l10n/langs/ru.js +1 -1
- package/dist/constants/l10n/langs/uk.js +1 -1
- package/dist/constants/l10n/langs/zh.js +1 -1
- package/dist/server/constants/entitlements.d.ts +2 -2
- package/dist/server/constants/entitlements.js +1 -1
- package/dist/server/entitlements/entitlements-provider.d.ts +8 -2
- package/dist/server/entitlements/entitlements-provider.js +1 -1
- package/dist/server/entitlements/is-valid-plan.d.ts +2 -2
- package/dist/server/entitlements/is-valid-plan.js +1 -1
- package/dist/server/fs/content-fs.js +1 -1
- package/dist/server/fs/utils/external-ref-resolver.js +2 -2
- package/dist/server/fs/utils/is-translation-fallback.d.ts +9 -0
- package/dist/server/fs/utils/is-translation-fallback.js +1 -0
- package/dist/server/node-bundle-entry.js +1 -1
- package/dist/server/plugins/api-docs/get-server-props.js +1 -1
- package/dist/server/plugins/api-docs/index.js +1 -1
- package/dist/server/plugins/api-docs/loader.js +3 -3
- package/dist/server/plugins/api-docs/search/get-ai-search-documents.d.ts +6 -3
- package/dist/server/plugins/api-docs/search/get-ai-search-documents.js +52 -52
- package/dist/server/plugins/api-docs/utils/inject-metadata.d.ts +19 -0
- package/dist/server/plugins/api-docs/utils/inject-metadata.js +1 -0
- package/dist/server/plugins/catalog-entities/template/index.js +1 -1
- package/dist/server/plugins/config-parser/index.js +1 -1
- package/dist/server/plugins/config-parser/loaders/versions-config-loader.js +1 -1
- package/dist/server/plugins/default-theme/resolve-logo.js +1 -1
- package/dist/server/plugins/dev-onboarding/api/routes/products.js +1 -1
- package/dist/server/plugins/l10n/index.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-json-example-ref.js +1 -1
- package/dist/server/plugins/markdown/attribute-resolvers/resolve-link.js +1 -1
- package/dist/server/plugins/markdown/get-server-props.js +1 -1
- package/dist/server/plugins/markdown/markdoc/resolve-raw-partials.js +1 -1
- package/dist/server/plugins/markdown/markdown-static-data-loader.js +1 -1
- package/dist/server/plugins/markdown/read-file-content.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/allowed-http-methods.d.ts +0 -5
- package/dist/server/plugins/mcp/gateway-mcp/allowed-http-methods.js +1 -1
- package/dist/server/plugins/mcp/gateway-mcp/caller-api-calls.d.ts +3 -4
- package/dist/server/plugins/mcp/gateway-mcp/caller-api-calls.js +1 -1
- package/dist/server/plugins/nav-utils.js +1 -1
- package/dist/server/providers/database/has-project-database.js +1 -1
- package/dist/server/store.d.ts +3 -1
- package/dist/server/store.js +1 -1
- package/dist/server/types/index.d.ts +1 -0
- package/dist/server/types/plugins/markdown.d.ts +1 -0
- package/dist/server/types/static-files.d.ts +6 -0
- package/dist/server/types/static-files.js +0 -0
- package/dist/server/utils/content/build-static-file-paths.d.ts +15 -0
- package/dist/server/utils/content/build-static-file-paths.js +1 -0
- package/dist/server/utils/find-disallowed-packages.d.ts +16 -0
- package/dist/server/utils/find-disallowed-packages.js +1 -0
- package/dist/server/utils/is-realm-or-reef.js +1 -1
- package/dist/server/utils/lifecycle-hooks.js +1 -1
- package/dist/server/utils/rbac-expand.d.ts +4 -0
- package/dist/server/utils/rbac-expand.js +1 -1
- package/dist/server/utils/rbac.js +1 -1
- package/dist/server/utils/redirects/find-redirect.d.ts +4 -3
- package/dist/server/utils/redirects/find-redirect.js +1 -1
- package/dist/server/utils/resolve-asset-path.js +1 -1
- package/dist/server/utils/validate-allowed-packages.d.ts +7 -0
- package/dist/server/utils/validate-allowed-packages.js +2 -0
- package/dist/server/web-server/auth.d.ts +2 -0
- package/dist/server/web-server/auth.js +3 -3
- package/dist/server/web-server/jwt/jwt.js +1 -1
- package/dist/server/web-server/middleware/catalogAuthMiddleware.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-client-metadata.d.ts +3 -3
- package/dist/server/web-server/routes/mcp-routes/mcp-client-metadata.js +1 -1
- package/dist/server/web-server/routes/mcp-routes/mcp-oauth.js +1 -1
- package/dist/types/entitlements.d.ts +10 -1
- package/dist/types/global-data.d.ts +4 -0
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as
|
|
1
|
+
import g from"path";import{DEFAULT_LOCALE_PLACEHOLDER as d,TRANSLATIONS_FILE_NAME as h}from"../../../constants/common.js";import{I18N_DIR_NAME as y,L10N_DIR_NAME as w}from"../../constants/common.js";import{logger as m}from"../../tools/notifiers/logger.js";import{reporter as A}from"../../tools/notifiers/reporter.js";import{EntitlementsProvider as N}from"../../entitlements/entitlements-provider.js";import{isL10nPath as O}from"../../fs/utils/is-l10n-path.js";import{isOpenapiDoc as E}from"../api-docs/utils/is-api-doc.js";import{telemetryTraceStep as I}from"../../../cli/telemetry/helpers/trace-step.js";async function $(){return{id:"l10n",async processContent(n,e){await I("com.redocly.build.plugin.l10n",async a=>{const{fs:t,cache:c,getConfig:r}=e,i={},p=N.instance(),l=await r();a?.setAttribute("config",JSON.stringify(l.l10n||{}));const s=l.l10n?.defaultLocale||d;if(p.canAccessFeature("l10n")){await F(e);for(const{relativePath:o}of t.scan(/(?:^|[/\\])translations\.yaml$/)){const u=await c.load(o,"yaml"),L=P(o)||s;i[L]={translation:u.data||{}}}}i[s]={translation:{...i[s]?.translation||{}}};const f=l.l10n?.locales||[d,...t.localeFolders].map(o=>({code:o.toLowerCase(),name:o}));a?.setAttribute("locales",JSON.stringify(f)),n.setGlobalData({l10n:{translations:i,defaultLocale:s,locales:f.map(o=>({code:o.code,name:o.name||o.code,showMissingTranslationNotice:o.showMissingTranslationNotice}))}})})}}}function P(n){return n.indexOf("/")>0?n.split("/")[1]:void 0}async function F(n){const e=n.fs.scan();for(const{isVirtual:a,realRelativePath:t}of e){if(a)continue;if(O(t)&&t.endsWith(".page.tsx")&&await A.panicOnBuild(`The file %rp is not allowed in ${w} or ${y} folders`,t),g.posix.basename(t)===h){const r=/^(?:@(i18n|l10n)[/\\][^/\\]+[/\\])?translations\.yaml$/.test(t),i=await E(t,n);!r&&!i&&m.warn("The file %rp is in the wrong location. Make sure it is located in the root directory or in the locale root directory.",t),r&&i&&m.warn("It looks like the file %rp might be an OpenAPI definition and is located in a location reserved for translation files. Please rename it or move to another directory if it is not a translations file",t)}}}export{$ as l10nPlugin};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{JsonPointer as
|
|
1
|
+
import{JsonPointer as d}from"@redocly/api-docs";import{isObject as u}from"../../../../utils/guards/is-object.js";import{getNodeAttribute as w}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as s}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{MdResolveError as p}from"./md-resolve-error.js";import{resolvePathInMarkdown as $}from"../resolve-path-in-markdown.js";async function b(e,o,m,{context:n,actions:h}){const r=w(e,o);try{if(!u(r)||typeof r.$ref!="string"){try{JSON.stringify(r)}catch(i){throw new Error(`Invalid JSON value: ${i.message}`)}s(e,o+"Resolved",r);return}const[t,f]=r.$ref.split("#");if(!t)throw new Error(`Invalid $ref. Path to file is required: ${r.$ref}`);const l=$(t,m,h.contentDir),c=n.fs.getFileInfo(l);if(!c)throw new Error(`Invalid $ref. No such file: ${l}`);let a;try{a=(await n.cache.load(c.realRelativePath,"yaml")).data}catch(i){throw new Error(`Invalid file format. File must be valid json or yaml: ${l} ${i?.message||""}`)}if(!f){s(e,o+"Resolved",a);return}const v=d.get(a,f);s(e,o+"Resolved",v)}catch(t){throw s(e,o+"ResolvedErrors",[t.message]),new p(t.message,{rawLink:""})}}export{b as resolveJsonExampleRef};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import l from"node:path";import{API_DOCS_TEMPLATE_ID as O,ASYNC_API_DOCS_TEMPLATE_ID as y,GRAPHQL_TEMPLATE_ID as M,OPENAPI_DOCS_TEMPLATE_ID as U}from"../../../../constants/common.js";import{isLocalLink as C}from"../../../../utils/path/is-local-link.js";import{normalizeRouteSlug as P}from"../../../../utils/path/normalize-route-slug.js";import{removeFragment as B}from"../../../../utils/path/remove-fragment.js";import{getInnerText as W}from"../../../../markdoc/helpers/get-inner-text.js";import{getNodeAttribute as j}from"../../../../markdoc/helpers/get-node-attribute.js";import{setNodeAttributeValue as p}from"../../../../markdoc/helpers/set-node-attribute-value.js";import{isAuthRoutePath as $}from"../../../../utils/auth/is-auth-route-path.js";import{isApiDownloadLink as b}from"../../../utils/is-api-download-link.js";import{isTranslationFallback as V}from"../../../fs/utils/is-translation-fallback.js";import{removeL10nPrefix as z}from"../../../fs/utils/remove-l10n-prefix.js";import{MdResolveError as A}from"./md-resolve-error.js";import{getLinkOriginalAttrName as G}from"./utils.js";import{isOpenApiURL as N}from"../../api-docs/utils/is-api-doc.js";import{parseBaseName as q}from"../../utils.js";import{isMarkdownPage as H}from"../is-markdown-page.js";import{copyStaticFile as K}from"../../../utils/fs.js";async function ht(i,s,u,{actions:I,context:m}){const{contentDir:T,outdir:v,getRouteByFsPath:d,getRouteBySlug:k,hasRouteOrRedirectBySlug:w}=I,x=G(s),o=i[x]||j(i,s);if(i[x]=o,!C(o)||b(o)||$(o))return;const[Q,t="",R,L]=/^([^?#]+)?([^#]+)?(.+)?/.exec(o)||[],g=i.type==="image"?"IMAGE":"LINK",h=String(i.attributes.title||i.attributes.alt||W([i])||""),c=B(u);if(i.type!=="image"){const{isOpenapiDetected:e,isOpenapiValid:r}=await N(t,c,I,m);if(e&&!r)throw new A(`OpenAPI route ${o} does not exist`,{rawLink:o,link:t,title:h,brokenLinkType:g})}if(l.extname(t)===""){if(t.startsWith("/")){const e=P(t),r=w(e)?t:_(e,k);if(!r)throw new A(`Route ${t} does not exist`,{rawLink:o,link:t,title:h,brokenLinkType:g});p(i,s,r+(R||"")+(L||""))}if(!o.startsWith("#")&&!t.startsWith("/")&&H(c)){const e=d(c)?.slug;if(!e)return;const{isIndexFile:r}=q(c),a=r?P(l.posix.join(e,t)):P(l.posix.join(e,"../",t)),E=w(P(a))?a:_(a,k);if(!E)throw new A(`Route ${t} does not exist`,{rawLink:o,link:a,title:h,brokenLinkType:g});p(i,s,E+(R||"")+(L||""))}return}const n=t.startsWith("/")?t.substring(1):l.posix.join(l.posix.dirname(c),decodeURI(t)),D=t.startsWith("/")?l.posix.join("static",t.substring(1)):"",S=m.fs.exists(n),F=m.fs.exists(D),f=d(n);if(!S&&!f&&!F)throw p(i,s,"#"),new A(`File ${n} does not exist`,{rawLink:o,link:n,title:h,brokenLinkType:g});if(f){const e=[U,M,y].includes(f.templateId);p(i,s,(e?f.baseSlug:f.slug)+(L||""))}else if(S){const e=m.fs.getFileInfo(n),r=V(e)?m.fs.getFileInfo(z(n)):e;if(!r||r.isVirtual)return;const a=await K(T,r.realRelativePath,v);p(i,s,a)}}function _(i,s){const u=s(i.toLowerCase());return u?.templateId===O?u.slug:void 0}export{ht as resolveLink};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e from"@markdoc/markdoc";import{getPublicEnvVariables as u}from"../../utils/envs/get-public-env-variables.js";import{transformMdAst as i}from"./runtime-transform";const v=async(A,o,t,s)=>{const{ast:l,frontmatter:r,props:n,editPage:f,lastModified:m,isTranslationFallback:b}=o,{headings:d,renderableAst:p}=await i(e.Ast.fromJSON(l),{partials:t.partials,variables:{frontmatter:r,...t.variables,env:u()}},s.serverOutDir);return Array.isArray(r.banner)&&(r.banner=await Promise.all(r.banner.map(async a=>{if(a.ast){const{renderableAst:c}=await i(e.Ast.fromJSON(a.ast),{partials:{},variables:{}},s.serverOutDir);return{...a,ast:c}}return a}))),{...n,ast:p,headings:d,frontmatter:r,editPage:f,lastModified:m,...b?{isTranslationFallback:!0}:{}}};var k=v;export{k as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import p from"node:path";import _ from"is-glob";import{slash as $}from"../../../../utils/path/slash.js";import{reporter as d}from"../../../tools/notifiers/reporter.js";import{convertGlobToRegex as h}from"../../../utils/index.js";import{formatMarkdocError as k}from"../errors.js";import{isPartial as E}from"../is-partial.js";const b=/\{% ?raw-partial file="([^"]+)" ?\/?%\}/gm,y=async(t,a,i=[],o,l=[a])=>{for(const s of i){const r=_(s)?h(s):new RegExp(`^${s}/`);
|
|
1
|
+
import p from"node:path";import _ from"is-glob";import{slash as $}from"../../../../utils/path/slash.js";import{reporter as d}from"../../../tools/notifiers/reporter.js";import{convertGlobToRegex as h}from"../../../utils/index.js";import{formatMarkdocError as k}from"../errors.js";import{isPartial as E}from"../is-partial.js";const b=/\{% ?raw-partial file="([^"]+)" ?\/?%\}/gm,y=async(t,a,i=[],o,l=[a])=>{for(const s of i){const r=_(s)?h(s):new RegExp(`^${s}/`);o.fs.scan(r)}const n=[],f=t.replace(b,(s,r)=>(n.push(u(s,r)),"_$redocly$"+(n.length-1)+"$")),w=await Promise.all(n);return f.replace(/_\$redocly\$(\d+)\$/g,(s,r)=>w[+r]);async function u(s,r){const e=r.startsWith("/")?r.slice(1):$(p.relative(o.fs.cwd,p.resolve(o.fs.cwd,p.dirname(a),r)));if(l.includes(e)){const c=[...l,e];return await d.panicOnBuildContentError(`Circular reference chain detected when processing raw partials: ${c.map(()=>"%rp").join(" -> ")}`,...c),""}const m=!o.fs.exists(e),g=!e.endsWith(".md")||await o.isPathIgnored(e)||!E(e,i);if(m||g){const R={type:"resolve_link",lines:[1,t.split(`
|
|
2
2
|
`).length],meta:{rawLink:r,link:e},error:{id:"error",level:"error",message:m?"Raw partial file does not exist":"Could not resolve raw partial. Starting with 0.73.0 version all partials should be placed in partials folders"}};return d.reportMarkdocProblem(k(R,a,t)),""}const v=await o.fs.read(e);return await y(v,e,i,o,[...l,e])}};export{y as resolveRawPartials};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import D from"path";import{REDOCLY_TEAMS_RBAC as
|
|
1
|
+
import D from"path";import{REDOCLY_TEAMS_RBAC as m,REDOCLY_ROUTE_RBAC as A}from"@redocly/config";import{removeTrailingSlash as F}from"../../../utils/url/remove-trailing-slash.js";import{addLeadingSlash as M}from"../../../utils/url/add-leading-slash.js";import{shaHexShort as N}from"../../utils/crypto/sha-hex-short.js";import{isDefined as E}from"../../../utils/guards/is-defined.js";import{isTranslationFallback as I}from"../../fs/utils/is-translation-fallback.js";import{resolveFrontmatterKeys as L}from"../resolve-frontmatter-keys.js";import{resolveItem as _}from"../nav-utils.js";const R=new WeakMap;async function z(n,i,s,e,a){const l=await s.getConfig(),{ast:d,compoundHash:t,info:g}=await a.parseMarkdoc({input:n,context:s}),r={...l.markdown?.editPage,...e.markdown?.editPage},o=i.fsPath!=null?s.fs.getFileInfo(i.fsPath):null,f=!r?.hide&&r?.baseUrl?{to:F(r.baseUrl)+M(o?.realRelativePath||i.fsPath||"")}:void 0,v={...l.feedback,...e.feedback},w=e.feedback?{type:v.type||"sentiment",settings:v.settings||{},hide:e.feedback?.hide}:void 0;let h;Array.isArray(e.banner)&&(h=(await Promise.all(e.banner.map(async(T,B)=>{const{content:k,...b}=T;if(!k)return;const{ast:O}=await a.parseMarkdoc({input:{content:k,relativePath:n.relativePath,isVirtual:n.isVirtual},context:s,resource:`${n.relativePath}#banner${B}`});return{...b,...b.rbac?{[m]:b.rbac}:{},ast:JSON.stringify(O),hash:N(k)}}))).filter(E));const y=R.get(d);let c=y?.ast;(!c||y?.compoundHash!==t)&&(c=JSON.stringify(d),R.set(d,{ast:c,compoundHash:t}));let p;e.navigation&&(p={...e.navigation,nextButton:await S(e.navigation.nextButton,i,a,s),previousButton:await S(e.navigation.previousButton,i,a,s)});const u=e?.seo?await L(e.seo,["image"],i.fsPath||"",a,s):void 0,P=g.tagList;Array.isArray(P)&&P.includes("code-walkthrough")&&(e.markdown=e.markdown||{},e.markdown.toc={hide:!0},e.footer=e.footer||{},e.footer={hide:!0});const C=e?.seo?.title||await i.getNavText?.();return{ast:c,frontmatter:await L({...e,...w!==void 0?{feedback:w}:{},...u!==void 0?{seo:u}:{},...p!==void 0?{navigation:p}:{},...h!==void 0?{banner:h}:{}},l.markdown?.frontMatterKeysToResolve||["image","links"],i.fsPath||"",a,s),editPage:f,...I(n)?{isTranslationFallback:!0}:{},props:{metadata:{markdoc:{tagList:g.tagList}},seo:{...u,...C?{title:C}:{}}},[m]:i[m],[A]:i[A]}}async function S(n,i,s,e){if(!n||typeof n!="object")return;let a=n,l,d;if("page"in a&&typeof a.page=="string"){const{page:o,...f}=a;a=f,l=o}if("label"in a&&typeof a.label=="string"){const{label:o,...f}=a;a=f,d=o}let t;if(l){const o=await _({page:l},i.fsPath?D.dirname(i.fsPath):".",s,e,{navFile:i.fsPath||""});t=Array.isArray(o)?o[0]:o,t=t?.type!=="error"?t:void 0}const g=t?.routeSlug,r=d??t?.label;return{...a,label:r,link:g}}export{z as markdownStaticDataLoader};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{reporter as
|
|
1
|
+
import{reporter as e}from"../../tools/notifiers/reporter.js";async function o(r,n){return n.exists(r)?n.read(r):(await e.panicOnBuildContentError(`File ${r} does not exist`),null)}export{o as readFileContent};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import type { RedoclyConfig } from '@redocly/config';
|
|
2
|
-
export type ApiCallsConfig = NonNullable<NonNullable<RedoclyConfig['mcp']>['apiCalls']>;
|
|
3
|
-
type ApiCallsHttpMethod = NonNullable<ApiCallsConfig['allowedHttpMethods']>[number];
|
|
4
|
-
/** The methods agents may send when `mcp.apiCalls.allowedHttpMethods` is not set. */
|
|
5
|
-
export declare const DEFAULT_ALLOWED_HTTP_METHODS: readonly ApiCallsHttpMethod[];
|
|
6
2
|
/** Upper-case HTTP methods agents may send; read-only unless `redocly.yaml` allows more. */
|
|
7
3
|
export declare function getAllowedHttpMethods(mcp: RedoclyConfig['mcp'] | undefined): string[];
|
|
8
4
|
/** Whether every allowed method is safe by HTTP semantics (`GET`, `HEAD`, `OPTIONS`). */
|
|
9
5
|
export declare function allowsOnlySafeHttpMethods(mcp: RedoclyConfig['mcp'] | undefined): boolean;
|
|
10
|
-
export {};
|
|
11
6
|
//# sourceMappingURL=allowed-http-methods.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const o=["GET","HEAD","OPTIONS"],r={GET:!0,HEAD:!0,OPTIONS:!0};function T(t){return(t?.apiCalls?.allowedHttpMethods??o).map(e=>e.toUpperCase())}function
|
|
1
|
+
const o=["GET","HEAD","OPTIONS"],r={GET:!0,HEAD:!0,OPTIONS:!0};function T(t){return(t?.apiCalls?.allowedHttpMethods??o).map(e=>e.toUpperCase())}function l(t){return T(t).every(e=>r[e])}export{l as allowsOnlySafeHttpMethods,T as getAllowedHttpMethods};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { RedoclyConfig } from '@redocly/config';
|
|
2
2
|
/**
|
|
3
|
-
* `mcp` with
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the project's methods turns API calls off.
|
|
3
|
+
* `mcp` with API calls turned off when the caller's `metadata.apiCalls.hide` is `true`: the AI
|
|
4
|
+
* Assistant sends it when the host page of its web component runs the API calls itself. The caller
|
|
5
|
+
* can only take API calls away; a value of another shape changes nothing.
|
|
7
6
|
*/
|
|
8
7
|
export declare function narrowMcpConfigForCaller(mcp: RedoclyConfig['mcp'], metadata: Record<string, unknown> | undefined): RedoclyConfig['mcp'];
|
|
9
8
|
//# sourceMappingURL=caller-api-calls.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
function i(e,t){const r=t?.apiCalls;return!r||typeof r!="object"||r.hide!==!0?e:{...e,apiCalls:{...e?.apiCalls,hide:!0}}}export{i as narrowMcpConfigForCaller};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as v from"path";import{REDOCLY_ROUTE_RBAC as b,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import{VERSION_SEPARATOR as M}from"../constants/common.js";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../constants/common.js";import{removeTrailingSlash as j}from"../../utils/url/remove-trailing-slash.js";import{isPrimitive as W}from"../../utils/guards/is-primitive.js";import{slash as w}from"../../utils/path/slash.js";import{isAbsoluteUrl as z}from"../../utils/url/is-absolute-url.js";import{normalizeRouteSlug as J}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as C}from"../../utils/path/parse-path-versions.js";import{logger as A}from"../tools/notifiers/logger.js";import{reporter as S}from"../tools/notifiers/reporter.js";import{shaDirPathShort as R}from"../utils/crypto/sha-dir-path-short.js";import{copyStaticFile as U,FileNotFoundError as E}from"../utils/fs.js";import{isIconPath as H,resolveAssetPath as Y}from"../utils/index.js";import{resolveSrcSet as G}from"../utils/resolve-src-set.js";import{isL10nPath as B}from"../fs/utils/is-l10n-path.js";import{getLocaleFromRelativePath as q}from"../fs/utils/get-locale-from-relative-path.js";async function N(e,i,n,t,a){if(!e)return;const f={...a,ignoreCustomSidebar:!0};if(W(e)){if(typeof e=="string"){const r=F(n.contentDir,i,a,e,t.fs);if(t.fs.exists(r)){if(n.getRouteByFsPath(r))return K({page:e},i,n,t,f);{const g=t.fs.getFileInfo(r);return g?U(n.contentDir,g.realRelativePath,n.outdir):void 0}}}return e}return Array.isArray(e)?I(D(e),i,n,t,f):Object.fromEntries(await Promise.all(Object.entries(e).map(async([r,l])=>[r,await N(l,i,n,t,a)])))}function D(e){return e.map(i=>({...i,items:i.items?D(i.items):void 0}))}async function I(e,i,n,t,a){if(Array.isArray(e))return(await Promise.all(e.map(f=>K(f,i,n,t,a)))).flatMap(f=>f)}async function y(e,i,n,t){let a,f;if(typeof e.icon=="object"){if("srcSet"in e.icon)try{a=await G(e.icon.srcSet,n.fs,{fromFileRelativePath:t.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`):await S.panicOnBuild(`Cannot resolve "item.icon.srcSet" from ${t.navFile}: ${d.message}`)}}else if(typeof e.icon=="string")if(z(e.icon)||H(e.icon))try{f=await Y(e.icon,n.fs,{fromFileRelativePath:t.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof E?await S.panicOnBuildContentError(`Cannot resolve "item.icon" from ${t.navFile}: file ${f} does not exist`):await S.panicOnBuild(`Cannot resolve "item.icon" from ${t.navFile}: ${d.message}`)}else f=e.icon;return{icon:f,srcSet:a}}function Q(e){return i=>{if(i.type==="link"||i.type==="group"){const n=i.metadata;return n?Object.entries(e).every(([t,a])=>Array.isArray(a)?a.some(f=>n[t]===f):n[t]===a):!1}return!0}}async function K(e,i,n,t,a){if(e?.tab!==void 0||e?.menu!==void 0){const s=`Navigation tabs ("tab"/"menu") are only allowed at the top level of a sidebars.yaml file: ${JSON.stringify(e)}`;return await S.panicOnBuildContentError(`Invalid nav item in %rp. ${s}`,a.navFile),{type:"error",label:s}}if(e?.directory&&e.items?.length)return{type:"error",label:`Can't have both "directory" and "items" in the nav item: ${JSON.stringify(e)}`};e?.directory&&e?.group&&(e={...e,directory:void 0,items:[{directory:e.directory}]});const f=e?.directory?F(n.contentDir,i,a,e.directory,t.fs):void 0;if(f!==void 0){const s=f===""?"":f+"/",{locale:u,ignoredRoutes:o}=a,p=n.getAllRoutesForLocale(u).filter(c=>!o?.has(c.baseSlug||"")&&c.fsPath.startsWith(s)&&!c.excludeFromSidebar).sort((c,P)=>c.fsPath===P.fsPath?0:c.baseSlug.localeCompare(P.baseSlug,void 0,{numeric:!0})),m=e.includeByMetadata?Q(e.includeByMetadata):Boolean;if(!p.length)return[];const T=(await Promise.all(p.map(async c=>{const P=c.versions?.find(x=>x.active),L=P&&{version:P.version,isDefault:P.default,versionFolderId:P.folderId},V=ee(v.posix.relative(f,c.fsPath)),O=c.getSidebar?.(c);return!a.ignoreCustomSidebar&&O?.length?{type:"group",fsPath:c.fsPath,metadata:c.metadata,link:c.slug,routeSlug:c.slug,label:await c.getNavText?.()||c.slug,[h]:c[h],[b]:c[b],sidebarItems:k(O,L,c[h],c[b]),...L,relativePathFromDirectory:v.relative(f,c.fsPath).replace(/@(?<!@[^/]*?@)[^/]+\//,"")}:{type:"link",fsPath:c.fsPath,metadata:c.metadata,[h]:c[h],[b]:c[b],label:await c.getNavText?.()||c.slug,link:c.slug,routeSlug:c.slug,...L,relativePathFromDirectory:V}}))).filter(m);return e.flatten?$(T,a):Z(T,a)}let d=typeof e=="string"?e:e?.page,r,l;if(d){if(d.includes("#")){const[s,u]=d.split("#");u?l=u:A.warn(`Invalid heading anchor format in sidebar: "${u}". Heading anchors should contain only alphanumeric characters, hyphens, and underscores.`),d=s}if(d=j(d),a.locale&&a.locale!==_){const s=J(v.join(a.locale.toLowerCase(),d));r=n.getRouteBySlug(s)}r||(r=n.getRouteBySlug(d)),r||(r=n.getRouteByFsPath(F(n.contentDir,i,a,d,t.fs)))}const g=r?.metadata;if(e?.$ref){let s=F(n.contentDir,i,a,e.$ref,t.fs);if(a.ref!==void 0&&(s=v.posix.join(a.ref,e.$ref)),!t.fs.exists(s))return await S.panicOnBuildContentError(`Failed to load ${s} file. Make sure sidebar $ref path is correct.`),[];const u=await t.cache.load(s,"yaml"),o=v.dirname(s);return await I(u.data,i,n,t,{...a,navFile:s,ref:o})||[]}if(!r){const s=a.excludedFromLinkCheckerPatterns?.catalog.some(o=>o.test(d||"")),u=a.excludedFromLinkCheckerPatterns?.apiFunctions.some(o=>o.test(d||e.href||""));(u||s)&&(e={...e,href:d||e.href,page:void 0,target:e.target??(u?"_blank":void 0)}),await X(e,a,t,i)}if(r&&!e.disconnect&&!a.ignoreCustomSidebar&&(l||r?.getSidebar)){const s=r.versions?.find(o=>o.active),u=s&&{version:s.version,isDefault:s.default,versionFolderId:s.folderId};if(l){let o=[];if(r.getSidebar&&(o=r.getSidebar(r,{...e,...await y(e,n,t,a)}),o&&o.length>0)){const p=o[0];p&&p.link&&(p.link=`${p.link}#${l}`)}if(!o||o.length===0){const p=e.group||e.label||l;o=[{type:"link",fsPath:r.fsPath,metadata:r.metadata,link:`${r.slug}#${l}`,routeSlug:r.slug,label:p,labelTranslationKey:e.labelTranslationKey,...await y(e,n,t,a),[h]:r[h],[b]:{slug:r.slug,fsPath:r.fsPath},...u}]}return k(o,u,r[h],r[b])}if(r?.getSidebar){const o=r.getSidebar(r,{...e,...await y(e,n,t,a)}),p=e.group&&o?.[0]?.routeSlug===r.slug?o.slice(1):o;return k(a.groupCustomSidebars||e.group?[{type:"group",fsPath:r.fsPath,link:r.slug,routeSlug:r.slug,label:e.group||e.label||await r.getNavText?.()||r.slug,items:p,labelTranslationKey:e.labelTranslationKey,metadata:g,badges:e.badges,...await y(e,n,t,a)}]:o,u,r[h],r[b])}}if(r&&!e.group){const s=l?`${r.slug}#${l}`:r.slug;let u=e.label||l||"";u||(u=await r.getNavText?.()||r.slug);const o=r.versions?.find(m=>m.active),p=o&&{version:o.version,isDefault:o.default,versionFolderId:o.folderId};return{type:"link",fsPath:r.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,[h]:e?.rbac||r[h],[b]:{slug:r.slug,fsPath:r.fsPath},label:u,labelTranslationKey:e.labelTranslationKey,link:s,items:await I(e.items,i,n,t,a),separatorLine:e.separatorLine,linePosition:e.linePosition,routeSlug:e.disconnect?void 0:s,external:e.external,target:e.target,badges:e.badges,...await y(e,n,t,a),...p,additionalProps:e.additionalProps}}else if(e?.group){const s=r?.versions?.find(o=>o.active),u=C(a?.navFile);return{type:"group",fsPath:r?.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,version:s?.version||u?.versionName,versionFolderId:s?.folderId||(u?.versionFolderPath?R(u.versionFolderPath):void 0),label:e.group,link:r?.slug,routeSlug:r?.slug,badges:e.badges,labelTranslationKey:e.groupTranslationKey,items:await I(e.items,i,n,t,a),expanded:e.expanded?e.expanded.toString():void 0,selectFirstItemOnExpand:e.selectFirstItemOnExpand,menuStyle:e.menuStyle,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,t,a),[h]:e?.rbac,[b]:{slug:r?.slug||"",fsPath:r?.fsPath||""},additionalProps:e.additionalProps}}else{if(e?.href||e?.label)return{type:"link",metadata:g,link:e.href||"",label:e?.label||e?.href||"",labelTranslationKey:e.labelTranslationKey,external:e.external,target:e.target,separatorLine:e.separatorLine,linePosition:e.linePosition,badges:e.badges,...await y(e,n,t,a),[h]:e?.rbac,additionalProps:e.additionalProps};if(e?.separator!=null||e?.separatorLine!=null){const s=C(a?.navFile);return{type:"separator",metadata:g,version:s?.versionName,versionFolderId:s?.versionFolderPath?R(s.versionFolderPath):void 0,label:e.separator,labelTranslationKey:e.separatorTranslationKey,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,t,a),[h]:e?.rbac,additionalProps:e.additionalProps}}else{const s=C(a?.navFile);return{type:"error",label:`Can't resolve page: ${JSON.stringify(e)}`,version:s?.versionName,versionFolderId:s?.versionFolderPath?R(s.versionFolderPath):void 0}}}}async function X(e,i,n,t){const{href:a,page:f}=e;if(a||!f)return;const d=F(n.fs.cwd,t,i,f,n.fs),r=n.fs.exists(d),l=await n.isPathIgnored(d),g=(r?"The page is ignored: ":"Can't resolve page: ")+f;(!r||l)&&S.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",title:e.label||e.group||"",link:d,rawLink:f,message:g,sourceFileRelativePath:i.navFile,sourceFileLocation:{line:0}})}function F(e,i,n,t="",a){if(n.ref!==void 0)return w(v.relative(e,v.resolve(e,v.join(n.ref,t))));if(t.startsWith("/")){const f=B(i)?q(i):void 0,d=f?`${a.localizationFolder}/${f}/`:"",r=t.slice(1);return B(r)?r:d+w(r)}return w(v.relative(e,v.resolve(e,i,t)))}function Z(e,i){const n={};for(const r of e){const l=v.dirname(r.relativePathFromDirectory),g=r.version?M+r.version:"",s=v.basename(r.relativePathFromDirectory)+g;d(l,r,s)}const t=f(a(n));return $(t,i);function a(r){const l=[];for(const g of Object.keys(r)){const s=r[g];l.push({...s,items:s.items?a(s.items):void 0})}return l}function f(r){return r.sort((l,g)=>{const s=typeof l=="string"?l.toLowerCase():l.relativePathFromDirectory||l.label||"",u=typeof g=="string"?g.toLowerCase():g.relativePathFromDirectory||g.label||"";return s.startsWith("index.")?-1:u.startsWith("index.")?1:s.localeCompare(u,void 0,{numeric:!0})})}function d(r,l,g){r==="."&&(r="");const s=r.split("/").filter(Boolean);let u=n;for(const o of s){const p=o+(l?.version||"");u[p]||(u[p]={type:"group",version:l?.version,label:o,isDefault:l?.isDefault,versionFolderId:l.versionFolderId,items:{}}),u=u[p].items}u[g]=l}}function $(e,i){return e.flatMap(n=>n?.sidebarItems?i.groupCustomSidebars?{...n,items:n.sidebarItems,sidebarItems:void 0,relativePathFromDirectory:void 0}:n.sidebarItems:{...n,items:n.items?$(n.items,i):void 0})}function k(e,i,n,t){return e.map(a=>({...a,...i,[h]:a[h]||n,[b]:a[b]||t,items:a.type==="group"&&a.items?k(a.items,i,n):a.items}))}function ee(e){return e.replace(/@(?<!@[^/]*?@)[^/]+\//,"")}async function ye(e,i,n,t){const a=(e?.items||[]).filter(r=>r.linkedSidebars?.length).map(r=>({...r,items:void 0})),f=await N(a,i.contentDir,i,n,t),d=new Map;for(const r of f)if(r.linkedSidebars?.length)for(const l of r.linkedSidebars){if(d.has(l)){A.warn(`Only one navbar item can belong to sidebar. "${l}" on 'linkedSidebars' property on "${r.label}" will be ignored.`);continue}d.set(l,{label:r.label,link:r.link})}return d}export{ye as collectItemsLinkedToSidebars,D as normalizeItems,K as resolveItem,I as resolveItems,N as resolveLinksFromConfig};
|
|
1
|
+
import*as h from"path";import{REDOCLY_ROUTE_RBAC as b,REDOCLY_TEAMS_RBAC as p}from"@redocly/config";import{VERSION_SEPARATOR as x}from"../constants/common.js";import{DEFAULT_LOCALE_PLACEHOLDER as M}from"../../constants/common.js";import{removeTrailingSlash as j}from"../../utils/url/remove-trailing-slash.js";import{isPrimitive as W}from"../../utils/guards/is-primitive.js";import{slash as w}from"../../utils/path/slash.js";import{isAbsoluteUrl as z}from"../../utils/url/is-absolute-url.js";import{normalizeRouteSlug as J}from"../../utils/path/normalize-route-slug.js";import{parsePathVersions as C}from"../../utils/path/parse-path-versions.js";import{logger as A}from"../tools/notifiers/logger.js";import{reporter as F}from"../tools/notifiers/reporter.js";import{shaDirPathShort as R}from"../utils/crypto/sha-dir-path-short.js";import{copyStaticFile as U,FileNotFoundError as D}from"../utils/fs.js";import{isIconPath as H,resolveAssetPath as Y}from"../utils/index.js";import{resolveSrcSet as G}from"../utils/resolve-src-set.js";import{isL10nPath as E}from"../fs/utils/is-l10n-path.js";import{getLocaleFromRelativePath as q}from"../fs/utils/get-locale-from-relative-path.js";async function B(e,i,n,s,a){if(!e)return;const f={...a,ignoreCustomSidebar:!0};if(W(e)){if(typeof e=="string"){const r=I(n.contentDir,i,a,e,s.fs);if(s.fs.exists(r)){if(n.getRouteByFsPath(r))return K({page:e},i,n,s,f);{const g=s.fs.getFileInfo(r);return g?U(n.contentDir,g.realRelativePath,n.outdir):void 0}}}return e}return Array.isArray(e)?k(N(e),i,n,s,f):Object.fromEntries(await Promise.all(Object.entries(e).map(async([r,l])=>[r,await B(l,i,n,s,a)])))}function N(e){return e.map(i=>({...i,items:i.items?N(i.items):void 0}))}async function k(e,i,n,s,a){if(Array.isArray(e))return(await Promise.all(e.map(f=>K(f,i,n,s,a)))).flatMap(f=>f)}async function y(e,i,n,s){let a,f;if(typeof e.icon=="object"){if("srcSet"in e.icon)try{a=await G(e.icon.srcSet,n.fs,{fromFileRelativePath:s.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof D?await F.panicOnBuildContentError(`Cannot resolve "item.icon.srcSet" from ${s.navFile}: ${d.message}`):await F.panicOnBuild(`Cannot resolve "item.icon.srcSet" from ${s.navFile}: ${d.message}`)}}else if(typeof e.icon=="string")if(z(e.icon)||H(e.icon))try{f=await Y(e.icon,n.fs,{fromFileRelativePath:s.navFile,contentDir:i.contentDir,outdir:i.outdir})}catch(d){d instanceof D?await F.panicOnBuildContentError(`Cannot resolve "item.icon" from ${s.navFile}: file ${f} does not exist`):await F.panicOnBuild(`Cannot resolve "item.icon" from ${s.navFile}: ${d.message}`)}else f=e.icon;return{icon:f,srcSet:a}}function Q(e){return i=>{if(i.type==="link"||i.type==="group"){const n=i.metadata;return n?Object.entries(e).every(([s,a])=>Array.isArray(a)?a.some(f=>n[s]===f):n[s]===a):!1}return!0}}async function K(e,i,n,s,a){if(e?.tab!==void 0||e?.menu!==void 0){const t=`Navigation tabs ("tab"/"menu") are only allowed at the top level of a sidebars.yaml file: ${JSON.stringify(e)}`;return await F.panicOnBuildContentError(`Invalid nav item in %rp. ${t}`,a.navFile),{type:"error",label:t}}if(e?.directory&&e.items?.length)return{type:"error",label:`Can't have both "directory" and "items" in the nav item: ${JSON.stringify(e)}`};e?.directory&&e?.group&&(e={...e,directory:void 0,items:[{directory:e.directory}]});const f=e?.directory?I(n.contentDir,i,a,e.directory,s.fs):void 0;if(f!==void 0){const t=f===""?"":f+"/",{locale:u,ignoredRoutes:o}=a,v=n.getAllRoutesForLocale(u).filter(c=>!o?.has(c.baseSlug||"")&&c.fsPath.startsWith(t)&&!c.excludeFromSidebar).sort((c,P)=>c.fsPath===P.fsPath?0:c.baseSlug.localeCompare(P.baseSlug,void 0,{numeric:!0})),L=e.includeByMetadata?Q(e.includeByMetadata):Boolean;if(!v.length)return[];const T=(await Promise.all(v.map(async c=>{const P=c.versions?.find(_=>_.active),S=P&&{version:P.version,isDefault:P.default,versionFolderId:P.folderId},V=ee(h.posix.relative(f,c.fsPath)),O=c.getSidebar?.(c);return!a.ignoreCustomSidebar&&O?.length?{type:"group",fsPath:c.fsPath,metadata:c.metadata,link:c.slug,routeSlug:c.slug,label:await c.getNavText?.()||c.slug,[p]:c[p],[b]:c[b],sidebarItems:m(O,S,c[p],c[b]),version:S?.version,isDefault:S?.isDefault,versionFolderId:S?.versionFolderId,relativePathFromDirectory:h.relative(f,c.fsPath).replace(/@(?<!@[^/]*?@)[^/]+\//,"")}:{type:"link",fsPath:c.fsPath,metadata:c.metadata,[p]:c[p],[b]:c[b],label:await c.getNavText?.()||c.slug,link:c.slug,routeSlug:c.slug,version:S?.version,isDefault:S?.isDefault,versionFolderId:S?.versionFolderId,relativePathFromDirectory:V}}))).filter(L);return e.flatten?$(T,a):Z(T,a)}let d=typeof e=="string"?e:e?.page,r,l;if(d){if(d.includes("#")){const[t,u]=d.split("#");u?l=u:A.warn(`Invalid heading anchor format in sidebar: "${u}". Heading anchors should contain only alphanumeric characters, hyphens, and underscores.`),d=t}if(d=j(d),a.locale&&a.locale!==M){const t=J(h.join(a.locale.toLowerCase(),d));r=n.getRouteBySlug(t)}r||(r=n.getRouteBySlug(d)),r||(r=n.getRouteByFsPath(I(n.contentDir,i,a,d,s.fs)))}const g=r?.metadata;if(e?.$ref){let t=I(n.contentDir,i,a,e.$ref,s.fs);if(a.ref!==void 0&&(t=h.posix.join(a.ref,e.$ref)),!s.fs.exists(t))return await F.panicOnBuildContentError(`Failed to load ${t} file. Make sure sidebar $ref path is correct.`),[];const u=await s.cache.load(t,"yaml"),o=h.dirname(t);return await k(u.data,i,n,s,{...a,navFile:t,ref:o})||[]}if(!r){const t=a.excludedFromLinkCheckerPatterns?.catalog.some(o=>o.test(d||"")),u=a.excludedFromLinkCheckerPatterns?.apiFunctions.some(o=>o.test(d||e.href||""));(u||t)&&(e={...e,href:d||e.href,page:void 0,target:e.target??(u?"_blank":void 0)}),await X(e,a,s,i)}if(r&&!e.disconnect&&!a.ignoreCustomSidebar&&(l||r?.getSidebar)){const t=r.versions?.find(o=>o.active),u=t&&{version:t.version,isDefault:t.default,versionFolderId:t.folderId};if(l){let o=[];if(r.getSidebar&&(o=r.getSidebar(r,{...e,...await y(e,n,s,a)}),o&&o.length>0)){const v=o[0];v&&v.link&&(v.link=`${v.link}#${l}`)}if(!o||o.length===0){const v=e.group||e.label||l;o=[{type:"link",fsPath:r.fsPath,metadata:r.metadata,link:`${r.slug}#${l}`,routeSlug:r.slug,label:v,labelTranslationKey:e.labelTranslationKey,...await y(e,n,s,a),[p]:r[p],[b]:{slug:r.slug,fsPath:r.fsPath},...u}]}return m(o,u,r[p],r[b])}if(r?.getSidebar){const o=r.getSidebar(r,{...e,...await y(e,n,s,a)}),v=e.group&&o?.[0]?.routeSlug===r.slug?o.slice(1):o;return m(a.groupCustomSidebars||e.group?[{type:"group",fsPath:r.fsPath,link:r.slug,routeSlug:r.slug,label:e.group||e.label||await r.getNavText?.()||r.slug,items:v,labelTranslationKey:e.labelTranslationKey,metadata:g,badges:e.badges,...await y(e,n,s,a)}]:o,u,r[p],r[b])}}if(r&&!e.group){const t=l?`${r.slug}#${l}`:r.slug;let u=e.label||l||"";u||(u=await r.getNavText?.()||r.slug);const o=r.versions?.find(L=>L.active),v=o&&{version:o.version,isDefault:o.default,versionFolderId:o.folderId};return{type:"link",fsPath:r.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,[p]:e?.rbac||r[p],[b]:{slug:r.slug,fsPath:r.fsPath},label:u,labelTranslationKey:e.labelTranslationKey,link:t,items:await k(e.items,i,n,s,a),separatorLine:e.separatorLine,linePosition:e.linePosition,routeSlug:e.disconnect?void 0:t,external:e.external,target:e.target,badges:e.badges,...await y(e,n,s,a),...v,additionalProps:e.additionalProps}}else if(e?.group){const t=r?.versions?.find(o=>o.active),u=C(a?.navFile);return{type:"group",fsPath:r?.fsPath,linkedSidebars:e.linkedSidebars,metadata:g,version:t?.version||u?.versionName,versionFolderId:t?.folderId||(u?.versionFolderPath?R(u.versionFolderPath):void 0),label:e.group,link:r?.slug,routeSlug:r?.slug,badges:e.badges,labelTranslationKey:e.groupTranslationKey,items:await k(e.items,i,n,s,a),expanded:e.expanded?e.expanded.toString():void 0,selectFirstItemOnExpand:e.selectFirstItemOnExpand,menuStyle:e.menuStyle,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,s,a),[p]:e?.rbac,[b]:{slug:r?.slug||"",fsPath:r?.fsPath||""},additionalProps:e.additionalProps}}else{if(e?.href||e?.label)return{type:"link",metadata:g,link:e.href||"",label:e?.label||e?.href||"",labelTranslationKey:e.labelTranslationKey,external:e.external,target:e.target,separatorLine:e.separatorLine,linePosition:e.linePosition,badges:e.badges,...await y(e,n,s,a),[p]:e?.rbac,additionalProps:e.additionalProps};if(e?.separator!=null||e?.separatorLine!=null){const t=C(a?.navFile);return{type:"separator",metadata:g,version:t?.versionName,versionFolderId:t?.versionFolderPath?R(t.versionFolderPath):void 0,label:e.separator,labelTranslationKey:e.separatorTranslationKey,separatorLine:e.separatorLine,linePosition:e.linePosition,...await y(e,n,s,a),[p]:e?.rbac,additionalProps:e.additionalProps}}else{const t=C(a?.navFile);return{type:"error",label:`Can't resolve page: ${JSON.stringify(e)}`,version:t?.versionName,versionFolderId:t?.versionFolderPath?R(t.versionFolderPath):void 0}}}}async function X(e,i,n,s){const{href:a,page:f}=e;if(a||!f)return;const d=I(n.fs.cwd,s,i,f,n.fs),r=n.fs.exists(d),l=await n.isPathIgnored(d),g=(r?"The page is ignored: ":"Can't resolve page: ")+f;(!r||l)&&F.reportBrokenLink({type:"BROKEN_LINK",brokenLinkType:"LINK",title:e.label||e.group||"",link:d,rawLink:f,message:g,sourceFileRelativePath:i.navFile,sourceFileLocation:{line:0}})}function I(e,i,n,s="",a){if(n.ref!==void 0)return w(h.relative(e,h.resolve(e,h.join(n.ref,s))));if(s.startsWith("/")){const f=E(i)?q(i):void 0,d=f?`${a.localizationFolder}/${f}/`:"",r=s.slice(1);return E(r)?r:d+w(r)}return w(h.relative(e,h.resolve(e,i,s)))}function Z(e,i){const n={};for(const r of e){const l=h.dirname(r.relativePathFromDirectory),g=r.version?x+r.version:"",t=h.basename(r.relativePathFromDirectory)+g;d(l,r,t)}const s=f(a(n));return $(s,i);function a(r){const l=[];for(const g of Object.keys(r)){const t=r[g];l.push({...t,items:t.items?a(t.items):void 0})}return l}function f(r){return r.sort((l,g)=>{const t=typeof l=="string"?l.toLowerCase():l.relativePathFromDirectory||l.label||"",u=typeof g=="string"?g.toLowerCase():g.relativePathFromDirectory||g.label||"";return t.startsWith("index.")?-1:u.startsWith("index.")?1:t.localeCompare(u,void 0,{numeric:!0})})}function d(r,l,g){r==="."&&(r="");const t=r.split("/").filter(Boolean);let u=n;for(const o of t){const v=o+(l?.version||"");u[v]||(u[v]={type:"group",version:l?.version,label:o,isDefault:l?.isDefault,versionFolderId:l.versionFolderId,items:{}}),u=u[v].items}u[g]=l}}function $(e,i){return e.flatMap(n=>n?.sidebarItems?i.groupCustomSidebars?{...n,items:n.sidebarItems,sidebarItems:void 0,relativePathFromDirectory:void 0}:n.sidebarItems:{...n,items:n.items?$(n.items,i):void 0})}function m(e,i,n,s){return e.map(a=>({...a,...i,[p]:a[p]||n,[b]:a[b]||s,items:a.type==="group"&&a.items?m(a.items,i,n):a.items}))}function ee(e){return e.replace(/@(?<!@[^/]*?@)[^/]+\//,"")}async function ye(e,i,n,s){const a=(e?.items||[]).filter(r=>r.linkedSidebars?.length).map(({items:r,...l})=>l),f=await B(a,i.contentDir,i,n,s),d=new Map;for(const r of f)if(r.linkedSidebars?.length)for(const l of r.linkedSidebars){if(d.has(l)){A.warn(`Only one navbar item can belong to sidebar. "${l}" on 'linkedSidebars' property on "${r.label}" will be ignored.`);continue}d.set(l,{label:r.label,link:r.link})}return d}export{ye as collectItemsLinkedToSidebars,N as normalizeItems,K as resolveItem,k as resolveItems,B as resolveLinksFromConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PACKAGE_NAME as e}from"../../../config/product-gates.js";const r=["@redocly/realm","@redocly/reef","@redocly/redoc-reef","@redocly/revel-reef"];function c(){return r.includes(e)}export{c as hasProjectDatabase};
|
|
1
|
+
import{PACKAGE_NAME as e}from"../../../config/product-gates.js";const r=["@redocly/realm","@redocly/framework","@redocly/reef","@redocly/redoc-reef","@redocly/revel-reef"];function c(){return r.includes(e)}export{c as hasProjectDatabase};
|
package/dist/server/store.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Node } from '@markdoc/markdoc';
|
|
2
2
|
import type { JSX } from 'react';
|
|
3
3
|
import type { CommonError, GlobalData } from '../types/index.js';
|
|
4
|
-
import type { MiddlewareDetails, PageRouteInit, PageRouteDetails, RouteDetails, LifecycleContext, ApiRoute, ParseMarkdocOpts, WildcardRedirectsTree, RedirectOptions, McpToolRegistration, McpToolSchema, MarkdocOptions } from './types';
|
|
4
|
+
import type { MiddlewareDetails, PageRouteInit, PageRouteDetails, RouteDetails, LifecycleContext, ApiRoute, ParseMarkdocOpts, WildcardRedirectsTree, StaticFilePaths, RedirectOptions, McpToolRegistration, McpToolSchema, MarkdocOptions } from './types';
|
|
5
5
|
import type { Skill } from './types/plugins/skills.js';
|
|
6
6
|
import type { RedoclyConfig, RedirectConfig, CompilationError, PageStaticData } from '@redocly/config';
|
|
7
7
|
import type { SearchFacet } from '@redocly/theme/core/types';
|
|
@@ -28,6 +28,7 @@ export type ComputedRedoclyConfig = {
|
|
|
28
28
|
export declare class Store {
|
|
29
29
|
#private;
|
|
30
30
|
routesBySlug: Map<string, PageRouteDetails>;
|
|
31
|
+
staticFilePaths: StaticFilePaths;
|
|
31
32
|
replacedEnvVars: Record<string, {
|
|
32
33
|
original: string;
|
|
33
34
|
replaced: string;
|
|
@@ -112,6 +113,7 @@ export declare class Store {
|
|
|
112
113
|
loadApiDocuments(context: LifecycleContext): Promise<BundledApiDefinition[]>;
|
|
113
114
|
setSearchEngine(engine: SearchEngine): void;
|
|
114
115
|
setSearchFacets: (searchFacets: Map<string, SearchFacet>) => void;
|
|
116
|
+
setStaticFilePaths: (staticFilePaths: StaticFilePaths) => void;
|
|
115
117
|
setGlobalConfig: (data: Partial<RedoclyConfig>) => void;
|
|
116
118
|
getConfig: () => RedoclyConfig;
|
|
117
119
|
getGlobalConfig: <T = unknown>(key: string) => T;
|
package/dist/server/store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import A from"@markdoc/markdoc";import{parseAndResolveMarkdoc as T}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as M}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as O,MARKDOC_PARTIALS_DATA_KEY as m,MARKDOC_PARTIALS_DEPS_KEY as k}from"./constants/common.js";import{GATED_MARKDOC_TAGS as R}from"./constants/entitlements.js";import{isObject as L}from"../utils/guards/is-object.js";import{mapObject as H}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as D}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 G}from"./utils/crypto/sha1.js";import{envConfig as _,setEnv as B}from"./config/env-config.js";import{KvService as F}from"./persistence/kv/services/kv-service.js";import{SandboxContext as I}from"./utils/sandbox-context.js";import{writeSharedData as N}from"./utils/index.js";import{renderComponents as V}from"./ssr/render.js";import{readStaticData as q,writeStaticData as U}from"./utils/static-data.js";import{getMarkdocOptions as j}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as v}from"./entitlements/entitlements-provider.js";import{isRouteReserved as x}from"./plugins/get-reserved-routes.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as W}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as $}from"./utils/redirects/find-redirect.js";import{followRedirectChain as z}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as Y}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as Z}from"../cli/telemetry/helpers/trace-step.js";const E={routesBySlug:"map",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},P="PLAN_GATES",Q=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],ke="userDefinedApiFunctions";class b{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;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#a=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#u=Promise.resolve();#h;#e=!1;#r=0;#f=0;#o=new Map;constructor({outdir:e,contentDir:s,serverMode:t=!1,serverOutDir:r}){this.#i=s,this.outdir=e,this.serverMode=t,this.serverOutDir=r,I.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(o=>{this.#n=o})}on(e,s){const t=this.listeners.get(e);t?t.add(s):this.listeners.set(e,new Set([s]))}queueEvent=(e,s,...t)=>{this.#o.set(e+String(s),[e,s,...t])};runListeners=(e,s,...t)=>{for(const r of this.listeners.get(e)||new Set)s?r(s,...t):r(...t)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#u])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#o.values())this.runListeners(...e);this.#o.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#u=new Promise(e=>{this.#h=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#h?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await Z("com.redocly.build.reloadMarkdocOptions",async()=>{const e=v.instance(),s=await j(this.serverOutDir),t=Object.fromEntries(Object.entries(s.tags).filter(([r])=>R[r]!=null?e.canAccessFeature(R[r]):!0));this.#a={...s,tags:t}})}get markdocOptions(){return{...this.#a,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=e=>{const s=this.globalData,t={...this.globalData,...e};this.globalData=t,JSON.stringify(t)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,t)};getGlobalData=()=>this.globalData;getKv=async()=>F.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:s,deps:t,resource:r})=>{const{data:{info:o,ast:i},compoundHash:l}=await T(e,this.markdocOptions,{actions:this,context:s},r);for(const a of o.sharedDataDeps||[]){for(const n of t?.routeSlugs||[])this.addRouteSharedData(n,a,a);for(const n of t?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(a),this.sharedDataDeps.set(n,c)}}for(const a of o.dynamicMarkdocComponents||[]){for(const n of t?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(a),this.routesDynamicComponents.set(n,c)}for(const n of t?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(a),this.sharedDataMarkdocComponents.set(n,c)}}if(t?.routeSlugs&&o.partials?.length)for(const a of t.routeSlugs){const n=this.routesPartials.get(a)||[];for(const c of o.partials)n.includes(c)||n.push(c);this.routesPartials.set(a,n)}return{info:o,ast:i,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setGlobalConfig=e=>{const s=Object.keys(e);for(const l of s)for(const a in this.replacedEnvVars)if(a===l||a.startsWith(`${l}:`)){const n=a.split(":"),{error:c,value:d}=y(e,n);(c||d!==this.replacedEnvVars[a].replaced)&&delete this.replacedEnvVars[a]}const{resolvedObj:t,unsetEnvVars:r,replacedValues:o}=W(e);for(const l of r)this.unsetEnvVars.add(l);Object.assign(this.replacedEnvVars,o);const i=t.seo?.siteUrl?.trim();i&&(t.seo={...t.seo,siteUrl:URL.canParse(i)?new URL(i).origin:D(i)}),Object.assign(this.config,t)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,s,t={})=>{if(!v.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const i=h(e).toLowerCase();this.config.redirects[i]=s;const{trackOriginalSource:l=!0}=t,a=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(a)&&!a.includes(i)&&a.push(i),i.endsWith("*")&&Y(this.config.wildcardRedirectsTree,i)};getRedirect=e=>{const s=h(e).toLowerCase(),t=$(s,this.config.redirects,this.config.wildcardRedirectsTree);if(!t)return null;if(S(t.to)){const r=h(t.to).toLowerCase();if(!r.endsWith("*")&&z(r,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:t.to,type:t.type}};createSharedData=async(e,s,t)=>{if(t&&this.#t[e]===t)return e;const r=JSON.stringify(s),o=t??G(r);return this.#t[e]===o||(this.#t[e]=o,await N(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,s,t)=>{const r=D(e),o=this.routesSharedData.get(r)||{};o[s]=t,this.routesSharedData.set(r,o),u.verbose(`Adding shared data to ${e}, ${s}, ${t}`)};getRouteSharedDataByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=e=>{const s=this.getGlobalConfig(m)||{},t=this.routesPartials.get(e);if(!t||t.length===0)return{};const r=this.getGlobalConfig(k)||{},o=new Set(t),i=Array.from(t);for(let a=0;a<i.length;a++){const n=i[a],c=r[n]?.partials??[];for(const d of c)o.has(d)||(o.add(d),i.push(d))}const l={};for(const a of o)s[a]&&(l[a]=s[a]);return l};addRoute=e=>{const t={...J(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:t}),u.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,s,t)=>{const r=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(o=>({code:o,name:o}));for(const o of r){const i=M(e,g,o.code,r);this.addRouteSharedData(i,s,t)}};addApiRoute=e=>{this.apiRoutes.push(e),u.verbose("Created API route %s",e.slug)};addMcpTools=(e,s)=>{for(const t of s){const r=this.mcpToolHandlers.get(t.name);r&&r.importPath!==e&&u.warn('MCP tool "%s" from %s overwrites the tool registered from %s',t.name,e,r.importPath),this.mcpToolHandlers.set(t.name,{...t,importPath:e}),u.verbose("Created MCP tool %s",t.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const s of e){const t=this.mcpToolHandlers.get(s);t&&this.mcpToolHandlers.set(s,{...t,hasAvailabilityGate:!0})}};addSkills=e=>{for(const s of e)this.skills.set(s.slug,s),u.verbose("Discovered skill %s",s.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const s of e)this.mcpToolHandlers.delete(s)};addMiddleware=e=>{this.middleware.push(e),u.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,s)=>{this.config.responseHeaders||(this.config.responseHeaders={});const t=new Set(s.map(i=>i.name.toLowerCase())),o=[...(this.config.responseHeaders[e]??[]).filter(i=>!t.has(i.name.toLowerCase())),...s];this.config.responseHeaders[e]=o};getRouteByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(e,s={})=>{const{followRedirect:t=!0}=s,r=this.getRedirect(e);return t&&r?this.routesBySlug.get(h(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||x(e,this.getConfig()))return!0;const s=this.getRedirect(e);if(!s)return!1;if(!S(s.to))return!0;const t=h(s.to);return this.routesBySlug.has(t)};getRoutesByTemplateId=e=>this.newRoutes.filter(s=>s.templateId===e);getAllRoutesForLocale=(e=g)=>{const s=Array.from(this.routesBySlug.values()),t=e.toLowerCase();return s.filter(r=>e===g?!K(r.fsPath):r.slug.startsWith(`/${t}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,s)=>(this.templates.set(e,s),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,s)=>(this.apiRoutesRequestHandlers.set(e,s),e);clearRequestHandlersByPrefix=e=>{for(const s of this.apiRoutesRequestHandlers.keys())s.startsWith(e)&&this.apiRoutesRequestHandlers.delete(s)};registerServerPropsGetter=(e,s)=>(this.serverPropsGetters.set(e,s),e);registerPagePropsGetter=(e,s)=>{this.pagePropsGetters.set(e,s)};async writeRouteStaticData(e,s){const t=await this.resolveRouteStaticData(e,s,!1);t&&U(e.slug,t,this.outdir)}async resolveRouteStaticData(e,s,t){if(this.serverMode)return q(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[e.slug]},resource:f})},o=await e.getStaticData?.(e,r)||{},i=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>i.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const a=this.getGlobalConfig("seo"),n=o?.frontmatter||{};return{...o,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...o.props,dynamicMarkdocComponents:Array.from(i),metadata:{...o?.props?.metadata,...e.metadata},seo:{title:O,...a,...o.props?.seo,siteUrl:a?.siteUrl},compilationErrors:this.compilationErrors},lastModified:t||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,s){if(!e?.length)return;const t=typeof e[0]=="string"?e.join(""):V(e);t&&(s==="head"?this.ssr.headTags.push(t):s==="preBody"?this.ssr.preBodyTags.push(t):this.ssr.postBodyTags.push(t))}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.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[t,r]of Object.entries(E))switch(r){case"map":{const o=Array.from(this[t].entries());e.push([t,o]);break}case"object":if(t==="config"){e.push([t,await this.getConfigWithEnvPlaceholders()]);break}e.push([t,this[t]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(e);return s[P]=_.PLAN_GATES,s}static fromJson(e,s){const t=new b(s);for(const[o,i]of Object.entries(E))switch(i){case"map":t[o]=new Map(e[o]);break;case"object":if(o==="config"){t.setGlobalConfig(e[o]);break}t[o]=e[o];break;default:throw new Error("Invalid format")}t.config[m]=X(t.config[m]||{});const r=e[P];return r&&B("PLAN_GATES",r),t}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:t}=this.replacedEnvVars[s],r=s.split(":"),o=r.pop(),{error:i,value:l}=y(e,r);if(i||!L(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[o]=t}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(t=>!Q.includes(t));if(e.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await w.panicOnBuildContentError(s)}}function X(C){return H(C,e=>A.Ast.fromJSON(JSON.stringify(e)))}export{b as Store,ke as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
1
|
+
import A from"@markdoc/markdoc";import{parseAndResolveMarkdoc as T}from"./plugins/markdown/compiler.js";import{getPathnameForLocale as M}from"@redocly/theme/core/utils";import{DEFAULT_LOCALE_PLACEHOLDER as g}from"../constants/common.js";import{DEFAULT_TITLE as O,MARKDOC_PARTIALS_DATA_KEY as m,MARKDOC_PARTIALS_DEPS_KEY as k}from"./constants/common.js";import{GATED_MARKDOC_TAGS as R}from"./constants/entitlements.js";import{isObject as L}from"../utils/guards/is-object.js";import{mapObject as H}from"../utils/object/map-object.js";import{getValueDeep as y}from"../utils/object/get-value-deep.js";import{removeTrailingSlash as D}from"../utils/url/remove-trailing-slash.js";import{normalizeRouteSlug as u}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 h}from"./tools/notifiers/logger.js";import{sha1 as F}from"./utils/crypto/sha1.js";import{envConfig as G,setEnv as _}from"./config/env-config.js";import{KvService as B}from"./persistence/kv/services/kv-service.js";import{SandboxContext as I}from"./utils/sandbox-context.js";import{writeSharedData as N}from"./utils/index.js";import{renderComponents as V}from"./ssr/render.js";import{readStaticData as q,writeStaticData as j}from"./utils/static-data.js";import{getMarkdocOptions as U}from"./plugins/markdown/markdoc/markdoc-options.js";import{EntitlementsProvider as v}from"./entitlements/entitlements-provider.js";import{isRouteReserved as x}from"./plugins/get-reserved-routes.js";import{isL10nPath as K}from"./fs/utils/is-l10n-path.js";import{resolveGlobMapValue as J}from"./utils/globs.js";import{replaceEnvVariablesDeep as W}from"./utils/envs/replace-env-variables-deep.js";import{findRedirect as $}from"./utils/redirects/find-redirect.js";import{followRedirectChain as z}from"./utils/redirects/follow-redirect-chain.js";import{addWildcardRedirectToTree as Y}from"./utils/redirects/add-wildcard-redirect-to-tree.js";import{telemetryTraceStep as Z}from"../cli/telemetry/helpers/trace-step.js";const E={routesBySlug:"map",staticFilePaths:"object",apiRoutes:"object",middleware:"object",routesByFsPath:"map",routesSharedData:"map",globalData:"object",config:"object",ssr:"object",searchFacets:"map",routesPartials:"map",mcpToolHandlers:"map",skills:"map",devLogin:"object"},P="PLAN_GATES",Q=["OAUTH_CLIENT_ID","OAUTH_CLIENT_SECRET","ORGANIZATION_SLUG","ORGANIZATION_ID","ORG_ID"],ke="userDefinedApiFunctions";class b{routesBySlug=new Map;staticFilePaths={};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;skills=new Map;serverPropsGetters=new Map;pagePropsGetters=new Map;listeners=new Map;globalData={};devLogin=!1;#o=void 0;config={configFilePath:"",redirects:{},wildcardRedirectsTree:{},access:{rbac:{},requiresLogin:!1},directoryPermissions:{},devLogin:!1,ssoDirect:{}};#i;serverMode;serverOutDir;outdir;buildRevision=0;hasSitemap=!1;compilationErrors=[];#n;userCodeReady;#s=Promise.resolve();#c;#l=Promise.resolve();#d;#h=Promise.resolve();#u;#e=!1;#r=0;#f=0;#a=new Map;constructor({outdir:e,contentDir:s,serverMode:t=!1,serverOutDir:r}){this.#i=s,this.outdir=e,this.serverMode=t,this.serverOutDir=r,I.register({serverOutDir:r,readRoots:[e,process.cwd()]}),this.userCodeReady=new Promise(a=>{this.#n=a})}on(e,s){const t=this.listeners.get(e);t?t.add(s):this.listeners.set(e,new Set([s]))}queueEvent=(e,s,...t)=>{this.#a.set(e+String(s),[e,s,...t])};runListeners=(e,s,...t)=>{for(const r of this.listeners.get(e)||new Set)s?r(s,...t):r(...t)};startPluginsRun(){this.clear(),this.#s=new Promise(e=>{this.#c=e})}waitForPluginsLifecycle(){return Promise.all([this.#s,this.#l,this.#h])}waitForPluginsRun(){return this.#s}finishPluginsRun(){this.#c?.();for(const e of this.#a.values())this.runListeners(...e);this.#a.clear()}startEsbuildRun(){this.#l=new Promise(e=>{this.#d=e})}finishEsbuildRun(){this.#d?.()}markRequestHandlersEntryOutdated(){this.#r++,!this.#e&&(this.#e=!0,this.#h=new Promise(e=>{this.#u=e}))}noteRequestHandlersEntryBuildStart(){this.#f=this.#r}markRequestHandlersEntryUpdated(){this.#e&&(this.#r>this.#f||(this.#e=!1,this.#u?.()))}get contentDir(){if(this.serverMode)throw new Error("contentDir should not be used in server mode");return this.#i}markUserCodeReady(){this.#n?.(!0)}async reloadMarkdocOptions(){await Z("com.redocly.build.reloadMarkdocOptions",async()=>{const e=v.instance(),s=await U(this.serverOutDir),t=Object.fromEntries(Object.entries(s.tags).filter(([r])=>R[r]!=null?e.canAccessFeature(R[r]):!0));this.#o={...s,tags:t}})}get markdocOptions(){return{...this.#o,partials:this.getGlobalConfig(m),themeConfig:this.config.markdown}}setGlobalData=e=>{const s=this.globalData,t={...this.globalData,...e};this.globalData=t,JSON.stringify(t)!==JSON.stringify(s)&&this.queueEvent("global-data-updated",void 0,t)};getGlobalData=()=>this.globalData;getKv=async()=>B.getInstance({baseDbDir:this.serverOutDir});parseMarkdoc=async({input:e,context:s,deps:t,resource:r})=>{const{data:{info:a,ast:i},compoundHash:l}=await T(e,this.markdocOptions,{actions:this,context:s},r);for(const o of a.sharedDataDeps||[]){for(const n of t?.routeSlugs||[])this.addRouteSharedData(n,o,o);for(const n of t?.sharedDataIds||[]){const c=this.sharedDataDeps.get(n)||new Set;c.add(o),this.sharedDataDeps.set(n,c)}}for(const o of a.dynamicMarkdocComponents||[]){for(const n of t?.routeSlugs||[]){const c=this.routesDynamicComponents.get(n)||new Set;c.add(o),this.routesDynamicComponents.set(n,c)}for(const n of t?.sharedDataIds||[]){const c=this.sharedDataMarkdocComponents.get(n)||new Set;c.add(o),this.sharedDataMarkdocComponents.set(n,c)}}if(t?.routeSlugs&&a.partials?.length)for(const o of t.routeSlugs){const n=this.routesPartials.get(o)||[];for(const c of a.partials)n.includes(c)||n.push(c);this.routesPartials.set(o,n)}return{info:a,ast:i,compoundHash:l}};async loadApiDocuments(e){return(await e.cache.load(".","api-docs")).data}setSearchEngine(e){this.searchEngine=e}setSearchFacets=e=>{this.searchFacets=e};setStaticFilePaths=e=>{this.staticFilePaths=e};setGlobalConfig=e=>{const s=Object.keys(e);for(const l of s)for(const o in this.replacedEnvVars)if(o===l||o.startsWith(`${l}:`)){const n=o.split(":"),{error:c,value:d}=y(e,n);(c||d!==this.replacedEnvVars[o].replaced)&&delete this.replacedEnvVars[o]}const{resolvedObj:t,unsetEnvVars:r,replacedValues:a}=W(e);for(const l of r)this.unsetEnvVars.add(l);Object.assign(this.replacedEnvVars,a);const i=t.seo?.siteUrl?.trim();i&&(t.seo={...t.seo,siteUrl:URL.canParse(i)?new URL(i).origin:D(i)}),Object.assign(this.config,t)};getConfig=()=>this.config;getGlobalConfig=e=>this.config[e];getSearchFacets=()=>this.searchFacets;addRedirect=(e,s,t={})=>{if(!v.instance().canAccessFeature("redirects")&&e!=="/")return;this.config.redirects||(this.config.redirects={});const i=u(e).toLowerCase();this.config.redirects[i]=s;const{trackOriginalSource:l=!0}=t,o=this.getGlobalConfig("originalRedirectSources");l&&Array.isArray(o)&&!o.includes(i)&&o.push(i),i.endsWith("*")&&Y(this.config.wildcardRedirectsTree,i)};getRedirect=e=>{const s=u(e).toLowerCase(),t=$(s,this.config.redirects,this.config.wildcardRedirectsTree,this.staticFilePaths);if(!t)return null;if(S(t.to)){const r=u(t.to).toLowerCase();if(!r.endsWith("*")&&z(r,[s],this.config.redirects,this.config.wildcardRedirectsTree).type==="cycle")return null}return{to:t.to,type:t.type}};createSharedData=async(e,s,t)=>{if(t&&this.#t[e]===t)return e;const r=JSON.stringify(s),a=t??F(r);return this.#t[e]===a||(this.#t[e]=a,await N(e,r,this.outdir),this.queueEvent("shared-data-updated",e)),e};addRouteSharedData=(e,s,t)=>{const r=D(e),a=this.routesSharedData.get(r)||{};a[s]=t,this.routesSharedData.set(r,a),h.verbose(`Adding shared data to ${e}, ${s}, ${t}`)};getRouteSharedDataByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.routesSharedData.get(s)||{}:{}};getPartialsForRoute=e=>{const s=this.getGlobalConfig(m)||{},t=this.routesPartials.get(e);if(!t||t.length===0)return{};const r=this.getGlobalConfig(k)||{},a=new Set(t),i=Array.from(t);for(let o=0;o<i.length;o++){const n=i[o],c=r[n]?.partials??[];for(const d of c)a.has(d)||(a.add(d),i.push(d))}const l={};for(const o of a)s[o]&&(l[o]=s[o]);return l};addRoute=e=>{const t={...J(e.fsPath,this.config.metadataGlobs),...e.metadata||{}};this.newRoutes.push({...e,metadata:t}),h.verbose("Created route %s",e.slug)};addRouteSharedDataToAllLocales=(e,s,t)=>{const r=[g,...this.lifecycleContext?.fs.localeFolders||[]].map(a=>({code:a,name:a}));for(const a of r){const i=M(e,g,a.code,r);this.addRouteSharedData(i,s,t)}};addApiRoute=e=>{this.apiRoutes.push(e),h.verbose("Created API route %s",e.slug)};addMcpTools=(e,s)=>{for(const t of s){const r=this.mcpToolHandlers.get(t.name);r&&r.importPath!==e&&h.warn('MCP tool "%s" from %s overwrites the tool registered from %s',t.name,e,r.importPath),this.mcpToolHandlers.set(t.name,{...t,importPath:e}),h.verbose("Created MCP tool %s",t.name)}};getMcpTools=()=>Array.from(this.mcpToolHandlers.values());markGatedMcpTools=e=>{for(const s of e){const t=this.mcpToolHandlers.get(s);t&&this.mcpToolHandlers.set(s,{...t,hasAvailabilityGate:!0})}};addSkills=e=>{for(const s of e)this.skills.set(s.slug,s),h.verbose("Discovered skill %s",s.slug)};getSkills=()=>Array.from(this.skills.values());removeMcpTools=e=>{for(const s of e)this.mcpToolHandlers.delete(s)};addMiddleware=e=>{this.middleware.push(e),h.verbose("Created middleware %s",e.id)};setResourceResponseHeaders=(e,s)=>{this.config.responseHeaders||(this.config.responseHeaders={});const t=new Set(s.map(i=>i.name.toLowerCase())),a=[...(this.config.responseHeaders[e]??[]).filter(i=>!t.has(i.name.toLowerCase())),...s];this.config.responseHeaders[e]=a};getRouteByFsPath=e=>{const s=this.routesByFsPath.get(e);return s?this.getRouteBySlug(s):void 0};getRouteBySlug=(e,s={})=>{const{followRedirect:t=!0}=s,r=this.getRedirect(e);return t&&r?this.routesBySlug.get(u(r.to)):this.routesBySlug.get(e)};hasRouteOrRedirectBySlug=e=>{if(this.routesBySlug.has(e)||x(e,this.getConfig()))return!0;const s=this.getRedirect(e);if(!s)return!1;if(!S(s.to))return!0;const t=u(s.to);return this.routesBySlug.has(t)};getRoutesByTemplateId=e=>this.newRoutes.filter(s=>s.templateId===e);getAllRoutesForLocale=(e=g)=>{const s=Array.from(this.routesBySlug.values()),t=e.toLowerCase();return s.filter(r=>e===g?!K(r.fsPath):r.slug.startsWith(`/${t}`))};getAllRoutes=()=>Array.from(this.routesBySlug.values());getAllApiRoutes=()=>this.apiRoutes;getAllMiddleware=()=>this.middleware;getTemplate=e=>this.templates.get(e);getRequestHandler=e=>this.apiRoutesRequestHandlers.get(e);createTemplate=(e,s)=>(this.templates.set(e,s),e);addBrowserPlugin=e=>{this.browserPlugins.add(e)};createRequestHandler=(e,s)=>(this.apiRoutesRequestHandlers.set(e,s),e);clearRequestHandlersByPrefix=e=>{for(const s of this.apiRoutesRequestHandlers.keys())s.startsWith(e)&&this.apiRoutesRequestHandlers.delete(s)};registerServerPropsGetter=(e,s)=>(this.serverPropsGetters.set(e,s),e);registerPagePropsGetter=(e,s)=>{this.pagePropsGetters.set(e,s)};async writeRouteStaticData(e,s){const t=await this.resolveRouteStaticData(e,s,!1);t&&j(e.slug,t,this.outdir)}async resolveRouteStaticData(e,s,t){if(this.serverMode)return q(e.slug,this.outdir);const r={...this,contentDir:this.contentDir,parseMarkdoc:({input:c,context:d,resource:f})=>this.parseMarkdoc({input:c,context:d,deps:{routeSlugs:[e.slug]},resource:f})},a=await e.getStaticData?.(e,r)||{},i=new Set(this.routesDynamicComponents.get(e.slug)),l=this.routesSharedData.get(e.slug)||{};for(const c of Object.values(l)){const d=this.sharedDataMarkdocComponents.get(c);d&&d.forEach(p=>i.add(p));const f=this.sharedDataDeps.get(c);f&&f.forEach(p=>this.addRouteSharedData(e.slug,p,p))}const o=this.getGlobalConfig("seo"),n=a?.frontmatter||{};return{...a,frontmatter:{...n,seo:{...n?.seo,title:n?.seo?.title||await e.getNavText?.()}},props:{...a.props,dynamicMarkdocComponents:Array.from(i),metadata:{...a?.props?.metadata,...e.metadata},seo:{title:O,...o,...a.props?.seo,siteUrl:o?.siteUrl},compilationErrors:this.compilationErrors},lastModified:t||!e.fsPath?null:await this.lifecycleContext?.fs.getLastModified(e.fsPath)}}addSsrComponents(e,s){if(!e?.length)return;const t=typeof e[0]=="string"?e.join(""):V(e);t&&(s==="head"?this.ssr.headTags.push(t):s==="preBody"?this.ssr.preBodyTags.push(t):this.ssr.postBodyTags.push(t))}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.skills.clear(),this.config.redirects={},this.config.wildcardRedirectsTree={},this.config.directoryPermissions={},this.ssr={preBodyTags:[],postBodyTags:[],headTags:[]}};async toJson(){const e=[];for(const[t,r]of Object.entries(E))switch(r){case"map":{const a=Array.from(this[t].entries());e.push([t,a]);break}case"object":if(t==="config"){e.push([t,await this.getConfigWithEnvPlaceholders()]);break}e.push([t,this[t]]);break;default:throw new Error("Invalid format")}const s=Object.fromEntries(e);return s[P]=G.PLAN_GATES,s}static fromJson(e,s){const t=new b(s);for(const[a,i]of Object.entries(E))switch(i){case"map":t[a]=new Map(e[a]);break;case"object":if(a==="config"){t.setGlobalConfig(e[a]);break}t[a]=e[a];break;default:throw new Error("Invalid format")}t.config[m]=X(t.config[m]||{});const r=e[P];return r&&_("PLAN_GATES",r),t}async getConfigWithEnvPlaceholders(){const e=JSON.parse(JSON.stringify(this.config));for(const s in this.replacedEnvVars){const{original:t}=this.replacedEnvVars[s],r=s.split(":"),a=r.pop(),{error:i,value:l}=y(e,r);if(i||!L(l)&&!Array.isArray(l)){await w.panicOnBuild(`Failed to replace env var with env name for ${s}`);continue}l[a]=t}return e}async reportUnsetEnvVars(){if(this.unsetEnvVars.size===0)return;const e=Array.from(this.unsetEnvVars).filter(t=>!Q.includes(t));if(e.length===0)return;const s=`Failed to resolve config. The following environment variables are not set: ${e.join(", ")}`;await w.panicOnBuildContentError(s)}}function X(C){return H(C,e=>A.Ast.fromJSON(JSON.stringify(e)))}export{b as Store,ke as USER_DEFINED_API_FUNCTIONS_COUNTER_KEY};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every file of the `static` folder, keyed by its lowercased URL path with the real URL path as the value.
|
|
3
|
+
* Built once per build; files added while developing appear after a restart.
|
|
4
|
+
*/
|
|
5
|
+
export type StaticFilePaths = Record<string, string>;
|
|
6
|
+
//# sourceMappingURL=static-files.d.ts.map
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StaticFilePaths } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Indexes the files of the `static` folder by their lowercased URL path,
|
|
4
|
+
* so a path can be looked up regardless of its casing.
|
|
5
|
+
*
|
|
6
|
+
* @param contentDir - The project content directory that holds the `static` folder.
|
|
7
|
+
* @returns The index, empty when the folder is missing.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* // static/1.0.7/Tags.yaml and static/robots.txt
|
|
11
|
+
* buildStaticFilePaths(contentDir);
|
|
12
|
+
* // Returns: { '/1.0.7/tags.yaml': '/1.0.7/Tags.yaml', '/robots.txt': '/robots.txt' }
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildStaticFilePaths(contentDir: string): StaticFilePaths;
|
|
15
|
+
//# sourceMappingURL=build-static-file-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import i from"path";import{PUBLIC_STATIC_FOLDER as s}from"../../constants/common.js";import{slash as m}from"../../../utils/path/slash.js";import{readFileNames as c}from"../fs.js";function h(a){const t=i.join(a,s),o={};for(const e of c(t)){const r="/"+m(i.relative(t,e));o[r.toLowerCase()]=r}return o}export{h as buildStaticFilePaths};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type PackageJsonSection = 'dependencies' | 'optionalDependencies' | 'peerDependencies' | 'overrides' | 'resolutions';
|
|
2
|
+
export type PackageViolation = {
|
|
3
|
+
/** The declared name; for an override, its key path joined with ` > `. */
|
|
4
|
+
name: string;
|
|
5
|
+
section: PackageJsonSection;
|
|
6
|
+
reason: 'not-allowed' | 'alias-not-allowed' | 'non-registry-source';
|
|
7
|
+
specifier: string;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The package.json entries outside `allowedPackages`, in file order. Entries are exact names or
|
|
11
|
+
* `@scope/*`; `@redocly/*` is always allowed. `devDependencies` are not checked: gated builds do
|
|
12
|
+
* not install them. Returns `[]` for a value that is not an object.
|
|
13
|
+
*/
|
|
14
|
+
export declare function findDisallowedPackages(packageJson: unknown, allowedPackages: readonly string[]): PackageViolation[];
|
|
15
|
+
export declare function describePackageViolation({ name, section, reason, specifier, }: PackageViolation): string;
|
|
16
|
+
//# sourceMappingURL=find-disallowed-packages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const p=["dependencies","optionalDependencies","peerDependencies"],y=["@redocly/*"];function E(e,n){if(!l(e))return[];const t=[...y,...n],o=s=>t.some(r=>r.endsWith("/*")?s.startsWith(r.slice(0,-1)):r===s),i=s=>{const r=m(s);return r&&!o(r.name)?"alias-not-allowed":$(r?r.version:s.trim())?null:"non-registry-source"},f=[],w=new Map([...p,"devDependencies"].flatMap(s=>g(e[s])));for(const s of p)for(const[r,a]of g(e[s])){const c=o(r)?i(a):"not-allowed";c&&f.push({name:r,section:s,reason:c,specifier:a})}const A=l(e.pnpm)?e.pnpm:{},v=[["overrides",e.overrides],["overrides",A.overrides],["resolutions",e.resolutions]];for(const[s,r]of v)for(const[a,c]of h(r,[])){const d=c.startsWith("$")?w.get(c.slice(1)):c;if(d===void 0)continue;const u=i(d);u&&f.push({name:a,section:s,reason:u,specifier:d})}return f}function L({name:e,section:n,reason:t,specifier:o}){const i=`\`${e}\` in \`${n}\``;switch(t){case"not-allowed":return`${i} is not available on this plan. Remove it from package.json or upgrade the plan.`;case"alias-not-allowed":return`${i} is an alias of \`${m(o)?.name}\`, which is not available on this plan. Remove it from package.json or upgrade the plan.`;case"non-registry-source":return`${i} must come from the npm registry, not \`${o}\`.`}}function m(e){const n=e.trim();if(!n.startsWith("npm:"))return null;const t=n.slice(4),o=t.lastIndexOf("@");return o>0?{name:t.slice(0,o),version:t.slice(o+1)}:{name:t,version:""}}const W=[".tgz",".tar",".tar.gz"];function $(e){const n=e.toLowerCase();return!e.includes(":")&&!e.includes("/")&&!e.includes("\\")&&!e.startsWith(".")&&!W.some(t=>n.endsWith(t))}function h(e,n){return typeof e=="string"?[[n.join(" > "),e]]:l(e)?Object.entries(e).flatMap(([t,o])=>h(o,t==="."?n:[...n,t])):[]}function g(e){return l(e)?Object.entries(e).filter(n=>typeof n[1]=="string"):[]}function l(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}export{L as describePackageViolation,E as findDisallowedPackages};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PRODUCT_NAME as e}from"../../config/product-gates.js";function o(){return e.toLowerCase().includes("realm")||e.toLowerCase().includes("reef")}export{o as isRealmOrReef};
|
|
1
|
+
import{PRODUCT_NAME as e}from"../../config/product-gates.js";function o(){return e.toLowerCase().includes("realm")||e.toLowerCase().includes("reef")||e.toLowerCase()==="framework"}export{o as isRealmOrReef};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as r from"path";import{cliCommandNames as e}from"../../constants/common.js";import{PUBLIC_STATIC_FOLDER as n}from"../constants/common.js";import{logger as a}from"../tools/notifiers/logger.js";import{blue as l,gray as f}from"../tools/notifiers/helpers/colors.js";import{loadEnvVariables as c}from"./envs/load-env-variables.js";import{buildStaticFilePaths as p}from"./content/build-static-file-paths.js";import{copyFolderRecursiveSync as s}from"./fs.js";import{validateInstalledVersion as E}from"./validate-installed-version.js";import{validateAllowedPackages as P}from"./validate-allowed-packages.js";import{PACKAGE_NAME as d}from"../../config/product-gates.js";import{PORTAL_VERSION as u}from"../version.js";import{setEnv as v}from"../config/env-config.js";function L(o){return o?"true":"false"}function C(o){const t={};o["log-level"]&&(t.REDOCLY_LOG_LEVEL=String(o["log-level"])),t.INSPECT_MODE="inspect"in o?L(o.inspect):"false",o.pathPrefix&&(t.REDOCLY_PREFIX_PATHS=o.pathPrefix),v(t)}function I({contentDir:o,outdir:t}){s(r.join(o,n),r.join(t,n))}async function V(o,t,i){await c(t["project-dir"]);const m=o===e.DEVELOP?" Previewing with":"Building with";switch(a.logInFooter("product",`${m} ${l(`${d}@${u}`)}`),a.logInFooter("server",` \u{1F310} Preview URL: ${f("server starting...")}`),o){case e.DEVELOP:case e.BUILD:case e.PREPARE:C(t);break;default:break}await E(),await P(),I(i),i.setStaticFilePaths(p(i.contentDir))}export{V as beforeCommand};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* LEGACY: classic team folders (`teamFolders`, `teamNamePatterns`, `teamFoldersBaseRoles`).
|
|
3
|
+
* One customer uses it. Remove this module and its callers once that customer runs
|
|
4
|
+
* on Realm Plus, which derives team rules from directories instead (`{folder}` rules).
|
|
5
|
+
*
|
|
2
6
|
* (!) We have a copy of this file in the packages/shared, so we need to keep them in sync.
|
|
3
7
|
*/
|
|
4
8
|
import type { RbacConfig, RbacScopeItems } from '@redocly/config';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getHigherRole as c}from"./rbac.js";function
|
|
1
|
+
import{getHigherRole as c}from"./rbac.js";function R(e,r){if(!e)return;if(!p(e))return e;const o={reunite:{},content:f(e)},n=i(e,r);for(const t of n)o.reunite[t.teamName]=t.projectRole,o.content={...o.content,...Object.fromEntries((e.teamFolders||[]).flatMap(a=>{const l={...e.teamFoldersBaseRoles||{authenticated:"READ"},[t.teamName]:t.projectRole,"redocly.owners":"ADMIN"},m=a.replaceAll("{teamPathSegment}",t.teamPathSegment),s=m+"/**";return[[m,l],[s,l]]}))};return{...e,reunite:{...e.reunite,...o.reunite},content:{...d(e.content||{},o.content)}}}function p(e){return!!(e.teamNamePatterns&&e.teamFolders)}function u(e,r){for(const o of e.teamNamePatterns||[]){if(!o.includes("{teamPathSegment}")&&!o.includes("{projectRole}"))continue;const n="^"+o.replace("{teamPathSegment}","(?<teamPathSegment>[a-zA-Z0-9_.-]+)").replace("{projectRole}","(?<projectRole>admin|maintain|triage|write|read|none)")+"$",a=new RegExp(n,"i").exec(r)?.groups;if(a?.projectRole||a?.teamPathSegment)return{teamName:r,projectRole:a.projectRole?.toUpperCase(),teamPathSegment:a.teamPathSegment?.toLowerCase()}}return null}function g(e,r){for(const o of e?.teamFolders||[]){if(!o.includes("{teamPathSegment}"))continue;const n=`^${o.replace("{teamPathSegment}","(?<teamPathSegment>[a-zA-Z0-9_.-]+)")}($|/)`,t=new RegExp(n,"i");for(const a of r){const l=t.exec(a)?.groups;if(l?.teamPathSegment)return{teamPathSegment:l.teamPathSegment.toLowerCase()}}}return null}function i(e,r){const o=r.map(t=>u(e,t));let n=null;for(const t of o)t?.projectRole&&!t.teamPathSegment&&(n=n?c(n,t.projectRole):t.projectRole);return o.map(t=>!t?.teamPathSegment||!t.projectRole&&!n?null:(t.projectRole=t.projectRole??n??void 0,t)).filter(Boolean)}function f(e){const r={};if(e.teamFoldersBaseRoles)for(const o of e.teamFolders){const n=o.replaceAll("{teamPathSegment}","**");r[n]=e.teamFoldersBaseRoles}return r}function d(e,r){const o={...e};for(const[n,t]of Object.entries(r))o[n]?o[n]={...o[n],...t}:o[n]=t;return o}export{p as canExpandConfig,R as expandRbacConfig,f as getTeamFolderDefaults,g as parseTeamFoldersTemplate,u as parseTeamNameTemplate,i as parseTeams};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import R from"path";import P from"picomatch";import"../node-crypto-polyfill.js";import{REDOCLY_TEAMS_RBAC as x,REDOCLY_ROUTE_RBAC as E}from"@redocly/config";import{MCP_ROUTE as U,PUBLIC_MCP_ROUTE as k}from"@redocly/theme/core/constants/mcp";import{ServerRoutes as w}from"../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as D,PUBLIC_RBAC_SCOPE_ITEM as y,RBAC_ALL_OTHER_TEAMS as l,DEFAULT_RBAC_SCOPE as L,GRAPHQL_SPEC_SLUG as M}from"../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as g,PUBLIC_API_DEFINITIONS_FOLDER as C,PUBLIC_ASSETS_FOLDER as B}from"../constants/common.js";import{MCP_CREDENTIALS_ROUTE as b}from"../constants/mcp.js";import{ANONYMOUS_AUTH_DETAILS as W}from"../constants/rbac.js";import{removeTrailingSlash as T}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as $}from"../../utils/url/remove-leading-slash.js";import{parsePathVersions as v}from"../../utils/path/parse-path-versions.js";import{reporter as Y}from"../tools/notifiers/reporter.js";import{bold as G}from"../tools/notifiers/helpers/colors.js";import{shaDirPathShort as H}from"../utils/crypto/sha-dir-path-short.js";import{isTruthy as z}from"../../utils/guards/is-truthy.js";import{canExpandConfig as K,expandRbacConfig as V,getTeamFolderDefaults as J,parseTeamFoldersTemplate as Q,parseTeamNameTemplate as X}from"./rbac-expand.js";import{getUserParamsFromCookies as Z}from"../web-server/auth.js";import{getDeeperGlobPattern as q}from"./globs.js";import{EntitlementsProvider as tt}from"../entitlements/entitlements-provider.js";const j=["NONE","READ","TRIAGE","WRITE","MAINTAIN","ADMIN"],et=new Set(["x-parsed-md-description","x-parsed-md-summary"]),rt=new Set(Object.values(w).map(t=>T(t.split(":")[0])));function It(t,e){const r=j.indexOf(t.toUpperCase()),n=j.indexOf(e.toUpperCase());return r>n?t:e}const A={};function I(t,e){if(!t?.content)return y;const r=t.content,{slug:n,fsPath:o}=e;if(!n&&!o)return y;const s=a=>{const d=`slug:${a}`,p=A[d]??P(a);A[d]=p;const _=`fsPath:${a}`,S=A[_]??P($(a));return A[_]=S,!!(n&&p(n))||!!(o&&S(o))};if(st(n||o||"")&&Object.keys(r).filter(p=>s(p)).length===0)return r[L]||y;const f=Object.keys(r).filter(a=>s(a));if(f.length==0)return y;const u=f.map(a=>P.scan(a,{tokens:!0,parts:!0}));let h=u[0];for(let a=1;a<u.length;a++)h=q(h,u[a]);return r[h.input]}function F(t,e,r){const n=r?[...e,r]:e,o=[];for(const s of n)t[s]?o.push(t[s]):t[l]&&s!==r&&o.push(t[l]);return o.some(s=>s.toLowerCase()!=="none")}function Ft(t,e,r={},n=!1){if(n&&Object.keys(r).length===0)return e.isAuthenticated;const o=r.features?.[t];return o?F(o,e.teams):!0}function Nt(t,e){return O(t,W,e.access?.rbac||{},e.access?.requiresLogin||!1)}function O(t,e={},r={},n=!1){if(t.slug&&typeof t.slug=="string"&&rt.has(T(t.slug))||(t.slug===U||t.slug===k||t.slug===b)&&tt.instance().canAccessFeature("mcp"))return!0;if(n&&Object.keys(r).length===0)return!!e.isAuthenticated;const o=V(r,e.teams||[]),s=t[x]||I(o,t[E]||{});return Object.keys(s||{}).length===0?!1:Object.keys(s).length===1&&s[l]&&s[l].toLowerCase()!=="none"?!0:F(s,e?.teams||[],e?.email)}function Ut(t,e,r,n){if(!t.startsWith(C)&&!t.startsWith(g))return!0;const o=t.replace(new RegExp(`^${C}/`),"").replace(new RegExp(`^${g}/`),"").replace(new RegExp(`^${M}/`),""),c=o==="."?"":o,i={[E]:{slug:t,fsPath:c},slug:t};return O(i,n,e,r)}function kt(t,e,r,n,o){if(!t.startsWith(B))return!0;const s=t.match(/\..{64}\.([A-Fa-f0-9]{8})\.[^.]+$/)?.[1];if(!s)return!0;const c=n[s];if(!c)return!0;const{base:i,ext:f}=R.parse(t),u=i.split(".")[0],h=f.split(".").join(""),d=c==="."?"":c,p={[E]:{slug:t,fsPath:R.posix.join(d,`${u}.${h}`)},slug:t};return O(p,o,e,r)}async function wt(t,e){const{isAuthenticated:r=!1,idpAccessToken:n,federatedAccessToken:o,federatedIdToken:s,...c}=await Z(t,e),{teams:i=[]}=c;let f;return r?f=i.filter(u=>u!==D):f=[D],{isAuthenticated:r,idpAccessToken:n,teams:f,claims:c}}function N(t,e,r={},n=!1){if(!t)return t;if(Array.isArray(t)){const o=[];for(const s of t){const c=N(s,e,r,n);c!==void 0&&o.push(c)}return o}if(typeof t=="object"){if(!O(t,e,r,n))return;let o=!1;const s={};for(const c in t){if(c===x||c===E)continue;if(et.has(c)){s[c]=t[c];continue}const i=N(t[c],e,r,n);if(!t.link&&(c==="items"||c==="menu"&&t.type==="tab")&&Array.isArray(i)&&i.length===0&&t[c].length!==0){o=!0;continue}i!==void 0&&(s[c]=i),c==="paths"&&nt(i)&&ot(i)}return o?void 0:s}return t}function Mt(t){return typeof t=="string"?t.split(" ").filter(Boolean):Array.isArray(t)?t.map(e=>e.toString()):[]}function Bt(t,e){if(!e)return;const r=e.content;if(!r)return e;const n=Object.entries(r).flatMap(([s,c])=>s===L?[[s,c]]:[[s,c]].concat(t.localeFolders.map(i=>[s.startsWith("/")?`/${i.toLocaleLowerCase()}${s}`:R.posix.join(t.localizationFolder,i,s),c]))),o=Object.fromEntries(n);return{...e,content:o}}async function bt(t,e){if(!e)return{};const r={},n=new Set(
|
|
1
|
+
import R from"path";import P from"picomatch";import"../node-crypto-polyfill.js";import{REDOCLY_TEAMS_RBAC as x,REDOCLY_ROUTE_RBAC as E}from"@redocly/config";import{MCP_ROUTE as U,PUBLIC_MCP_ROUTE as k}from"@redocly/theme/core/constants/mcp";import{ServerRoutes as w}from"../../constants/api.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as D,PUBLIC_RBAC_SCOPE_ITEM as y,RBAC_ALL_OTHER_TEAMS as l,DEFAULT_RBAC_SCOPE as L,GRAPHQL_SPEC_SLUG as M}from"../../constants/common.js";import{DEPRECATED_PUBLIC_API_DEFINITIONS_FOLDER as g,PUBLIC_API_DEFINITIONS_FOLDER as C,PUBLIC_ASSETS_FOLDER as B}from"../constants/common.js";import{MCP_CREDENTIALS_ROUTE as b}from"../constants/mcp.js";import{ANONYMOUS_AUTH_DETAILS as W}from"../constants/rbac.js";import{removeTrailingSlash as T}from"../../utils/url/remove-trailing-slash.js";import{removeLeadingSlash as $}from"../../utils/url/remove-leading-slash.js";import{parsePathVersions as v}from"../../utils/path/parse-path-versions.js";import{reporter as Y}from"../tools/notifiers/reporter.js";import{bold as G}from"../tools/notifiers/helpers/colors.js";import{shaDirPathShort as H}from"../utils/crypto/sha-dir-path-short.js";import{isTruthy as z}from"../../utils/guards/is-truthy.js";import{canExpandConfig as K,expandRbacConfig as V,getTeamFolderDefaults as J,parseTeamFoldersTemplate as Q,parseTeamNameTemplate as X}from"./rbac-expand.js";import{getUserParamsFromCookies as Z}from"../web-server/auth.js";import{getDeeperGlobPattern as q}from"./globs.js";import{EntitlementsProvider as tt}from"../entitlements/entitlements-provider.js";const j=["NONE","READ","TRIAGE","WRITE","MAINTAIN","ADMIN"],et=new Set(["x-parsed-md-description","x-parsed-md-summary"]),rt=new Set(Object.values(w).map(t=>T(t.split(":")[0])));function It(t,e){const r=j.indexOf(t.toUpperCase()),n=j.indexOf(e.toUpperCase());return r>n?t:e}const A={};function I(t,e){if(!t?.content)return y;const r=t.content,{slug:n,fsPath:o}=e;if(!n&&!o)return y;const s=a=>{const d=`slug:${a}`,p=A[d]??P(a);A[d]=p;const _=`fsPath:${a}`,S=A[_]??P($(a));return A[_]=S,!!(n&&p(n))||!!(o&&S(o))};if(st(n||o||"")&&Object.keys(r).filter(p=>s(p)).length===0)return r[L]||y;const f=Object.keys(r).filter(a=>s(a));if(f.length==0)return y;const u=f.map(a=>P.scan(a,{tokens:!0,parts:!0}));let h=u[0];for(let a=1;a<u.length;a++)h=q(h,u[a]);return r[h.input]}function F(t,e,r){const n=r?[...e,r]:e,o=[];for(const s of n)t[s]?o.push(t[s]):t[l]&&s!==r&&o.push(t[l]);return o.some(s=>s.toLowerCase()!=="none")}function Ft(t,e,r={},n=!1){if(n&&Object.keys(r).length===0)return e.isAuthenticated;const o=r.features?.[t];return o?F(o,e.teams):!0}function Nt(t,e){return O(t,W,e.access?.rbac||{},e.access?.requiresLogin||!1)}function O(t,e={},r={},n=!1){if(t.slug&&typeof t.slug=="string"&&rt.has(T(t.slug))||(t.slug===U||t.slug===k||t.slug===b)&&tt.instance().canAccessFeature("mcp"))return!0;if(n&&Object.keys(r).length===0)return!!e.isAuthenticated;const o=V(r,e.teams||[]),s=t[x]||I(o,t[E]||{});return Object.keys(s||{}).length===0?!1:Object.keys(s).length===1&&s[l]&&s[l].toLowerCase()!=="none"?!0:F(s,e?.teams||[],e?.email)}function Ut(t,e,r,n){if(!t.startsWith(C)&&!t.startsWith(g))return!0;const o=t.replace(new RegExp(`^${C}/`),"").replace(new RegExp(`^${g}/`),"").replace(new RegExp(`^${M}/`),""),c=o==="."?"":o,i={[E]:{slug:t,fsPath:c},slug:t};return O(i,n,e,r)}function kt(t,e,r,n,o){if(!t.startsWith(B))return!0;const s=t.match(/\..{64}\.([A-Fa-f0-9]{8})\.[^.]+$/)?.[1];if(!s)return!0;const c=n[s];if(!c)return!0;const{base:i,ext:f}=R.parse(t),u=i.split(".")[0],h=f.split(".").join(""),d=c==="."?"":c,p={[E]:{slug:t,fsPath:R.posix.join(d,`${u}.${h}`)},slug:t};return O(p,o,e,r)}async function wt(t,e){const{isAuthenticated:r=!1,idpAccessToken:n,federatedAccessToken:o,federatedIdToken:s,...c}=await Z(t,e),{teams:i=[]}=c;let f;return r?f=i.filter(u=>u!==D):f=[D],{isAuthenticated:r,idpAccessToken:n,teams:f,claims:c}}function N(t,e,r={},n=!1){if(!t)return t;if(Array.isArray(t)){const o=[];for(const s of t){const c=N(s,e,r,n);c!==void 0&&o.push(c)}return o}if(typeof t=="object"){if(!O(t,e,r,n))return;let o=!1;const s={};for(const c in t){if(c===x||c===E)continue;if(et.has(c)){s[c]=t[c];continue}const i=N(t[c],e,r,n);if(!t.link&&(c==="items"||c==="menu"&&t.type==="tab")&&Array.isArray(i)&&i.length===0&&t[c].length!==0){o=!0;continue}i!==void 0&&(s[c]=i),c==="paths"&&nt(i)&&ot(i)}return o?void 0:s}return t}function Mt(t){return typeof t=="string"?t.split(" ").filter(Boolean):Array.isArray(t)?t.map(e=>e.toString()):[]}function Bt(t,e){if(!e)return;const r=e.content;if(!r)return e;const n=Object.entries(r).flatMap(([s,c])=>s===L?[[s,c]]:[[s,c]].concat(t.localeFolders.map(i=>[s.startsWith("/")?`/${i.toLocaleLowerCase()}${s}`:R.posix.join(t.localizationFolder,i,s),c]))),o=Object.fromEntries(n);return{...e,content:o}}async function bt(t,e){if(!e)return{};const r={},n=new Set(t.scan().flatMap(({relativePath:o})=>{const{versionFolderPath:s}=v(o)||{},c=R.dirname(o);return s?[s,c]:c}));for(const o of n)r[H(o)]=o;return r}const m=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function nt(t){return m(t)&&Object.keys(t).length>0}function ot(t){for(const e of Object.keys(t)){const r=t[e];m(r)&&Object.keys(r).length===0&&delete t[e]}}function st(t){return t?t.split("/").filter(Boolean).some(r=>r.startsWith(".")):!1}const ct=t=>{if(t&&m(t)&&("content"in t&&m(t.content)||"reunite"in t&&m(t.reunite)||"features"in t&&m(t.features)||t.teamFolders&&t.teamNamePatterns)){const e=Object.values(t.content||{});if(e.length===0)return!0;if(e.every(m))return e.every(r=>Object.values(r).every(n=>typeof n=="string"))}return!1},Wt=async t=>{if(t){if(Object.keys(t).length===0)return{};if(ct(t))return it(t);await Y.panicOnContentError(`You are using an incorrect format of ${G("rbac:")} configuration. See: https://redocly.com/docs/realm/access`)}},it=t=>{const e={...t};if(e.content){const r={};for(const n in e.content)if(e.content[n]!==void 0){const o=T(n);r[o]=e.content[n]}e.content=r}return e};function $t(t,e){const r=t.fsPath,n=t.slug,o=[],s=K(e)&&(r||n)?Q(e,[r,n].filter(z)):null;if(s){const i=e?.teamNamePatterns?.map(f=>f.replace("{teamPathSegment}",s.teamPathSegment).replace("{projectRole}","read"))??[];o.push(...i)}const c=I(s?{content:{...J(e),...e.content}}:e,t);return o.push(...at(c)),ft(e,o)}function at(t){if(!t)return[];const e=[],r=l in t?{authenticated:t[l],anonymous:t[l]}:{};for(const[n,o]of Object.entries({...r,...t}))o.toLowerCase()!=="none"&&n!==l&&e.push(n);return e}function ft(t,e){return e.map(n=>X(t,n)??{teamName:n}).map(n=>n.projectRole&&n.projectRole!=="READ"?n.teamName?.toLowerCase().replace(n.projectRole?.toLowerCase?.()??"","read")??"":n.teamName?.toLowerCase()??"")}export{j as PROJECT_ROLES_ORDERED_BY_ACCESS_LEVEL,Bt as applyL10nToRbacConfig,kt as canAccessAsset,Ft as canAccessFeature,O as canAccessResource,Ut as canDownloadApiDefinition,ft as expandTeamsForRead,at as extractTeamsFromScopeItems,N as filterDataByAccessDeep,wt as getAuthDetailsFromCookies,It as getHigherRole,$t as getRbacTeamsListForResource,I as getScopeItemsForResource,F as hasScopeAccess,ct as isRbacConfigValid,Nt as isResourcePubliclyAccessible,it as normalizeRbacConfig,Wt as parseRbacConfig,Mt as parseTeamClaimToArray,bt as resolveDirectoryHashes};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { RedirectConfig, RedirectsConfig } from '@redocly/config';
|
|
2
|
-
import type { WildcardRedirectsTree } from '../../types';
|
|
2
|
+
import type { StaticFilePaths, WildcardRedirectsTree } from '../../types';
|
|
3
3
|
/**
|
|
4
4
|
* Looks up a redirect rule for a slug
|
|
5
5
|
*
|
|
6
6
|
* **IMPORTANT:** The `slug` parameter must be normalized before passing to this function.
|
|
7
7
|
*
|
|
8
|
-
* - For wildcard rules whose target ends with `*`, the remainder of the path is preserved
|
|
8
|
+
* - For wildcard rules whose target ends with `*`, the remainder of the path is preserved;
|
|
9
|
+
* a target found in `staticFilePaths` is replaced by that file path, with its real casing.
|
|
9
10
|
* - `from` is the matched config key (path or pattern); exposed for `followRedirectChain` rule tracking.
|
|
10
11
|
*
|
|
11
12
|
* @returns Redirect config with resolved `to`, plus `from`, or `null` if no rule matches or the rule would not change the slug.
|
|
12
13
|
*/
|
|
13
|
-
export declare function findRedirect(slug: string, redirects: RedirectsConfig, wildcardRedirectsTree: WildcardRedirectsTree): (WithRequired<RedirectConfig, 'to'> & {
|
|
14
|
+
export declare function findRedirect(slug: string, redirects: RedirectsConfig, wildcardRedirectsTree: WildcardRedirectsTree, staticFilePaths?: StaticFilePaths): (WithRequired<RedirectConfig, 'to'> & {
|
|
14
15
|
from: string;
|
|
15
16
|
}) | null;
|
|
16
17
|
//# sourceMappingURL=find-redirect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeRouteSlug as
|
|
1
|
+
import{normalizeRouteSlug as l}from"../../../utils/path/normalize-route-slug.js";import{removeLeadingSlash as u}from"../../../utils/url/remove-leading-slash.js";function w(t,n,c,e={}){const o=n[t];if(o?.to){const f=o.to;return l(f).toLowerCase()===t?null:{to:f,type:o.type,from:t}}const i=p(t,c);if(!i)return null;const a=n[i],d=a?.to;if(!d)return null;let r=d;if(r.endsWith("*")){const f=i.split("*")[0];r=r.replace(/\*$/,t.substring(f.length)),r=e[l(r).toLowerCase()]??r}return l(r).toLowerCase()===t?null:{...a,to:r,from:i}}function p(t,n){const c=u(t).split("/");let e=n;for(const o of c){if(!e[o])break;e=e[o]}return e["*"]||null}export{w as findRedirect};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import n from"node:path";import{withPathPrefix as f}from"@redocly/theme/core/utils";import{PUBLIC_STATIC_FOLDER as e}from"../constants/common.js";import{isLocalLink as p}from"../../utils/path/is-local-link.js";import{copyStaticFile as u,FileNotFoundError as x}from"./fs.js";async function w(r,o,i){if(!p(r))return r;const t=r.startsWith("/")?n.posix.join(e,r):void 0;if(t&&o.exists(t))return f(r);const c=r.startsWith("/")?r.slice(1):n.posix.join(n.dirname(i.fromFileRelativePath),r),m=o.exists(c)?o.getFileInfo(c):null;if(!m)throw new x(`Cannot resolve asset path: ${r}`,r);return u(i.contentDir,m.realRelativePath,i.outdir)}export{w as resolveAssetPath};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fails the build, or reports a problem in develop, when the plan limits npm packages and the
|
|
3
|
+
* package.json in the working directory declares one it does not allow or cannot be parsed.
|
|
4
|
+
* Does nothing without a package.json.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateAllowedPackages(): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=validate-allowed-packages.d.ts.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{readFile as i}from"node:fs/promises";import{join as c}from"node:path";import{EntitlementsProvider as s}from"../entitlements/entitlements-provider.js";import{reporter as t}from"../tools/notifiers/reporter.js";import{describePackageViolation as p,findDisallowedPackages as l}from"./find-disallowed-packages.js";async function w(){const e=s.instance();if(e.canUseAnyPackage())return;let n;try{n=await i(c(process.cwd(),"package.json"),"utf8")}catch{return}let r;try{r=m(n)}catch(a){await t.panicOnBuildContentError(`This plan allows only approved npm packages, but package.json cannot be checked: ${a.message}`);return}const o=l(r,e.getAllowedPackages());o.length!==0&&await t.panicOnBuildContentError(["This plan allows only approved npm packages in package.json:",...o.map(a=>` - ${p(a)}`)].join(`
|
|
2
|
+
`))}function m(e){return JSON.parse(e.replace(/^\uFEFF/,""))}export{w as validateAllowedPackages};
|
|
@@ -155,7 +155,9 @@ export declare const oidcJwksCache: {
|
|
|
155
155
|
jwks: Record<string, (OidcJwk & {
|
|
156
156
|
idpIds: string[];
|
|
157
157
|
}) | null>;
|
|
158
|
+
missedAt: Record<string, number>;
|
|
158
159
|
};
|
|
160
|
+
export declare const UNKNOWN_KID_RETRY_MS = 60000;
|
|
159
161
|
export declare function getOidcMetadata(idpId: string, providerConfig: OidcProviderConfig): Promise<OidcIssuerMetadata>;
|
|
160
162
|
export declare function discoverJwks(ssoConfig: SsoConfig): Promise<void>;
|
|
161
163
|
export declare function getRedoclyTokenPayload(token: string): Promise<Record<string, unknown>>;
|