@redocly/reef 0.131.1 → 0.131.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 +6 -0
- package/dist/server/plugins/asyncapi-docs/search/get-ai-search-documents.js +3 -3
- package/dist/server/plugins/openapi-docs/search/get-ai-search-documents.js +32 -32
- package/dist/server/plugins/search/ai-indexer/prepare-semantic-documents.js +1 -1
- package/dist/server/plugins/search/llmstxt/index.d.ts +0 -1
- package/dist/server/plugins/search/llmstxt/index.js +4 -4
- package/dist/server/utils/llmstxt/get-llms-txt-md-path-by-slug.d.ts +19 -0
- package/dist/server/utils/llmstxt/get-llms-txt-md-path-by-slug.js +1 -0
- package/dist/server/web-server/routes/dynamic-route.js +1 -1
- package/package.json +6 -6
- package/dist/server/web-server/routes/helpers/get-md-asset-pathname.d.ts +0 -2
- package/dist/server/web-server/routes/helpers/get-md-asset-pathname.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @redocly/reef
|
|
2
2
|
|
|
3
|
+
## 0.131.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4b110ce8f6: Fixed agent and crawler requests so static files such as `sitemap.xml` are served instead of a non-existent Markdown path, and the site root resolved `index.html.md` correctly instead of a hidden `.index.html.md` path.
|
|
8
|
+
|
|
3
9
|
## 0.131.1
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{basename as
|
|
1
|
+
import{basename as S}from"node:path";import{REDOCLY_TEAMS_RBAC as y}from"@redocly/config";import{isResourcePubliclyAccessible as C}from"../../../utils/rbac.js";import{getLlmsTxtMdPathBySlug as A}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{getLocaleFromRelativePath as L}from"../../../fs/utils/get-locale-from-relative-path.js";import{extractDocumentSearchFacets as j}from"./search-facets.js";import{removeMarkdownLinks as m}from"../../openapi-docs/utils.js";import{processSchema as d}from"./schema-processor.js";import{llmsTxtLink as k}from"../../search/llmstxt/index.js";const Z=({actions:n,document:e,metadata:i})=>async(t,s,r)=>{const a=t.getSidebar?.(t)||[],c=await r.getConfig(),{allSearchDocuments:o,publiclyAccessibleSearchDocuments:l}=b(t,a,e,n,i,c);if(o.length)return{async getLLMsTxts(){return l.map(f=>({slug:f.url,fsPath:t.fsPath,title:f.title,content:f.content,includeInLLMsTxt:f.includeInLLMsTxt}))},async getSearchDocuments(){return o}}};function b(n,e,i,t,s,r,a){const c=[],o=[];for(const l of e){if(l.type==="group"){const h=l.apiItemData?.type==="channel"?l:a,{allSearchDocuments:D,publiclyAccessibleSearchDocuments:P}=b(n,l.items||[],i,t,s,r,h);c.push(...D),o.push(...P)}const f=I(n,l,i,t,s,r);f&&(c.push(f),B(l,r,a)&&o.push(f))}return{allSearchDocuments:c,publiclyAccessibleSearchDocuments:o}}function I(n,e,i,t,s,r){const a=q(e,i);if(!a)return null;const c=e.link||"",o=e.httpVerb||"",l=L(n.fsPath),f=j(t,s),h=M(n,e,i,a,o,c,r);return{url:c||n.slug,fsPath:n.fsPath,content:h.trim(),title:m(a.title||"")||S(n.fsPath),locale:l,product:n.product?.name,facets:f,includeInLLMsTxt:!e.apiItemData}}function M(n,e,i,t,s,r,a){let c="";const o=m(t.title||""),l=m(t.description||"")+m(t.summary||"");return o&&(c+=`# ${o}
|
|
2
2
|
|
|
3
3
|
`),l&&(c+=`${l}
|
|
4
4
|
|
|
@@ -17,7 +17,7 @@ import{basename as C}from"node:path";import{REDOCLY_TEAMS_RBAC as y}from"@redocl
|
|
|
17
17
|
`),e+=`
|
|
18
18
|
`;return e}function T(n,e){const i=n.getSidebar?.(n)||[],t=$(i,e);if(Object.keys(t).length===0)return"";let s="";for(const[,r]of Object.entries(t))if(r.length>0)for(const a of r){const c=a.label||"Untitled",o=a.link||a.routeSlug||"";s+=`#### ${c}
|
|
19
19
|
|
|
20
|
-
`,o&&(s+=` - ${
|
|
20
|
+
`,o&&(s+=` - ${k({title:c,description:void 0,slug:A(o)})}
|
|
21
21
|
|
|
22
22
|
`)}return s}function x(n,e,i,t){const s=n.apiItemData?.id;if(!s)return"";const r=e.channels?.[s];if(!r)return"";let a="";if(r.parameters&&Object.keys(r.parameters).length>0){a+=`## Parameters
|
|
23
23
|
|
|
@@ -53,4 +53,4 @@ import{basename as C}from"node:path";import{REDOCLY_TEAMS_RBAC as y}from"@redocl
|
|
|
53
53
|
`,r.description&&(s+=`${r.description}
|
|
54
54
|
`),r.summary&&(s+=`${r.summary}
|
|
55
55
|
`),s+=`
|
|
56
|
-
`}}return s}function $(n,e){const i={};for(const t of n)t.type==="group"?t.apiItemData?.type==="channel"?V(t,i,e):E(t,i,e):t.apiItemData?.type==="channel"&&F(t,i,e);return i}function V(n,e,i){const t=n.label||"Channel";if(p(u(n),i)&&(e[t]||(e[t]=[]),e[t].push(n),n.items))for(const s of n.items)s.apiItemData?.type==="operation"&&p(u(s),i)&&e[t].push(s)}function E(n,e,i){if(n.items){const t=$(n.items,i);for(const[s,r]of Object.entries(t))e[s]||(e[s]=[]),e[s].push(...r)}}function F(n,e,i){const t=n.label||"Channel";if(p(u(n),i)&&(e[t]||(e[t]=[]),e[t].push(n),n.items))for(const s of n.items)s.apiItemData?.type==="operation"&&p(u(s),i)&&e[t].push(s)}function q(n,e){const{apiItemData:i,type:t}=n;return i?.type?w(i,e):t==="link"?_(e):null}function w(n,e){switch(n.type){case"channel":return e.channels?.[n.id]||null;case"operation":return e.operations?.[n.id]||null;default:return null}}function _(n){return{description:n.info?.description||"",title:n.info?.title||"",summary:""}}function
|
|
56
|
+
`}}return s}function $(n,e){const i={};for(const t of n)t.type==="group"?t.apiItemData?.type==="channel"?V(t,i,e):E(t,i,e):t.apiItemData?.type==="channel"&&F(t,i,e);return i}function V(n,e,i){const t=n.label||"Channel";if(p(u(n),i)&&(e[t]||(e[t]=[]),e[t].push(n),n.items))for(const s of n.items)s.apiItemData?.type==="operation"&&p(u(s),i)&&e[t].push(s)}function E(n,e,i){if(n.items){const t=$(n.items,i);for(const[s,r]of Object.entries(t))e[s]||(e[s]=[]),e[s].push(...r)}}function F(n,e,i){const t=n.label||"Channel";if(p(u(n),i)&&(e[t]||(e[t]=[]),e[t].push(n),n.items))for(const s of n.items)s.apiItemData?.type==="operation"&&p(u(s),i)&&e[t].push(s)}function q(n,e){const{apiItemData:i,type:t}=n;return i?.type?w(i,e):t==="link"?_(e):null}function w(n,e){switch(n.type){case"channel":return e.channels?.[n.id]||null;case"operation":return e.operations?.[n.id]||null;default:return null}}function _(n){return{description:n.info?.description||"",title:n.info?.title||"",summary:""}}function B(n,e,i){const t=p(u(n),e);if(n.apiItemData?.type==="operation"&&i){const s=p(u(i),e);return t&&s}return t}function u(n){return{slug:n.link||"",[y]:n[y]}}function p(n,e){return e.requiresLogin?!0:C(n,e)}export{Z as getAiDocumentsStore};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as F,join as
|
|
2
|
-
`;for(const[T,w]of $?.publiclyAccessibleTaggedSearchDocuments?.entries()||[]){if(!w.length)return;const U=s.definition.tags?.find(N=>N.name===T);
|
|
1
|
+
import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as F,join as _}from"node:path";import{toMarkdown as L}from"../../../plugins/markdown/search/to-markdown.js";import{canDownloadApiDefinition as G,isResourcePubliclyAccessible as J}from"../../../utils/rbac.js";import{PUBLIC_API_DEFINITIONS_FOLDER as q}from"../../../constants/common.js";import{DEFAULT_ANONYMOUS_VISITOR_TEAM as z}from"../../../../constants/common.js";import{getLlmsTxtMdPathBySlug as B}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{SearchIndexer as V}from"../search-indexer.js";import{getLocaleFromRelativePath as C}from"../../../fs/utils/get-locale-from-relative-path.js";import{extractDocumentSearchFacets as Y}from"./search-facets.js";import{formatDocumentMetadata as H}from"../../search/utils.js";import{llmsTxtLink as E}from"../../search/llmstxt/index.js";import{replaceFileExtension as K}from"../store-definition-bundles.js";const x=new Map,ge=({parser:s,options:c,info:t,tagOperations:r,relativePath:n,openapiContentItem:e,metadata:i,getSearchFacets:o,includeInLLMsTxt:a,excludeFromSearch:m})=>async(u,d,l)=>{if(m)return;const D=await u.getNavText?.()||F(u.fsPath),A=new V(s,c,u.baseSlug||u.slug),p=A.addItem(e);if(!p)return;const O=await l.getConfig(),S=Array.isArray(p.title)?p.title.join(" "):p.title;let g,f,$=x.get(n);if((e.type==="tag"||e.type==="section"&&e.infoDefinition)&&!$){const{all:b,publiclyAccessible:y}=ne(r.tagged,A,O),{all:T,publiclyAccessible:w}=te(r.untagged,A,O);x.set(n,{taggedSearchDocuments:new Map(b),untaggedSearchDocuments:T,publiclyAccessibleTaggedSearchDocuments:new Map(y),publiclyAccessibleUntaggedSearchDocuments:w})}$=x.get(n);const h="#";switch(e.type){case"operation":const b=A.getOperation(e);g=f=Z({title:S,security:s.definition.security,document:p,version:p.version||t.version,headingLevel:h,operation:b});break;case"section":if(e.infoDefinition){$=x.get(n),f=await M({parser:s,info:t,staticData:d,relativePath:n,headingLevel:h,pageName:D,config:O}),f+=`
|
|
2
|
+
`;for(const[T,w]of $?.publiclyAccessibleTaggedSearchDocuments?.entries()||[]){if(!w.length)return;const U=s.definition.tags?.find(N=>N.name===T);f+=j({title:U?.["x-displayName"]||T,description:U?.description,operationSearchDocuments:w,headingLevel:`${h}#`})}const y=$?.publiclyAccessibleUntaggedSearchDocuments||[];y.length&&(f+=j({title:"Other",description:void 0,operationSearchDocuments:y,headingLevel:`${h}#`})),g=await M({parser:s,info:t,staticData:d,relativePath:n,headingLevel:h,pageName:D,config:O})}else e.ast&&(f=g=L(e.ast));break;case"tag":f=j({title:S,description:e.description,operationSearchDocuments:$?.publiclyAccessibleTaggedSearchDocuments.get(e.name)||[],headingLevel:h}),g=j({title:S,description:e.description,operationSearchDocuments:[],headingLevel:h});break;case"rsrc":case"prompt":case"tool":f=I({title:S,description:e.description,name:e.name,xMcpConfig:s.definition["x-mcp"],headingLevel:h}),g=f;break}return{async getLLMsTxts(){return[{title:e.name,description:e.type==="tag"?e.description:void 0,content:f||"",slug:u.slug,fsPath:u.fsPath,includeInLLMsTxt:a}]},async getSearchDocuments(){if(e.type==="operation"||e.type==="section"&&(e.infoDefinition||e.ast)||e.type==="tag"){const b=C(u.fsPath),y=Y({...p,...i},t,o);return[{title:S,description:Array.isArray(p.text)?p.text.join(" "):p.text,content:g||"",url:p.url??u.slug,fsPath:u.fsPath,locale:b,product:u.product?.name,rbacTeams:p.rbacTeams,facets:y}]}return[]}}};async function M({parser:s,info:c,staticData:t,relativePath:r,pageName:n,headingLevel:e,config:i}){const o=H(c["x-metadata"]);let a=c.title?`${e} ${c.title}
|
|
3
3
|
|
|
4
4
|
`:`${e} ${n}
|
|
5
5
|
|
|
@@ -12,30 +12,30 @@ import{REDOCLY_TEAMS_RBAC as k}from"@redocly/config";import{basename as F,join a
|
|
|
12
12
|
`:"",e=`${e}#`,a+=o.length?`Metadata:
|
|
13
13
|
${o}
|
|
14
14
|
`:"",a+=`
|
|
15
|
-
`,a+=Q({parser:s,headingLevel:e}),a+=X({parser:s,headingLevel:e}),a+=await W({info:c,staticData:t,relativePath:
|
|
15
|
+
`,a+=Q({parser:s,headingLevel:e}),a+=X({parser:s,headingLevel:e}),a+=await W({info:c,staticData:t,relativePath:r,pageName:n,headingLevel:e,config:i}),a}function j({title:s="",description:c,operationSearchDocuments:t,headingLevel:r}){let n=`${r} ${s}
|
|
16
16
|
|
|
17
17
|
`;return c&&(n+=`${c}
|
|
18
18
|
|
|
19
|
-
`),t.length&&t.forEach(e=>{const
|
|
19
|
+
`),t.length&&t.forEach(e=>{const i=Array.isArray(e.title)?e.title.join(" "):e.title;n+=`${r}# ${i}${e.deprecated?" (deprecated)":""}
|
|
20
20
|
|
|
21
|
-
`,n+=` - ${E({title:`${e.httpMethod?.toUpperCase()} ${e.httpPath}`,description:Array.isArray(e.text)?e.text.join(" "):e.text,slug:
|
|
22
|
-
`}),n}function Q({parser:s,headingLevel:c}){const{servers:t}=s.definition;if(t&&t.length){let
|
|
21
|
+
`,n+=` - ${E({title:`${e.httpMethod?.toUpperCase()} ${e.httpPath}`,description:Array.isArray(e.text)?e.text.join(" "):e.text,slug:B(e.url)})}`,n+=`
|
|
22
|
+
`}),n}function Q({parser:s,headingLevel:c}){const{servers:t}=s.definition;if(t&&t.length){let r=`${c} Servers
|
|
23
23
|
|
|
24
|
-
`;return t.forEach(n=>{
|
|
25
|
-
`:"",
|
|
24
|
+
`;return t.forEach(n=>{r+=n.description?`${n.description}
|
|
25
|
+
`:"",r+=`\`\`\`
|
|
26
26
|
${n.url}
|
|
27
27
|
\`\`\`
|
|
28
28
|
|
|
29
|
-
`,n.variables&&(
|
|
30
|
-
`,Object.entries(n.variables).forEach(([e,
|
|
31
|
-
`,i
|
|
32
|
-
`:"",i
|
|
33
|
-
`:""}),
|
|
34
|
-
`)}),
|
|
29
|
+
`,n.variables&&(r+=`Variables:
|
|
30
|
+
`,Object.entries(n.variables).forEach(([e,i])=>{r+=`- \`${e}\`${i.description?`: ${i.description}`:""}
|
|
31
|
+
`,r+=i.default?`Default: ${JSON.stringify(i.default)}
|
|
32
|
+
`:"",r+=i.enum?`Enum: ${i.enum.map(o=>JSON.stringify(o)).join(", ")}
|
|
33
|
+
`:""}),r+=`
|
|
34
|
+
`)}),r}return""}async function W({info:s,staticData:c,relativePath:t,pageName:r,headingLevel:n,config:e}){const i=_(c.props?.outdir||"",q,K(t,".yaml"));if(G(i,e.rbac||{},e.requiresLogin||!1,{isAuthenticated:!1,teams:[z]})){let o=`${n} Download OpenAPI description
|
|
35
35
|
|
|
36
|
-
`;return o+=E({title:s.title||
|
|
36
|
+
`;return o+=E({title:s.title||r||"OpenAPI definition",description:void 0,slug:i}),o}return""}function X({parser:s,headingLevel:c}){if(!s.definition.components?.securitySchemes)return"";let t=`${c} Security
|
|
37
37
|
|
|
38
|
-
`;const{securitySchemes:
|
|
38
|
+
`;const{securitySchemes:r}=s.definition.components;return Object.keys(r).forEach(n=>{const e=r[n];e&&(t+=`${c}# ${n}
|
|
39
39
|
|
|
40
40
|
`,t+=e.description?`${e.description}
|
|
41
41
|
|
|
@@ -47,46 +47,46 @@ ${n.url}
|
|
|
47
47
|
`),e.bearerFormat&&(t+=`Bearer Format: ${e.bearerFormat}
|
|
48
48
|
`),e.flows?.implicit?.authorizationUrl&&(t+=`Authorization URL: ${e.flows.implicit?.authorizationUrl}
|
|
49
49
|
`),e.flows?.implicit?.scopes&&(t+=`Scopes:
|
|
50
|
-
`,Object.entries(e.flows?.implicit?.scopes||{}).forEach(([
|
|
50
|
+
`,Object.entries(e.flows?.implicit?.scopes||{}).forEach(([i,o])=>{t+=`- \`${i}\`: ${o}
|
|
51
51
|
`})),e.flows?.password?.tokenUrl&&(t+=`Token URL: ${e.flows.password?.tokenUrl}
|
|
52
52
|
`),e.flows?.password?.scopes&&(t+=`Scopes:
|
|
53
|
-
`,Object.entries(e.flows?.password?.scopes||{}).forEach(([
|
|
53
|
+
`,Object.entries(e.flows?.password?.scopes||{}).forEach(([i,o])=>{t+=`- \`${i}\`: ${o}
|
|
54
54
|
`})),t+=`
|
|
55
|
-
`)}),t}function Z({title:s,security:c,document:t,version:
|
|
55
|
+
`)}),t}function Z({title:s,security:c,document:t,version:r,headingLevel:n,operation:e}){const{text:i,httpMethod:o,httpPath:a,deprecated:m}=t,u=ee(t.parameters||[],`${n}#`),d=v(`${n}#`,t.parameters,e);let l=s?`${n} ${s}${m?" (deprecated)":""}
|
|
56
56
|
|
|
57
|
-
`:"";return l+=
|
|
57
|
+
`:"";return l+=i?`${i}
|
|
58
58
|
|
|
59
59
|
`:"",l+=`Endpoint: ${o?.toUpperCase()} ${a}
|
|
60
|
-
`,l+=
|
|
60
|
+
`,l+=r?`Version: ${r}
|
|
61
61
|
`:"",l+=t.security?.length?`Security: ${t.security.join(", ")}
|
|
62
62
|
`:c?.length?`Security: ${c.map(D=>D.id).join(", ")}
|
|
63
63
|
`:"",l+=`
|
|
64
64
|
`,l+=u?`${u}
|
|
65
65
|
`:"",l+=`
|
|
66
|
-
`,l+=`${
|
|
67
|
-
`)}`,l}function I({title:s,name:c,xMcpConfig:t,headingLevel:
|
|
66
|
+
`,l+=`${d.join(`
|
|
67
|
+
`)}`,l}function I({title:s,name:c,xMcpConfig:t,headingLevel:r}){const n=t?.tools.find(i=>i.name===c);if(!n)return"";let e=`${r} ${s}
|
|
68
68
|
|
|
69
69
|
`;return e+=n.description?`${n.description}
|
|
70
70
|
|
|
71
|
-
`:"",e+=`${
|
|
71
|
+
`:"",e+=`${r}# Input schema:
|
|
72
72
|
|
|
73
73
|
`,e+=`\`\`\`json
|
|
74
74
|
${JSON.stringify(n.inputSchema,null,2)}
|
|
75
75
|
\`\`\`
|
|
76
76
|
|
|
77
|
-
`,n.outputSchema&&(e+=`${
|
|
77
|
+
`,n.outputSchema&&(e+=`${r}# Output schema:
|
|
78
78
|
|
|
79
79
|
`,e+=`\`\`\`json
|
|
80
80
|
${JSON.stringify(n.outputSchema,null,2)}
|
|
81
81
|
\`\`\`
|
|
82
82
|
|
|
83
83
|
`),e}function v(s,c,t){return!c&&!t||!t?.responses?[]:t?.responses.filter(n=>!n.content?.mediaTypes[0]?.schema).map(n=>`${s} ${P(`response ${n.code} fields`)}
|
|
84
|
-
`)}function ee(s,c){const t={};for(const n of s){const e=`${n.place}${n.mediaType?` (${n.mediaType})`:""}`;t[e]=[...t[e]||[],n]}return Object.entries(t).map(([n,e])=>{const
|
|
85
|
-
`;return
|
|
86
|
-
`:"",o.enum?
|
|
87
|
-
`:o.example&&(
|
|
88
|
-
`),
|
|
84
|
+
`)}function ee(s,c){const t={};for(const n of s){const e=`${n.place}${n.mediaType?` (${n.mediaType})`:""}`;t[e]=[...t[e]||[],n]}return Object.entries(t).map(([n,e])=>{const i=e.map(o=>{const a=" ",m=[...o.path||[],o.name],u=Array.isArray(o.description)?o.description.join(" "):o.description;let d=` - \`${m.join(".")}\` (${o.type}${o.required?", required":""})
|
|
85
|
+
`;return d+=u?`${a}${u.trim()}
|
|
86
|
+
`:"",o.enum?d+=`${a}Enum: ${o.enum.map(l=>JSON.stringify(l)).join(", ")}
|
|
87
|
+
`:o.example&&(d+=`${a}Example: ${o.example}
|
|
88
|
+
`),d});return`${c} ${P(n)}:
|
|
89
89
|
|
|
90
|
-
${
|
|
90
|
+
${i.join(`
|
|
91
91
|
`)}`}).join(`
|
|
92
|
-
`)}function ne(s,c,t){const
|
|
92
|
+
`)}function ne(s,c,t){const r=[],n=[];return s.forEach((e,i)=>{const o=[],a=[];e.forEach(m=>{const u=c.addItem(m);u&&(o.push(u),R({[k]:m[k],slug:u.url},t)&&a.push(u))}),r.push([i,o]),n.push([i,a])}),{all:r,publiclyAccessible:n}}function te(s,c,t){const r=[],n=[];return s.forEach(e=>{const i=c.addItem(e);i&&(r.push(i),R({[k]:e[k],slug:i.url},t)&&n.push(i))}),{all:r,publiclyAccessible:n}}function P(s){return s.charAt(0).toUpperCase()+s.slice(1)}function R(s,c){return c.requiresLogin?!0:J(s,c)}export{ge as getAiDocumentsStore};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import p from"node:path";import{existsSync as v}from"node:fs";import{writeFile as R,access as N,rm as X,constants as $}from"fs/promises";import{REDOCLY_ROUTE_RBAC as A,REDOCLY_TEAMS_RBAC as
|
|
1
|
+
import p from"node:path";import{existsSync as v}from"node:fs";import{writeFile as R,access as N,rm as X,constants as $}from"fs/promises";import{REDOCLY_ROUTE_RBAC as A,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import b from"picomatch";import{DEFAULT_LOCALE_PLACEHOLDER as _}from"../../../../constants/common.js";import{AI_INDEX_EXPORT_FOLDER as j}from"../../../constants/plugins/search.js";import{LLMS_TXT_FILE_NAME as B}from"../../../constants/common.js";import{envConfig as k}from"../../../config/env-config.js";import{logger as s}from"../../../tools/notifiers/logger.js";import{shaHexShort as G}from"../../../utils/crypto/sha-hex-short.js";import{promiseMapLimit as P}from"../../../utils/async/promise-map-limit.js";import{getLlmsTxtMdPathBySlug as H}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{validateLLMsTxtConfig as U,generateLLMsTxt as Y}from"../llmstxt/index.js";import{ensureDir as S}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as J,extractTeamsFromScopeItems as K,getRbacTeamsListForResource as V}from"../../../utils/rbac.js";const C=20,d="llms.txt:";async function Lt(t,i,{embeddingsEnabled:e,llmstxtEnabled:r}){const n=p.join(t.outdir,B);if(!r){try{await N(n,$.W_OK),await X(n)}catch{}if(!e)return}e&&s.info("Preparing semantic documents..."),r&&s.info(`${d} Generating llms.txt files...`);const L=s.startTiming(),c=s.startTiming(),f=t.getGlobalConfig("seo"),m=f?.llmstxt,T=p.resolve(t.outdir,j),u=t.getConfig(),w=u.rbac??{},F=t.getAllRoutes(),M=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||_,y=(m?.excludeFiles||[]).map(o=>b(o)),x=[];if(await P(F,C,async o=>{if(o.excludeFromSearch)return;const O=await W(o,t),D=await q(o,O,i,t);if(D){if(r)for(const a of await D.getLLMsTxts()){if(y.some(l=>l(a.fsPath)))continue;const g=p.join(t.outdir,H(a.slug));S(g),await R(g,a.content),a.includeInLLMsTxt&&J(o,u)&&x.push(a)}if(e&&k.isBuildMode){const a=await D.getSearchDocuments();if(!a.length)return;const g=z(o,w),l=o.versions?.find(({active:I})=>I),E=l&&{folder:l.folderId,label:l.label,default:l.default};await Q(a,o.fsPath,g,T,M,E)}}}),e&&s.infoTime(c,"Semantic search documents prepared"),x.length)try{U(m);const o=await Y(x,m,{title:f?.title,description:f?.description},i);S(n),await R(n,o),s.infoTime(L,`${d} files generated`)}catch(o){s.error(`${d} Failed to generate llms.txt file. ${o.message}`)}}async function W(t,i){return t.getStaticData?t.getStaticData(t,{...i,contentDir:i.contentDir,parseMarkdoc:(e,r,n)=>i.parseMarkdoc(e,r,n)}):{}}async function q(t,i,e,r){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[h]:t[h],[A]:t[A]},e,r)}function z(t,i){const e=K(t?.[h]);return e?.length?e:V(t,i)}async function Q(t,i,e,r,n,L){await P(t,C,async c=>{const f=`${G(i+c.content)}.json`,m=S(p.join(r,f)),T=c.locale===_?n:c.locale;v(m)||await R(m,JSON.stringify({...c,rbacTeams:e||[],version:L,locale:T}),"utf-8")})}export{Lt as prepareSemanticDocuments};
|
|
@@ -11,5 +11,4 @@ export declare function llmsTxtLink({ title, description, slug, }: {
|
|
|
11
11
|
slug: LLMsTxt['slug'];
|
|
12
12
|
}): string;
|
|
13
13
|
export declare function validateLLMsTxtConfig(llmstxtConfig: SeoConfig['llmstxt']): void;
|
|
14
|
-
export declare function getLLMsTxtMdSlug(llmstxtSlug: string): string;
|
|
15
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import d from"picomatch";import{dirname as T,resolve as x}from"node:path";import{access as $,readFile as E,constants as F}from"fs/promises";import{removeTrailingSlash as w}from"../../../../utils/url/remove-trailing-slash.js";import{logger as g}from"../../../tools/notifiers/logger.js";import{withPathPrefix as y}from"@redocly/theme/core/utils";import{envConfig as I}from"../../../config/env-config.js";import{getLlmsTxtMdPathBySlug as v}from"../../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";const a="llms.txt",u="Table of contents";async function M(t,e,n={title:a,description:void 0},o){if(!e)return{title:n.title||a,description:n.description,details:void 0,sections:[{title:u,description:void 0,llmstxts:t}]};const s=e.title||n.title||a,r=e.description||n.description,i=await _(e,o),c=e.sections?.map(l=>{const{title:f,description:h,excludeFiles:m,includeFiles:L}=l,P=p(t,{excludeFiles:m,includeFiles:L});return{title:f,description:h,llmstxts:P}});return{title:s,description:r,details:i,sections:c||[{title:u,description:void 0,llmstxts:p(t,{includeFiles:["**/*"],excludeFiles:[]})}]}}async function _(t,e){const n=await e.getConfig();if(t?.details?.path&&n.configPath)try{const o=e.fs.getFileInfo(n.configPath);if(!o)throw new Error(`Config file ${n.configPath} not found`);const s=x(e.fs.cwd,T(o.relativePath),t.details.path);return await $(s,F.R_OK),E(s,"utf-8")}catch{throw new Error(`${t.details.path} is not accessible`)}if(t?.details?.content)return t.details.content}function p(t,e){const{excludeFiles:n,includeFiles:o}=e,s=n?.map(i=>d(i)),r=o?.map(i=>d(i));return t.filter(i=>s?.some(l=>l(i.fsPath))?!1:r?.some(l=>l(i.fsPath)))}async function j(t,e,n={title:a,description:void 0},o){const s=await M(t,e,n,o),r=[`# ${s.title}
|
|
2
2
|
|
|
3
3
|
`];return s.description&&r.push(`> ${s.description}
|
|
4
4
|
|
|
@@ -8,6 +8,6 @@ import a from"picomatch";import{dirname as $,resolve as x}from"node:path";import
|
|
|
8
8
|
`),i.description?r.push(`${i.description.replace(/\n+$/,"")}
|
|
9
9
|
|
|
10
10
|
`):r.push(`
|
|
11
|
-
`),i.llmstxts.forEach(c=>{r.push(` - ${
|
|
12
|
-
`)}),r.join("")}function
|
|
13
|
-
`}function
|
|
11
|
+
`),i.llmstxts.forEach(c=>{r.push(` - ${D({title:c.title,description:c.description,slug:v(c.slug)})}`)}),r.push(`
|
|
12
|
+
`)}),r.join("")}function D({title:t,description:e,slug:n}){return`[${t}](${w(I.REDOCLY_PUBLIC_URL||"")}${encodeURI(y(n))})${e?`: ${e}`:""}
|
|
13
|
+
`}function K(t){if(t?.details?.path&&t?.details?.content)throw new Error('"details.path" and "details.content" are mutually exclusive. Please use only one of them.')}export{j as generateLLMsTxt,D as llmsTxtLink,K as validateLLMsTxtConfig};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the markdown asset path used for `llms.txt` / AI agent flows from a route slug.
|
|
3
|
+
*
|
|
4
|
+
* The site root slug (`/`) maps to `index.html.md` so the home page resolves like other HTML routes;
|
|
5
|
+
* every other slug gets a `.md` suffix on the same path.
|
|
6
|
+
*
|
|
7
|
+
* @param routeSlug - URL path segment for the page (e.g. `/`, `/docs`, `/reference/petstore`)
|
|
8
|
+
* @returns Path to the corresponding markdown file (e.g. `/index.html.md`, `/docs.md`)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* getLlmsTxtMdPathBySlug('/');
|
|
12
|
+
* // returns '/index.html.md'
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* getLlmsTxtMdPathBySlug('/guides/getting-started');
|
|
16
|
+
* // returns '/guides/getting-started.md'
|
|
17
|
+
*/
|
|
18
|
+
export declare function getLlmsTxtMdPathBySlug(routeSlug: string): string;
|
|
19
|
+
//# sourceMappingURL=get-llms-txt-md-path-by-slug.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function d(t){return`${t}${t==="/"?"index.html.md":".md"}`}export{d as getLlmsTxtMdPathBySlug};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import l from"path";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as y}from"@redocly/config";import{withoutPathPrefix as z,withPathPrefix as G}from"@redocly/theme/core/utils";import{CACHE_CONTROL_NO_CACHE_HEADER_VALUE as I,DEFAULT_IMMUTABLE_CACHE_MAX_AGE as Y}from"../../constants/common.js";import{removeTrailingSlash as $}from"../../../utils/url/remove-trailing-slash.js";import{findInIterable as k}from"../../../utils/collection/find-in-iterable.js";import{sanitizeRedirectPathname as N}from"../../../utils/url/sanitize-redirect-pathname.js";import{envConfig as W}from"../../config/env-config.js";import{sanitizePath as X}from"../../../utils/path/sanitize-path.js";import{normalizeRouteSlug as j}from"../../../utils/path/normalize-route-slug.js";import{isPathInFolder as V}from"../../../utils/path/is-path-in-folder.js";import{getLlmsTxtMdPathBySlug as Z}from"../../utils/llmstxt/get-llms-txt-md-path-by-slug.js";import{removeLeadingSlash as S}from"../../../utils/url/remove-leading-slash.js";import{processRedirects as J}from"./helpers/process-redirects.js";import{renderPage as K,getServerProps as Q}from"../../ssr/index.js";import{canAccessAsset as x,canAccessResource as T}from"../../utils/rbac.js";import{handleErrorPageRender as U,handleUnauthorized as M,handleUnauthorizedAsset as b}from"../utils.js";import{DEFAULT_MAX_AGE_FOR_MIME_TYPE as ee,MIME_TYPES as te}from"../mime-types.js";import{fileExistsAsync as q}from"../../utils/index.js";import{isAiAgentRequest as ne}from"../../utils/ai-agent-detection.js";import{getRedirectRoute as oe}from"../utils/legacy-openapi-redirects.js";import{telemetry as re}from"../../../cli/telemetry/index.js";import{telemetry as ie}from"../../telemetry/index.js";function be(e,v,D){return async n=>{const A=n.get("logger"),i=n.req,a=new URL(i.url),r=z(X(decodeURIComponent(a.pathname))),R=l.parse(r).ext===".md",C=ne({accept:i.header("accept"),signatureAgent:i.header("signature-agent"),signature:i.header("signature"),signatureInput:i.header("signature-input"),userAgent:i.header("user-agent")}),c=j(r),o=(i.method==="GET"||i.method==="HEAD")&&!R?e.getRouteBySlug(c,{followRedirect:!1})||k(e.routesBySlug?.values(),t=>t.hasClientRoutes&&(r===t.slug||r.startsWith(t.slug+"/"))):void 0,E=e.getRedirect(c);if(E){const t=J({redirect:E,reqUrlSearch:a.search});return ie.sendRedirectMessage([{object:"redirect",from:c,templateId:t.type.toString()}]),n.newResponse(null,t.type,{Location:t.location})}const g=W.isProductionEnv?301:302;if(o?.metadata?.type==="openapi"){const t=oe(a.pathname);if(t)return A.info("Legacy OpenAPI docs redirect from "+a.pathname),n.newResponse(null,g,{Location:encodeURI(t)});if(a.pathname.match(/[A-Z]/))return A.warn("Redirect to lowercase route to avoid 404 error"),n.newResponse(null,g,{Location:encodeURI(a.pathname.toLowerCase())})}if(r.endsWith("/")&&r!=="/"){const t=N(new URL(c||"/",n.req.url).pathname);return n.newResponse(null,g,{Location:encodeURI(G((t==="/"?"/":$(t))+a.search))})}const u=o&&C?Z(o.slug):void 0,w=u?await q(l.resolve(e.outdir,S(u))):!1,{isAuthenticated:d,teams:f,claims:{email:p}}=n.get("auth");if(o&&!T(o,{isAuthenticated:d,email:p,teams:f},e.config.rbac,e.config.requiresLogin))return d?U(n,e,{slug:o.slug,[y]:o[y],[_]:o[_]},403):M(n,e,o.slug);if(o&&(!C||!w)){const t=await v(o),m=await Q(o,n,t,e),{html:B,statusCode:H}=await K(o,m,n,e,re);return n.html(B,H,{"Cache-Control":I})}const L=u&&w?u:r,O=S(L),s=l.resolve(e.outdir,O);if(!V(s,e.outdir))return b(n);if(R){const t=r==="index.html.md"?"/":r.replace(/\.md$/,""),m=e.getRouteBySlug(t,{followRedirect:!1});if(m&&!T(m,{isAuthenticated:d,email:p,teams:f},e.config.rbac,e.config.requiresLogin))return M(n,e,r)}if(!x(L,e.getGlobalConfig("rbac"),e.getGlobalConfig("requiresLogin"),e.getGlobalConfig("directoryPaths"),{isAuthenticated:d,email:p,teams:f}))return b(n);const P=te[l.extname(s)]||"text/plain",h=s.match(/assets\/.*\.[a-f0-9]{8,}\..+/)||s.match(/runtime\/chunks\/.*/)?Y:ee[P],F=h?{"Cache-Control":`public, max-age=${h}, immutable`,Expires:new Date(Date.now()+h*1e3).toUTCString()}:{"Cache-Control":I};if(await q(s)){const t=i.query("download")!=null,m=await D(s);return n.newResponse(m,200,{"Content-Type":P,"Access-Control-Allow-Origin":"*",...F,...t&&{"Content-Disposition":`attachment; filename="${l.basename(s)}"`}})}else return U(n,e,{slug:c},404)}}export{be as dynamicRouteHandler};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/reef",
|
|
3
|
-
"version": "0.131.
|
|
3
|
+
"version": "0.131.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -91,14 +91,14 @@
|
|
|
91
91
|
"xpath": "0.0.34",
|
|
92
92
|
"yaml-ast-parser": "0.0.43",
|
|
93
93
|
"zod": "^3.25.76",
|
|
94
|
-
"@redocly/asyncapi-docs": "1.8.1",
|
|
95
|
-
"@redocly/openapi-docs": "3.19.1",
|
|
96
|
-
"@redocly/portal-plugin-mock-server": "0.16.1",
|
|
97
94
|
"@redocly/config": "0.44.1",
|
|
98
95
|
"@redocly/realm-asyncapi-sdk": "0.9.0",
|
|
96
|
+
"@redocly/asyncapi-docs": "1.8.1",
|
|
99
97
|
"@redocly/portal-legacy-ui": "0.14.0",
|
|
100
|
-
"@redocly/
|
|
101
|
-
"@redocly/theme": "0.63.0"
|
|
98
|
+
"@redocly/portal-plugin-mock-server": "0.16.1",
|
|
99
|
+
"@redocly/theme": "0.63.0",
|
|
100
|
+
"@redocly/openapi-docs": "3.19.1",
|
|
101
|
+
"@redocly/graphql-docs": "1.8.0"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
104
|
"react": "^19.2.4",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function d(t,e,r){return e&&!r?t==="/"?"index.html.md":t+".md":t}export{d as getMdAssetPathname};
|