import M from"@markdoc/markdoc";import*as S from"path";import{GATED_MARKDOC_TAGS as O}from"../../constants/entitlements.js";import{logger as F}from"../../tools/notifiers/logger.js";import{reporter as N}from"../../tools/notifiers/reporter.js";import{sha1 as G}from"../../utils/crypto/sha1.js";import{formatMarkdocError as H}from"./errors.js";import{extractFirstHeading as j,visit as K}from"./markdoc/plugins/utils.js";import{attributeResolvers as y}from"./attribute-resolvers/index.js";import{MdResolveError as $}from"./attribute-resolvers/md-resolve-error.js";import{processHtmlTokens as U}from"./html/process-html-tokens.js";import{resolveRawPartials as W}from"./markdoc/resolve-raw-partials.js";import{EntitlementsProvider as Y}from"../../entitlements/entitlements-provider.js";import{MARKDOC_PARTIALS_DEPS_KEY as B}from"../../constants/common.js";import{getLinkOriginalAttrName as V}from"./attribute-resolvers/utils.js";const q="EMPTY";async function C(a,s,e){const n=Y.instance(),{actions:m}=e,{relativePath:i,resolveErrors:E}=a,k=new Set,g=new Set,b=new Set,c=new Set,u={},f=new Set,w={},_={};function R(t,P){const D=P||q;t[D]=(t[D]||0)+1}const A=[];return a.resolveErrors.length=0,K(a.ast,t=>{const P=D();A.push(P.then(r=>{r?.sharedDataIds&&r.sharedDataIds.forEach(d=>k.add(d))}).catch(z));async function D(){const r=[];switch(t.type){case"fence":R(w,t.attributes.language);break;case"link":case"image":await y.nativeMdLink(t,t.type==="link"?"href":"src",i,e);break;case"tag":if(!t.tag)break;const d=s?.tags?.[t.tag];if(!d){O[t.tag]&&!n.canAccessFeature(O[t.tag])&&(t.errors.push({level:"warning",id:"invalid-tag",message:`Undefined tag: ${t.tag}`}),t.tag="",t.type="error",t.attributes={});break}const v=t.tag==="html"?t.attributes.name:t.tag;if((t.tag==="html"?f:c).add(v),u[v]=(u[v]||0)+1,v==="code-snippet"&&R(w,t.attributes.language),d.attributes?.__idx&&(t.attributes.__idx=u[t.tag]),d.dynamicComponentLib&&g.add(d.dynamicComponentLib),!d.attributes)break;if(v==="partial"&&t.attributes?.file){const o=V("file"),l=t[o]||t.attributes.file,h=l.startsWith("/")?l.slice(1):S.posix.normalize(S.posix.join(S.posix.dirname(i),l));b.add(h);const p=(m.getGlobalConfig(B)||{})[h];if(p?.dynamicComponents)for(const L of p.dynamicComponents)g.add(L);if(p?.sharedDataDeps)for(const L of p.sharedDataDeps)k.add(L)}for(const[o,l]of Object.entries(d.attributes)){const h=l.type;if(h&&(h.resolver||l.resolver)){const T=y[h.resolver||l.resolver],p=await T?.(t,o,i,e);p?.sharedDataId&&r.push(p.sharedDataId)}}if(v==="code-walkthrough")for(const o of t.attributes.resolvedFilesets||[])for(const l of o.files||[])R(_,l.language);const I=t.attributes?.attrs;if(I&&t.tag==="html")for(const o of Object.keys(I))o==="src"||o==="srcSet"?await y.htmlSourceAttribute(t,o,i,e):o==="href"&&await y.htmlHref(t,o,i,e);break}return{sharedDataIds:r}}async function z(r){if(!(r instanceof $)){await N.panicOnBuild(r.message);return}E.push(H({type:"resolve_link",meta:{...r.meta,link:r.meta.link??r.meta.rawLink},lines:t.lines,location:t.location,error:{id:"",level:"error",message:r.message,location:t.location}},a.relativePath,a.rawContent))}}),await Promise.all(A),a.sharedDataDeps=k,a.dynamicMarkdocComponents=g,a.validatedAtRevision<m.buildRevision&&(a.markdocErrors=M.validate(a.ast,s).map(t=>H(t,i,a.rawContent)),a.validatedAtRevision=m.buildRevision),{sharedDataDeps:a.sharedDataDeps,dynamicMarkdocComponents:Array.from(a.dynamicMarkdocComponents?.values()??[]),partials:Array.from(b),tagList:Array.from(c),htmlTagsList:Array.from(f),tagOccurrence:u,codeSnippetLanguages:w,codeWalkthroughLanguages:_}}const x=new M.Tokenizer({html:!0,allowIndentation:!0,allowComments:!0});x.parser.block.ruler.getRules("reference").length=0;function J(a,s){const e=x.tokenize(s),n=U(e);return{ast:M.parse(n,{file:a,slots:!0}),rawContent:s,resolveErrors:[],markdocErrors:[],relativePath:a,sharedDataDeps:void 0,validatedAtRevision:-1}}async function dt(a,s){const{data:e}=await s.cache.load(a,"markdown-ast");return j(e.ast)}async function gt(a,s){N.clearMarkdocProblems();const e=a.getAllRoutes();let n=0;const m=F.isInteractive();for(const i of e)await a.resolveRouteStaticData(i,s,!0),n++,m&&n%100===0&&F.logInFooter("validate",`  \u{1F50D} Status: validating markdoc (${n}/${e.length})`)}async function ut(a,s,e,n){const m=a.content?G(a.content):"";return await e.context.cache.load(n||a.relativePath,{loader:E,name:"markdown-inline-parser"},[m,String(e.actions.buildRevision)]);async function E(k,g,b){let c;if(a.content){const f=await g.getConfig(),w=await W(a.content,a.relativePath,f.markdown?.partialsFolders,g);c=J(a.relativePath,w)}else c=(await g.cache.load(a.relativePath,"markdown-ast")).data;let u={};if(e.actions.buildRevision!==0&&(u=await C(c,s,e)),!a.isVirtual){for(const f of c.markdocErrors)b(f);for(const f of c.resolveErrors)b(f)}return{ast:c.ast,info:u}}}export{dt as extractMdFirstHeading,J as getAst,ut as parseAndResolveMarkdoc,C as resolveAndValidateMarkdoc,gt as validateAllMarkdowns};
