import p from"node:path";import{existsSync as X}from"node:fs";import{writeFile as D,access as N,rm as k,constants as B}from"fs/promises";import{REDOCLY_ROUTE_RBAC as _,REDOCLY_TEAMS_RBAC as h}from"@redocly/config";import U from"picomatch";import{combineUrls as j}from"@redocly/theme/core/utils";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 H}from"../../../constants/common.js";import{envConfig as C}from"../../../config/env-config.js";import{logger as a}from"../../../tools/notifiers/logger.js";import{shaHexShort as Y}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 J}from"../../../utils/llmstxt/agent-feedback-llms-footer.js";import{validateLLMsTxtConfig as V,generateLLMsTxt as W}from"../llmstxt/index.js";import{ensureDir as F}from"../../../utils/fs.js";import{isResourcePubliclyAccessible as q,extractTeamsFromScopeItems as z,getRbacTeamsListForResource as Q}from"../../../utils/rbac.js";const w=20,S="llms.txt:";async function Dt(t,i,{embeddingsEnabled:o,llmstxtEnabled:n}){const c=p.join(t.outdir,H);if(!n){try{await N(c,B.W_OK),await k(c)}catch{}if(!o)return}o&&a.info("Preparing semantic documents..."),n&&a.info(`${S} Generating llms.txt files...`);const T=a.startTiming(),l=a.startTiming(),m=t.getGlobalConfig("seo"),f=m?.llmstxt,d=C.REDOCLY_EXP_LLMSTXT_AGENT_FEEDBACK_ENABLED??!1,M=p.resolve(t.outdir,G),u=t.getConfig(),O=u.access?.rbac??{},b=t.getAllRoutes(),y=u?.l10n?.defaultLocale||u?.i18n?.defaultLocale||E,I=(f?.excludeFiles||[]).map(e=>U(e)),R=[];if(await P(b,w,async e=>{if(e.excludeFromSearch)return;const v=await Z(e,t),x=await tt(e,v,i,t);if(x){if(n)for(const s of await x.getLLMsTxts()){if(I.some($=>$(s.fsPath)))continue;const g=K(s.slug),r=p.join(t.outdir,g);F(r);const L=d?J(m,s.slug):void 0,A=L?`

${L}`:"";await D(r,`${s.content}${A}`),t.setResourceResponseHeaders(g,[{name:"X-Robots-Tag",value:"noindex, follow"},...u.seo?.siteUrl?[{name:"Link",value:`<${j(u.seo.siteUrl,s.slug)}>; rel="canonical"`}]:[]]),s.includeInLLMsTxt&&q(e,u)&&R.push(s)}if(o&&C.isBuildMode){const s=await x.getSearchDocuments();if(!s.length)return;const g=et(e,O),r=e.versions?.find(({active:A})=>A),L=r&&{folder:r.folderId,label:r.label,default:r.default};await ot(s,e.fsPath,g,M,y,L)}}}),o&&a.infoTime(l,"Semantic search documents prepared"),R.length)try{V(f);const e=await W(R,f,{title:m?.title,description:m?.description},i);F(c),await D(c,e),a.infoTime(T,`${S} files generated`)}catch(e){a.error(`${S} Failed to generate llms.txt file. ${e.message}`)}}async function Z(t,i){return t.getStaticData?t.getStaticData(t,i):{}}async function tt(t,i,o,n){if(t.getAiDocumentsStore)return t.getAiDocumentsStore(t,{...i,[h]:t[h],[_]:t[_]},o,n)}function et(t,i){const o=z(t?.[h]);return o?.length?o:Q(t,i)}async function ot(t,i,o,n,c,T){await P(t,w,async l=>{const m=`${Y(i+l.content)}.json`,f=F(p.join(n,m)),d=l.locale===E?c:l.locale;X(f)||await D(f,JSON.stringify({...l,rbacTeams:o||[],version:T,locale:d}),"utf-8")})}export{Dt as prepareSemanticDocuments};
