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