@redocly/realm 0.135.1 → 0.135.2
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
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @redocly/realm
|
|
2
2
|
|
|
3
|
+
## 0.135.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c6f35a51db4: Hardened access control of `llms.txt` on the homepage Markdown page.
|
|
8
|
+
- c6f35a51db4: Improved response time on sites with many pages that use the `llms.txt` feature.
|
|
9
|
+
|
|
3
10
|
## 0.135.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import L from"node:path";import{existsSync as N}from"node:fs";import{writeFile as R,access as X,rm as B,constants as k}from"fs/promises";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import j from"picomatch";import{DEFAULT_LOCALE_PLACEHOLDER as E}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as G}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as Y}from"../../../constants/common.js";import{envConfig as C}from"../../../config/env-config.js";import{logger as r}from"../../../tools/notifiers/logger.js";import{shaHexShort as H}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as P}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as K}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{buildAgentFeedbackLlmsFooter as U}from"../../../utils/llmstxt/agent-feedback-llms-footer.js";import{validateLLMsTxtConfig as J,generateLLMsTxt as V}from"../llmstxt/index.js";import{ensureDir as F}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as W,extractTeamsFromScopeItems as q,getRbacTeamsListForResource as z}from"../../../utils/rbac.js";const w=20,S="llms.txt:";async function At(t,i,{embeddingsEnabled:o,llmstxtEnabled:s}){const c=L.join(t.outdir,Y);if(!s){try{await X(c,k.W_OK),await B(c)}catch{}if(!o)return}o&&r.info("Preparing semantic documents..."),s&&r.info(`${S} Generating llms.txt files...`);const p=r.startTiming(),l=r.startTiming(),m=t.getGlobalConfig("seo"),f=m?.llmstxt,T=C.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED??!1,M=L.resolve(t.outdir,G),u=t.getConfig(),O=u.access?.rbac??{},y=t.getAllRoutes(),b=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||E,I=(f?.excludeFiles||[]).map(e=>j(e)),d=[];if(await P(y,w,async e=>{if(e.excludeFromSearch)return;const $=await Q(e,t),x=await Z(e,$,i,t);if(x){if(s)for(const n of await x.getLLMsTxts()){if(I.some(v=>v(n.fsPath)))continue;const A=K(n.slug),a=L.join(t.outdir,A);F(a);const g=T?U(m,n.slug):void 0,D=g?`
|
|
2
2
|
|
|
3
|
-
${
|
|
3
|
+
${g}`:"";await R(a,`${n.content}${D}`),n.includeInLLMsTxt&&W(e,u)&&d.push(n)}if(o&&C.isBuildMode){const n=await x.getSearchDocuments();if(!n.length)return;const A=tt(e,O),a=e.versions?.find(({active:D})=>D),g=a&&{folder:a.folderId,label:a.label,default:a.default};await et(n,e.fsPath,A,M,b,g)}}}),o&&r.infoTime(l,"Semantic search documents prepared"),d.length)try{J(f);const e=await V(d,f,{title:m?.title,description:m?.description},i);F(c),await R(c,e),r.infoTime(p,`${S} files generated`)}catch(e){r.error(`${S} Failed to generate llms.txt file. ${e.message}`)}}async function Q(t,i){return t.getStaticData?t.getStaticData(t,i):{}}async function Z(t,i,o,s){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[h]:t[h],[_]:t[_]},o,s)}function tt(t,i){const o=q(t?.[h]);return o?.length?o:z(t,i)}async function et(t,i,o,s,c,p){await P(t,w,async l=>{const m=`${H(i+l.content)}.json`,f=F(L.join(s,m)),T=l.locale===E?c:l.locale;N(f)||await R(f,JSON.stringify({...l,rbacTeams:o||[],version:p,locale:T}),"utf-8")})}export{At as prepareSemanticDocuments};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import m from"path";import{REDOCLY_ROUTE_RBAC as
|
|
1
|
+
import m from"path";import{REDOCLY_ROUTE_RBAC as M,REDOCLY_TEAMS_RBAC as S}from"@redocly/config";import{combineUrls as V,withoutPathPrefix as W,withPathPrefix as Z}from"@redocly/theme/core/utils";import{CACHE_CONTROL_NO_STORE_HEADER_VALUE as D,CACHE_CONTROL_PUBLIC_HTML as J,DEFAULT_IMMUTABLE_CACHE_MAX_AGE as K,X_REDOCLY_CACHE_CONTROL_HEADER as Q,X_REDOCLY_CACHE_CONTROL_PUBLIC_HTML as x}from"../../constants/common.js";import{removeTrailingSlash as ee}from"../../../utils/url/remove-trailing-slash.js";import{findInIterable as te}from"../../../utils/collection/find-in-iterable.js";import{sanitizeRedirectPathname as ne}from"../../../utils/url/sanitize-redirect-pathname.js";import{envConfig as oe}from"../../config/env-config.js";import{sanitizePath as re}from"../../../utils/path/sanitize-path.js";import{normalizeRouteSlug as ie}from"../../../utils/path/normalize-route-slug.js";import{isPathInFolder as ae}from"../../../utils/path/is-path-in-folder.js";import{getLlmsTxtMdPathBySlug as se}from"../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{removeLeadingSlash as H}from"../../../utils/url/remove-leading-slash.js";import{processRedirects as ce}from"./helpers/process-redirects.js";import{renderPage as le,getServerProps as me}from"../../ssr/index.js";import{canAccessAsset as ue,canAccessResource as q}from"../../utils/rbac.js";import{handleErrorPageRender as v,handleUnauthorized as B,handleUnauthorizedAsset as F}from"../utils.js";import{DEFAULT_MAX_AGE_FOR_MIME_TYPE as de,MIME_TYPES as ge}from"../mime-types.js";import{fileExistsAsync as z}from"../../utils/index.js";import{isAiAgentRequest as fe}from"../../utils/ai-agent-detection.js";import{getRedirectRoute as pe}from"../utils/legacy-openapi-redirects.js";import{getContentTypeHeaderValue as he}from"../utils/content-type.js";import{telemetry as Re}from"../../../cli/telemetry/index.js";import{telemetry as Ce}from"../../telemetry/index.js";function $e(e,Y,G){return async n=>{const A=n.get("logger"),i=n.req,a=new URL(i.url),r=W(re(decodeURIComponent(a.pathname))),E=m.parse(r).ext===".md",L=fe({accept:i.header("accept"),signatureAgent:i.header("signature-agent"),signature:i.header("signature"),signatureInput:i.header("signature-input"),userAgent:i.header("user-agent")}),c=ie(r),o=(i.method==="GET"||i.method==="HEAD")&&!E?e.getRouteBySlug(c,{followRedirect:!1})||te(e.routesBySlug?.values(),t=>t.hasClientRoutes&&(r===t.slug||r.startsWith(t.slug+"/"))):void 0,_=e.getRedirect(c);if(_){const t=ce({redirect:_,reqUrlSearch:a.search});return Ce.sendRedirectMessage([{object:"redirect",from:c,templateId:t.type.toString()}]),n.newResponse(null,t.type,{Location:t.location})}const f=oe.isProductionEnv?301:302;if(o?.metadata?.type==="openapi"){const t=pe(a.pathname);if(t)return A.info("Legacy OpenAPI docs redirect from "+a.pathname),n.newResponse(null,f,{Location:encodeURI(t)});if(a.pathname.match(/[A-Z]/))return A.warn("Redirect to lowercase route to avoid 404 error"),n.newResponse(null,f,{Location:encodeURI(a.pathname.toLowerCase())})}if(r.endsWith("/")&&r!=="/"){const t=ne(new URL(c||"/",n.req.url).pathname);return n.newResponse(null,f,{Location:encodeURI(Z((t==="/"?"/":ee(t))+a.search))})}const u=o&&L?se(o.slug):void 0,w=u?await z(m.resolve(e.outdir,H(u))):!1,{isAuthenticated:d,teams:p,claims:{email:h}}=n.get("auth");if(o&&!q(o,{isAuthenticated:d,email:h,teams:p},e.config.access?.rbac,e.config.access?.requiresLogin))return d?v(n,e,{slug:o.slug,[S]:o[S],[M]:o[M]},403):B(n,e,o.slug);if(o&&(!L||!w)){const t=await Y(o),C=await me(o,n,t,e),{html:k,statusCode:y,error:$}=await le(o,C,n,e,Re),b=e.config.access?.rbac,O=!e.config.access?.requiresLogin&&(!b||!Object.keys(b).length),I=y>=400||!!$||!!e.compilationErrors?.length,j=O&&!I;let g;return I?g=D:O?g=J:g="private",n.html(k,y,{"Cache-Control":g,...j&&{[Q]:x}})}const P=u&&w?u:r,N=H(P),s=m.resolve(e.outdir,N);if(!ae(s,e.outdir))return F(n);let l;if(E){const t=r==="/index.html.md"?"/":r.replace(/\.md$/,"");if(l=e.getRouteBySlug(t,{followRedirect:!1}),l&&!q(l,{isAuthenticated:d,email:h,teams:p},e.config.access?.rbac,e.config.access?.requiresLogin))return B(n,e,r)}const T=e.getGlobalConfig("access");if(!ue(P,T?.rbac||{},T?.requiresLogin||!1,e.getGlobalConfig("directoryPaths"),{isAuthenticated:d,email:h,teams:p}))return F(n);const U=ge[m.extname(s)]||"text/plain",R=s.match(/assets\/.*\.[a-f0-9]{8,}\..+/)||s.match(/runtime\/chunks\/.*/)?K:de[U],X=R?{"Cache-Control":`public, max-age=${R}, immutable`,Expires:new Date(Date.now()+R*1e3).toUTCString()}:{"Cache-Control":D};if(await z(s)){const t=i.query("download")!=null,C=await G(s);return n.newResponse(C,200,{"Content-Type":he(U),"Access-Control-Allow-Origin":"*",...X,...l&&{"X-Robots-Tag":"noindex, follow",...e.config.seo?.siteUrl&&{Link:`<${V(e.config.seo.siteUrl,l.slug)}>; rel="canonical"`}},...t&&{"Content-Disposition":`attachment; filename="${m.basename(s)}"`}})}else return v(n,e,{slug:c},404)}}export{$e as dynamicRouteHandler};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/realm",
|
|
3
|
-
"version": "0.135.
|
|
3
|
+
"version": "0.135.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -93,14 +93,14 @@
|
|
|
93
93
|
"xpath": "0.0.34",
|
|
94
94
|
"yaml-ast-parser": "0.0.43",
|
|
95
95
|
"zod": "^3.25.76",
|
|
96
|
-
"@redocly/config": "0.50.1",
|
|
97
96
|
"@redocly/asyncapi-docs": "1.12.1",
|
|
98
|
-
"@redocly/
|
|
97
|
+
"@redocly/portal-legacy-ui": "0.18.0",
|
|
99
98
|
"@redocly/graphql-docs": "1.12.1",
|
|
100
99
|
"@redocly/realm-asyncapi-sdk": "0.13.0",
|
|
101
100
|
"@redocly/theme": "0.67.0",
|
|
102
101
|
"@redocly/portal-plugin-mock-server": "0.20.1",
|
|
103
|
-
"@redocly/
|
|
102
|
+
"@redocly/config": "0.50.1",
|
|
103
|
+
"@redocly/openapi-docs": "3.23.1"
|
|
104
104
|
},
|
|
105
105
|
"peerDependencies": {
|
|
106
106
|
"react": "^19.2.4",
|