docs-cache 0.4.2 → 0.5.1

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.
Files changed (90) hide show
  1. package/dist/cli.mjs +20 -16
  2. package/dist/esm/api.d.ts +14 -0
  3. package/dist/esm/api.mjs +14 -0
  4. package/dist/esm/cache/cache-layout.d.ts +1 -0
  5. package/dist/esm/cache/cache-layout.mjs +12 -0
  6. package/dist/esm/cache/lock.d.ts +21 -0
  7. package/dist/esm/cache/lock.mjs +91 -0
  8. package/dist/esm/cache/manifest.d.ts +11 -0
  9. package/dist/esm/cache/manifest.mjs +68 -0
  10. package/dist/esm/cache/materialize.d.ts +26 -0
  11. package/dist/esm/cache/materialize.mjs +442 -0
  12. package/dist/esm/cache/targets.d.ts +19 -0
  13. package/dist/esm/cache/targets.mjs +66 -0
  14. package/dist/esm/cache/toc.d.ts +12 -0
  15. package/dist/esm/cache/toc.mjs +167 -0
  16. package/dist/esm/cli/exit-code.d.ts +11 -0
  17. package/dist/esm/cli/exit-code.mjs +5 -0
  18. package/dist/esm/cli/index.d.ts +5 -0
  19. package/dist/esm/cli/index.mjs +345 -0
  20. package/dist/esm/cli/live-output.d.ts +12 -0
  21. package/dist/esm/cli/live-output.mjs +30 -0
  22. package/dist/esm/cli/parse-args.d.ts +13 -0
  23. package/dist/esm/cli/parse-args.mjs +295 -0
  24. package/dist/esm/cli/run.d.ts +1 -0
  25. package/dist/esm/cli/run.mjs +2 -0
  26. package/dist/esm/cli/task-reporter.d.ts +32 -0
  27. package/dist/esm/cli/task-reporter.mjs +122 -0
  28. package/dist/esm/cli/types.d.ts +51 -0
  29. package/dist/esm/cli/types.mjs +0 -0
  30. package/dist/esm/cli/ui.d.ts +21 -0
  31. package/dist/esm/cli/ui.mjs +64 -0
  32. package/dist/esm/commands/add.d.ts +20 -0
  33. package/dist/esm/commands/add.mjs +81 -0
  34. package/dist/esm/commands/clean-git-cache.d.ts +10 -0
  35. package/dist/esm/commands/clean-git-cache.mjs +48 -0
  36. package/dist/esm/commands/clean.d.ts +10 -0
  37. package/dist/esm/commands/clean.mjs +27 -0
  38. package/dist/esm/commands/init.d.ts +19 -0
  39. package/dist/esm/commands/init.mjs +179 -0
  40. package/dist/esm/commands/prune.d.ts +11 -0
  41. package/dist/esm/commands/prune.mjs +52 -0
  42. package/dist/esm/commands/remove.d.ts +12 -0
  43. package/dist/esm/commands/remove.mjs +87 -0
  44. package/dist/esm/commands/status.d.ts +16 -0
  45. package/dist/esm/commands/status.mjs +78 -0
  46. package/dist/esm/commands/sync.d.ts +33 -0
  47. package/dist/esm/commands/sync.mjs +730 -0
  48. package/dist/esm/commands/verify.d.ts +11 -0
  49. package/dist/esm/commands/verify.mjs +120 -0
  50. package/dist/esm/config/index.d.ts +15 -0
  51. package/dist/esm/config/index.mjs +196 -0
  52. package/dist/esm/config/io.d.ts +30 -0
  53. package/dist/esm/config/io.mjs +112 -0
  54. package/dist/esm/config/schema.d.ts +171 -0
  55. package/dist/esm/config/schema.mjs +69 -0
  56. package/dist/esm/errors.d.ts +3 -0
  57. package/dist/esm/errors.mjs +2 -0
  58. package/dist/esm/git/cache-dir.d.ts +16 -0
  59. package/dist/esm/git/cache-dir.mjs +23 -0
  60. package/dist/esm/git/fetch-source.d.ts +19 -0
  61. package/dist/esm/git/fetch-source.mjs +477 -0
  62. package/dist/esm/git/redact.d.ts +1 -0
  63. package/dist/esm/git/redact.mjs +4 -0
  64. package/dist/esm/git/resolve-remote.d.ts +15 -0
  65. package/dist/esm/git/resolve-remote.mjs +87 -0
  66. package/dist/esm/git/resolve-repo.d.ts +5 -0
  67. package/dist/esm/git/resolve-repo.mjs +52 -0
  68. package/dist/esm/gitignore.d.ts +18 -0
  69. package/dist/esm/gitignore.mjs +80 -0
  70. package/dist/esm/paths.d.ts +8 -0
  71. package/dist/esm/paths.mjs +34 -0
  72. package/dist/esm/source-id.d.ts +1 -0
  73. package/dist/esm/source-id.mjs +29 -0
  74. package/dist/esm/types/sync.d.ts +25 -0
  75. package/dist/esm/types/sync.mjs +0 -0
  76. package/package.json +138 -91
  77. package/dist/chunks/add.mjs +0 -3
  78. package/dist/chunks/clean-git-cache.mjs +0 -2
  79. package/dist/chunks/clean.mjs +0 -2
  80. package/dist/chunks/init.mjs +0 -3
  81. package/dist/chunks/prune.mjs +0 -2
  82. package/dist/chunks/remove.mjs +0 -3
  83. package/dist/chunks/status.mjs +0 -2
  84. package/dist/chunks/sync.mjs +0 -9
  85. package/dist/chunks/verify.mjs +0 -2
  86. package/dist/shared/docs-cache.BSvQNKuf.mjs +0 -2
  87. package/dist/shared/docs-cache.DH8jN6rl.mjs +0 -5
  88. package/dist/shared/docs-cache.Oi01HUbh.mjs +0 -6
  89. package/dist/shared/docs-cache.bWkgSdUq.mjs +0 -3
  90. package/dist/shared/docs-cache.kK1DPQIQ.mjs +0 -2
@@ -1,9 +0,0 @@
1
- import{createHash as L,randomBytes as Pe}from"node:crypto";import{mkdtemp as X,rm as R,mkdir as H,readFile as A,writeFile as re,access as _,rename as W,open as J,lstat as xe,symlink as Ee,readdir as Te,cp as Oe}from"node:fs/promises";import h from"node:path";import k from"picocolors";import{g as ke,t as q,D as oe,r as K,u as P,a as F,b as Fe}from"../shared/docs-cache.Oi01HUbh.mjs";import{a as V,l as Re,D as be,b as He}from"../shared/docs-cache.bWkgSdUq.mjs";import{execFile as ie}from"node:child_process";import Ae,{tmpdir as se}from"node:os";import{pathToFileURL as je}from"node:url";import{promisify as ae}from"node:util";import{execa as Ie}from"execa";import{g as N,M as B,v as ne}from"./verify.mjs";import{e as Le,r as ce}from"../shared/docs-cache.kK1DPQIQ.mjs";import{writeLock as _e,resolveLockPath as Ne,readLock as Be}from"../lock.mjs";import{createWriteStream as le,createReadStream as ze,constants as ue}from"node:fs";import{pipeline as Ue}from"node:stream/promises";import fe from"fast-glob";const Ye=/^(https?:\/\/)([^@]+)@/i,j=e=>e.replace(Ye,"$1***@"),Ge=ae(ie),Xe=3e4,We=new Set(["file:","ftp:","data:","javascript:"]),Je=e=>{try{const r=new URL(e);if(We.has(r.protocol))throw new Error(`Blocked protocol '${r.protocol}' in repo URL '${j(e)}'.`)}catch(r){if(r instanceof TypeError)return;throw r}},qe=e=>{if(Je(e),e.startsWith("git@")){const r=e.indexOf("@"),t=e.indexOf(":",r+1);return t===-1?null:e.slice(r+1,t)||null}try{const r=new URL(e);return r.protocol!=="https:"&&r.protocol!=="ssh:"?null:r.hostname||null}catch{return null}},me=(e,r)=>{const t=qe(e);if(!t)throw new Error(`Unsupported repo URL '${j(e)}'. Use HTTPS or SSH.`);const i=t.toLowerCase();if(!r.map(o=>o.toLowerCase()).includes(i))throw new Error(`Host '${t}' is not in allowHosts for '${j(e)}'.`)},de=e=>{const r=e.trim().split(`
2
- `).filter(Boolean);return r.length===0?null:r[0].split(/\s+/)[0]||null},Ke=async e=>{me(e.repo,e.allowHosts);const{stdout:r}=await Ge("git",["ls-remote",e.repo,e.ref],{timeout:e.timeoutMs??Xe,maxBuffer:1024*1024}),t=de(r);if(!t)throw new Error(`Unable to resolve ref '${e.ref}' for ${j(e.repo)}.`);return{repo:e.repo,ref:e.ref,resolvedCommit:t}},Ve=ae(ie),he=12e4,z=1,Qe=3,Ze=100,T=async(e,r)=>{const t=process.env.PATH??process.env.Path,i=process.env.PATHEXT??(process.platform==="win32"?".COM;.EXE;.BAT;.CMD":void 0),o=["-c","core.hooksPath=/dev/null","-c","submodule.recurse=false","-c","protocol.ext.allow=never"];r?.allowFileProtocol?o.push("-c","protocol.file.allow=always"):o.push("-c","protocol.file.allow=never"),await Ie("git",[...o,...e],{cwd:r?.cwd,timeout:r?.timeoutMs??he,maxBuffer:10*1024*1024,env:{...process.env,...t?{PATH:t,Path:t}:{},...i?{PATHEXT:i}:{},HOME:process.env.HOME,USER:process.env.USER,USERPROFILE:process.env.USERPROFILE,TMPDIR:process.env.TMPDIR,TMP:process.env.TMP,TEMP:process.env.TEMP,SYSTEMROOT:process.env.SYSTEMROOT,WINDIR:process.env.WINDIR,SSH_AUTH_SOCK:process.env.SSH_AUTH_SOCK,SSH_AGENT_PID:process.env.SSH_AGENT_PID,HTTP_PROXY:process.env.HTTP_PROXY,HTTPS_PROXY:process.env.HTTPS_PROXY,NO_PROXY:process.env.NO_PROXY,GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_CONFIG_NOGLOBAL:"1",...process.platform==="win32"?{}:{GIT_ASKPASS:"/bin/false"}}})},b=async(e,r=Qe)=>{for(let t=0;t<=r;t+=1)try{await R(e,{recursive:!0,force:!0});return}catch(i){const o=N(i);if(o!=="ENOTEMPTY"&&o!=="EBUSY"&&o!=="EPERM"||t===r)throw i;await new Promise(n=>setTimeout(n,Ze*(t+1)))}},et=e=>L("sha256").update(e).digest("hex").substring(0,16),tt=e=>{const r=et(e);return h.join(ce(),r)},rt=async e=>{try{return await T(["rev-parse","--git-dir"],{cwd:e}),!0}catch{return!1}},pe=async e=>{try{const r=h.join(e,".git","config"),t=(await A(r,"utf8")).toLowerCase();return t.includes("partialclone")||t.includes("promisor")||t.includes("partialclonefilter")}catch{return!1}},Q=async(e,r,t)=>{try{await T(["-C",e,"cat-file","-e",`${r}^{commit}`],{timeoutMs:t?.timeoutMs,allowFileProtocol:t?.allowFileProtocol});return}catch{}await T(["-C",e,"fetch","origin",r],{timeoutMs:t?.timeoutMs,allowFileProtocol:t?.allowFileProtocol})},ot=async(e,r,t,i)=>{const o=h.join(t,"archive.tar");await T(["archive","--remote",e,"--format=tar","--output",o,r],{timeoutMs:i}),await Ve("tar",["-xf",o,"-C",t],{timeout:i??he,maxBuffer:1024*1024}),await R(o,{force:!0})},we=e=>{if(!e||e.length===0)return!1;for(const r of e)if(!r||r.includes("**"))return!1;return!0},ge=e=>{if(!e)return[];const r=e.map(t=>{const i=t.replace(/\\/g,"/"),o=i.indexOf("*");return(o===-1?i:i.slice(0,o)).replace(/\/+$|\/$/,"")});return Array.from(new Set(r.filter(t=>t.length>0)))},Z=async(e,r)=>{const t=/^[0-9a-f]{7,40}$/i.test(e.ref),i=we(e.include),o=["clone","--no-checkout","--depth",String(z),"--recurse-submodules=no","--no-tags"];if(i&&o.push("--sparse"),t||(o.push("--single-branch"),e.ref!=="HEAD"&&o.push("--branch",e.ref)),o.push(e.repo,r),await T(o,{timeoutMs:e.timeoutMs}),await Q(r,e.resolvedCommit,{timeoutMs:e.timeoutMs}),i){const n=ge(e.include);n.length>0&&await T(["-C",r,"sparse-checkout","set",...n],{timeoutMs:e.timeoutMs})}await T(["-C",r,"checkout","--quiet","--detach",e.resolvedCommit],{timeoutMs:e.timeoutMs})},it=async(e,r)=>{const t=tt(e.repo),i=await Le(t),o=/^[0-9a-f]{7,40}$/i.test(e.ref),n=we(e.include),s=ce();if(await H(s,{recursive:!0}),i&&await rt(t))if(await pe(t))await b(t),await Z(e,t);else try{const u=["fetch","origin"];if(o)u.push("--depth",String(z));else{const w=e.ref==="HEAD"?"HEAD":`${e.ref}:refs/remotes/origin/${e.ref}`;u.push(w,"--depth",String(z))}await T(["-C",t,...u],{timeoutMs:e.timeoutMs}),await Q(t,e.resolvedCommit,{timeoutMs:e.timeoutMs})}catch{await b(t),await Z(e,t)}else i&&await b(t),await Z(e,t);await H(r,{recursive:!0});const a=["clone","--no-checkout","--depth",String(z),"--recurse-submodules=no","--no-tags"];await pe(t)&&a.splice(2,0,"--filter=blob:none"),n&&a.push("--sparse"),o||(a.push("--single-branch"),e.ref!=="HEAD"&&a.push("--branch",e.ref));const c=je(t).href;if(a.push(c,r),await T(a,{timeoutMs:e.timeoutMs,allowFileProtocol:!0}),n){const u=ge(e.include);u.length>0&&await T(["-C",r,"sparse-checkout","set",...u],{timeoutMs:e.timeoutMs,allowFileProtocol:!0})}await Q(r,e.resolvedCommit,{timeoutMs:e.timeoutMs,allowFileProtocol:!0}),await T(["-C",r,"checkout","--quiet","--detach",e.resolvedCommit],{timeoutMs:e.timeoutMs,allowFileProtocol:!0})},st=async e=>{const r=await X(h.join(se(),`docs-cache-${e.sourceId}-`));try{return await ot(e.repo,e.resolvedCommit,r,e.timeoutMs),r}catch(t){throw await b(r),t}},at=async e=>{V(e.sourceId,"sourceId");try{const r=await st(e);return{repoDir:r,cleanup:async()=>{await b(r)},fromCache:!1}}catch{const r=await X(h.join(se(),`docs-cache-${e.sourceId}-`));try{return await it(e,r),{repoDir:r,cleanup:async()=>{await b(r)},fromCache:!0}}catch(t){throw await b(r),t}}},U=e=>q(e),ee=Number(process.env.DOCS_CACHE_STREAM_THRESHOLD_MB??"2"),nt=Number.isFinite(ee)&&ee>0?Math.floor(ee*1024*1024):1024*1024,ct=(e,r)=>{const t=h.resolve(e);if(!h.resolve(r).startsWith(t+h.sep))throw new Error(`Path traversal detected: ${r}`)},ye=async e=>{try{return await J(e,ue.O_RDONLY|ue.O_NOFOLLOW)}catch(r){const t=N(r);if(t==="ELOOP")return null;if(t==="EINVAL"||t==="ENOSYS"||t==="ENOTSUP")return(await xe(e)).isSymbolicLink()?null:await J(e,"r");throw r}},lt=(e,r)=>{if(!r||e.length===0)return null;let t="";for(;;){let i=null;for(const n of e){const s=(t?n.normalized.slice(t.length):n.normalized).split("/");if(s.length<2)return t||null;const a=s[0];if(!i){i=a;continue}if(i!==a)return t||null}if(!i)return t||null;const o=`${t}${i}/`;if(o===t)return t||null;t=o}},ut=e=>({...e,exclude:e.exclude??[],ignoreHidden:e.ignoreHidden??!1,unwrapSingleRootDir:e.unwrapSingleRootDir??!1}),ft=async(e,r=5e3)=>{const t=Date.now();for(;Date.now()-t<r;)try{const i=await J(e,"wx");return{release:async()=>{await i.close(),await R(e,{force:!0})}}}catch(i){if(N(i)!=="EEXIST")throw i;await new Promise(o=>setTimeout(o,100))}throw new Error(`Failed to acquire lock for ${e}.`)},mt=async e=>{const r=ut(e);V(r.sourceId,"sourceId");const t=ke(r.cacheDir,r.sourceId);await H(r.cacheDir,{recursive:!0});const i=await X(h.join(r.cacheDir,`.tmp-${r.sourceId}-`));let o=null;const n=async()=>{const s=o;!s||s.closed||s.destroyed||await new Promise(a=>{const c=()=>{s.off("close",u),s.off("error",w),a()},u=()=>c(),w=()=>c();s.once("close",u),s.once("error",w);try{s.end()}catch{c()}})};try{const s=[".git/**",...r.ignoreHidden?[".*","**/.*","**/.*/**"]:[],...r.exclude],a=(await fe(r.include,{cwd:r.repoDir,ignore:s,dot:!0,onlyFiles:!0,followSymbolicLinks:!1})).map(f=>({relativePath:f,normalized:U(f)})).sort((f,m)=>f.normalized.localeCompare(m.normalized)),c=lt(a,r.unwrapSingleRootDir),u=new Set;for(const{normalized:f}of a){const m=c?f.slice(c.length):f;u.add(h.posix.dirname(m))}await Promise.all(Array.from(u,f=>H(h.join(i,f),{recursive:!0})));let w=0,D=0;const C=Math.max(1,Math.min(a.length,Math.max(8,Math.min(128,Ae.cpus().length*8)))),y=h.join(i,B),d=le(y,{encoding:"utf8"});o=d;const g=L("sha256"),$=async f=>new Promise((m,l)=>{const S=E=>{d.off("drain",v),l(E)},v=()=>{d.off("error",S),m()};d.once("error",S),d.write(f)?(d.off("error",S),m()):d.once("drain",v)});for(let f=0;f<a.length;f+=C){const m=a.slice(f,f+C),l=await Promise.all(m.map(async S=>{const v=h.join(r.repoDir,S.relativePath),E=await ye(v);if(!E)return null;try{const x=await E.stat();if(!x.isFile())return null;const O=c?S.normalized.slice(c.length):S.normalized,Y=h.join(i,O);if(ct(i,Y),x.size>=nt){const G=ze(v,{fd:E.fd,autoClose:!1}),Me=le(Y);await Ue(G,Me)}else{const G=await E.readFile();await re(Y,G)}return{path:c?S.normalized.slice(c.length):S.normalized,size:x.size}}finally{await E.close()}}));for(const S of l){if(!S)continue;if(r.maxFiles!==void 0&&D+1>r.maxFiles)throw new Error(`Materialized content exceeds maxFiles (${r.maxFiles}).`);if(w+=S.size,w>r.maxBytes)throw new Error(`Materialized content exceeds maxBytes (${r.maxBytes}).`);const v=`${JSON.stringify(S)}
3
- `;g.update(v),await $(v),D+=1}}await new Promise((f,m)=>{d.end(()=>f()),d.once("error",m)});const M=g.digest("hex"),p=async f=>{try{return await _(f),!0}catch{return!1}};return await(async(f,m)=>{const l=await ft(`${m}.lock`);try{const S=await p(m),v=`${m}.bak-${Pe(8).toString("hex")}`;S&&await W(m,v);try{await W(f,m)}catch(E){if(S)try{await W(v,m)}catch(x){const O=x instanceof Error?x.message:String(x);process.stderr.write(`Warning: Failed to restore backup: ${O}
4
- `)}throw E}S&&await R(v,{recursive:!0,force:!0})}finally{await l.release()}})(i,t.sourceDir),{bytes:w,fileCount:D,manifestSha256:M}}catch(s){try{await n()}catch{}throw await R(i,{recursive:!0,force:!0}),s}},dt=async e=>{V(e.sourceId,"sourceId");const r=await fe(e.include,{cwd:e.repoDir,ignore:[".git/**",...e.ignoreHidden?[".*","**/.*","**/.*/**"]:[],...e.exclude??[]],dot:!0,onlyFiles:!0,followSymbolicLinks:!1});r.sort((n,s)=>U(n).localeCompare(U(s)));let t=0,i=0;const o=L("sha256");for(const n of r){const s=U(n),a=h.join(e.repoDir,n),c=await ye(a);if(c)try{const u=await c.stat();if(!u.isFile())continue;if(e.maxFiles!==void 0&&i+1>e.maxFiles)throw new Error(`Materialized content exceeds maxFiles (${e.maxFiles}).`);if(t+=u.size,t>e.maxBytes)throw new Error(`Materialized content exceeds maxBytes (${e.maxBytes}).`);const w=`${JSON.stringify({path:s,size:u.size})}
5
- `;o.update(w),i+=1}finally{await c.close()}}return{bytes:t,fileCount:i,manifestSha256:o.digest("hex")}},ht=async(e,r)=>{await r.rm(e,{recursive:!0,force:!0})},pt=async(e,r)=>{if(!e.unwrapSingleRootDir)return e.sourceDir;const t=await r.readdir(e.sourceDir,{withFileTypes:!0}),i=new Set([B,oe]),o=t.filter(a=>!(a.isFile()&&i.has(a.name))),n=o.filter(a=>a.isDirectory()),s=o.filter(a=>a.isFile());return n.length!==1||s.length>0?e.sourceDir:h.join(e.sourceDir,n[0].name)},te=async e=>{const r=e.deps??{cp:Oe,mkdir:H,readdir:Te,rm:R,symlink:Ee,stderr:process.stderr},t=await pt(e,r),i=h.dirname(e.targetDir);await r.mkdir(i,{recursive:!0}),await ht(e.targetDir,r);const o=process.platform==="win32"?"copy":"symlink";if((e.mode??o)==="copy"){await r.cp(t,e.targetDir,{recursive:!0});return}const n=process.platform==="win32"?"junction":"dir";try{await r.symlink(t,e.targetDir,n)}catch(s){const a=N(s);if(a&&new Set(["EPERM","EACCES","ENOTSUP","EINVAL"]).has(a)){if(e.explicitTargetMode){const c=s instanceof Error?s.message:String(s);r.stderr.write(`Warning: Failed to create symlink at ${e.targetDir}. Falling back to copy. ${c}
6
- `)}await r.cp(t,e.targetDir,{recursive:!0});return}throw s}},wt=e=>{const r={dirs:new Map,files:[]};for(const t of e){const i=t.split("/").filter(Boolean);if(i.length===0)continue;let o=r;for(const s of i.slice(0,-1)){let a=o.dirs.get(s);a||(a={dirs:new Map,files:[]},o.dirs.set(s,a)),o=a}const n=i[i.length-1];o.files.push({name:n,path:t})}return r},Se=(e,r,t)=>{const i=" ".repeat(r),o=Array.from(e.dirs.keys()).sort(),n=[...e.files].sort((s,a)=>s.name.localeCompare(a.name));for(const s of o){t.push(`${i}- ${s}/`);const a=e.dirs.get(s);a&&Se(a,r+1,t)}for(const s of n)t.push(`${i}- [${s.name}](./${s.path})`)},gt=(e,r,t)=>{const i=[...e].sort((a,c)=>a.localeCompare(c)),o=new Map;for(const a of i){const c=a.lastIndexOf("/"),u=c===-1?"":a.substring(0,c),w=c===-1?a:a.substring(c+1),D=o.get(u);D?D.push(w):o.set(u,[w])}const n=Array.from(o.keys()).sort(),s=[];s.push(`[${t}]`);for(const a of n){const c=o.get(a);if(!c)continue;const u=c.join(",");a===""?s.push(`root:{${u}}`):s.push(`${a}:{${u}}`)}r.push(s.join("|"))},yt=(e,r="compressed")=>{const t=[];if(r==="tree"){t.push(`# ${e.id} - Documentation`),t.push(""),t.push("## Files"),t.push("");const i=wt(e.files);Se(i,0,t)}else{const i=`${e.id} Docs Index`;gt(e.files,t,i)}return t.push(""),t.join(`
7
- `)},St=async e=>{const r=h.join(e,".manifest.jsonl");try{const t=await A(r,"utf8"),i=[];for(const o of t.split(`
8
- `))if(o.trim()){const n=JSON.parse(o);n.path&&i.push(n.path)}return i}catch{return[]}},Dt=async e=>{const r=new Map(e.sources.map(i=>[i.id,i])),t=new Map((e.results??[]).map(i=>[i.id,i]));for(const[i,o]of Object.entries(e.lock.sources)){const n=r.get(i);n?.targetDir&&q(K(e.configPath,n.targetDir));const s=h.join(e.cacheDir,i);try{await _(s)}catch{continue}const a=await St(s),c={id:i,repo:o.repo,ref:o.ref,resolvedCommit:o.resolvedCommit,fileCount:o.fileCount,cachePath:q(h.join(e.cacheDir,i)),files:a},u=n?.toc,w=u!==!1;let D="compressed";typeof u=="string"&&(D=u);const C=h.join(s,oe);if(w){if(t.get(i)?.status==="up-to-date")try{await _(C);continue}catch{}const y=yt(c,D);await re(C,y,"utf8")}else try{await R(C,{force:!0})}catch{}}},vt=e=>{if(e<1024)return`${e} B`;const r=["KB","MB","GB","TB"];let t=e,i=-1;for(;t>=1024&&i<r.length-1;)t/=1024,i+=1;return`${t.toFixed(1)} ${r[i]}`},I=async e=>{try{return await _(e),!0}catch{return!1}},De=async(e,r)=>{const t=h.join(e,r);return await I(t)?await I(h.join(t,B)):!1},Ct=e=>{if(!e||e.length===0)return[];const r=e.map(t=>t.trim()).filter(t=>t.length>0);return Array.from(new Set(r)).sort()},$t=["mode","include","exclude","maxBytes","maxFiles","ignoreHidden","unwrapSingleRootDir"],Mt=(e,r)=>e==="include"&&Array.isArray(r)||e==="exclude"&&Array.isArray(r)?Ct(r):r,Pt=e=>{const r=$t.map(o=>[o,Mt(o,e[o])]);r.sort(([o],[n])=>o.localeCompare(n));const t=Object.fromEntries(r),i=L("sha256");return i.update(JSON.stringify(t)),i.digest("hex")},ve=async(e,r={})=>{const{config:t,resolvedPath:i,sources:o}=await Re(e.configPath),n=t.defaults??be.defaults,s=Fe(i,t.cacheDir??He,e.cacheDirOverride),a=Ne(i),c=await I(a);let u=null;c&&(u=await Be(a));const w=r.resolveRemoteCommit??Ke,D=e.sourceFilter?.length?o.filter(y=>e.sourceFilter?.includes(y.id)):o,C=await Promise.all(D.map(async y=>{const d=u?.sources?.[y.id],g=y.include??n.include,$=y.exclude??n.exclude,M=Pt({...y,include:g,exclude:$});if(e.offline){const l=await De(s,y.id);return{id:y.id,repo:d?.repo??y.repo,ref:d?.ref??y.ref??n.ref,resolvedCommit:d?.resolvedCommit??"offline",lockCommit:d?.resolvedCommit??null,lockRulesSha256:d?.rulesSha256,status:d&&l?"up-to-date":"missing",bytes:d?.bytes,fileCount:d?.fileCount,manifestSha256:d?.manifestSha256,rulesSha256:M}}const p=await w({repo:y.repo,ref:y.ref,allowHosts:n.allowHosts,timeoutMs:e.timeoutMs}),f=d?.resolvedCommit===p.resolvedCommit&&d?.rulesSha256===M,m=d?f?"up-to-date":"changed":"missing";return{id:y.id,repo:p.repo,ref:p.ref,resolvedCommit:p.resolvedCommit,lockCommit:d?.resolvedCommit??null,lockRulesSha256:d?.rulesSha256,status:m,bytes:d?.bytes,fileCount:d?.fileCount,manifestSha256:d?.manifestSha256,rulesSha256:M}}));return{config:t,configPath:i,cacheDir:s,lockPath:a,lockExists:c,lockData:u,results:C,sources:D,defaults:n}},xt=async()=>{const e=h.resolve(process.cwd(),"package.json");try{const r=await A(e,"utf8"),t=JSON.parse(r.toString());return typeof t.version=="string"?t.version:"0.0.0"}catch{}try{const r=await A(new URL("../package.json",import.meta.url),"utf8"),t=JSON.parse(r.toString());return typeof t.version=="string"?t.version:"0.0.0"}catch{}try{const r=await A(new URL("../../package.json",import.meta.url),"utf8"),t=JSON.parse(r.toString());return typeof t.version=="string"?t.version:"0.0.0"}catch{return"0.0.0"}},Et=async(e,r)=>{const t=await xt(),i=new Date().toISOString(),o={...r?.sources??{}};for(const n of e.results){const s=o[n.id];o[n.id]={repo:n.repo,ref:n.ref,resolvedCommit:n.resolvedCommit,bytes:n.bytes??s?.bytes??0,fileCount:n.fileCount??s?.fileCount??0,manifestSha256:n.manifestSha256??s?.manifestSha256??n.resolvedCommit,rulesSha256:n.rulesSha256??s?.rulesSha256,updatedAt:i}}return{version:1,generatedAt:i,toolVersion:t,sources:o}},Ce=async(e,r={})=>{const t=process.hrtime.bigint();let i=0;const o=await ve(e,r);await H(o.cacheDir,{recursive:!0});const n=o.lockData,s=o.results.filter(c=>{const u=o.sources.find(w=>w.id===c.id);return c.status==="missing"&&(u?.required??!0)});if(e.failOnMiss&&s.length>0)throw new Error(`Missing required source(s): ${s.map(c=>c.id).join(", ")}.`);if(!e.lockOnly){const c=o.defaults,u=r.fetchSource??at,w=r.materializeSource??mt,D=new Map,C=async(g,$)=>{const M=g?.length?o.results.filter(p=>g.includes(p.id)):o.results;return(await Promise.all(M.map(async p=>{const f=o.sources.find(l=>l.id===p.id);if(!f)return null;if($)return{result:p,source:f};let m=D.get(p.id);return m===void 0&&(m=await De(o.cacheDir,p.id),D.set(p.id,m)),p.status!=="up-to-date"||!m?{result:p,source:f}:null}))).filter(Boolean)},y=async()=>{await Promise.all(o.sources.map(async g=>{if(!g.targetDir)return;const $=K(o.configPath,g.targetDir);await I($)||await te({sourceDir:h.join(o.cacheDir,g.id),targetDir:$,mode:g.targetMode??c.targetMode,explicitTargetMode:g.targetMode!==void 0,unwrapSingleRootDir:g.unwrapSingleRootDir})}))},d=async g=>{const $=e.concurrency??4;let M=0;const p=async()=>{const f=g[M];if(!f||!f.source)return;M+=1;const{result:m,source:l}=f,S=o.lockData?.sources?.[l.id],v=await u({sourceId:l.id,repo:l.repo,ref:l.ref,resolvedCommit:m.resolvedCommit,cacheDir:o.cacheDir,include:l.include??c.include,timeoutMs:e.timeoutMs});e.json||P.step(v.fromCache?"Restoring from cache":"Downloading repo",l.id);try{const E=h.join(o.cacheDir,l.id,B);if(m.status!=="up-to-date"&&S?.manifestSha256&&S?.rulesSha256===m.rulesSha256&&await I(E)){const O=await dt({sourceId:l.id,repoDir:v.repoDir,cacheDir:o.cacheDir,include:l.include??c.include,exclude:l.exclude,maxBytes:l.maxBytes??c.maxBytes,maxFiles:l.maxFiles??c.maxFiles,ignoreHidden:l.ignoreHidden??c.ignoreHidden});if(O.manifestSha256===S.manifestSha256){m.bytes=O.bytes,m.fileCount=O.fileCount,m.manifestSha256=O.manifestSha256,m.status="up-to-date",e.json||P.item(F.success,l.id,"no content changes"),await p();return}}e.json||P.step("Materializing",l.id);const x=await w({sourceId:l.id,repoDir:v.repoDir,cacheDir:o.cacheDir,include:l.include??c.include,exclude:l.exclude,maxBytes:l.maxBytes??c.maxBytes,maxFiles:l.maxFiles??c.maxFiles,ignoreHidden:l.ignoreHidden??c.ignoreHidden,unwrapSingleRootDir:l.unwrapSingleRootDir});if(l.targetDir){const O=K(o.configPath,l.targetDir);await te({sourceDir:h.join(o.cacheDir,l.id),targetDir:O,mode:l.targetMode??c.targetMode,explicitTargetMode:l.targetMode!==void 0,unwrapSingleRootDir:l.unwrapSingleRootDir})}m.bytes=x.bytes,m.fileCount=x.fileCount,m.manifestSha256=x.manifestSha256,e.json||P.item(F.success,l.id,`synced ${x.fileCount} files`)}finally{await v.cleanup()}await p()};await Promise.all(Array.from({length:Math.min($,g.length)},p))};if(e.offline)await y();else{const g=await C();await d(g),await y()}if(!e.offline){const g=(await ne({configPath:o.configPath,cacheDirOverride:o.cacheDir})).results.filter($=>!$.ok);if(g.length>0){const $=await C(g.map(p=>p.id),!0);$.length>0&&(await d($),await y());const M=(await ne({configPath:o.configPath,cacheDirOverride:o.cacheDir})).results.filter(p=>!p.ok);if(M.length>0&&(i+=1,!e.json)){const p=M.map(f=>`${f.id} (${f.issues.join("; ")})`).join(", ");P.line(`${F.warn} Verify failed for ${M.length} source(s): ${p}`)}}}}const a=await Et(o,n);if(await _e(o.lockPath,a),!e.json){const c=Number(process.hrtime.bigint()-t)/1e6,u=o.results.reduce((D,C)=>D+(C.bytes??0),0),w=o.results.reduce((D,C)=>D+(C.fileCount??0),0);P.line(`${F.info} Completed in ${c.toFixed(0)}ms \xB7 ${vt(u)} \xB7 ${w} files${i?` \xB7 ${i} warning${i===1?"":"s"}`:""}`)}return await Dt({cacheDir:o.cacheDir,configPath:o.configPath,lock:a,sources:o.sources,results:o.results}),o.lockExists=!0,o},$e=e=>{const r={upToDate:e.results.filter(t=>t.status==="up-to-date").length,changed:e.results.filter(t=>t.status==="changed").length,missing:e.results.filter(t=>t.status==="missing").length};if(e.results.length===0){P.line(`${F.info} No sources to sync.`);return}P.line(`${F.info} ${e.results.length} sources (${r.upToDate} up-to-date, ${r.changed} changed, ${r.missing} missing)`);for(const t of e.results){const i=P.hash(t.resolvedCommit),o=P.hash(t.lockCommit),n=!!t.lockRulesSha256&&!!t.rulesSha256&&t.lockRulesSha256!==t.rulesSha256;if(t.status==="up-to-date"){P.item(F.success,t.id,`${k.dim("up-to-date")} ${k.gray(i)}`);continue}if(t.status==="changed"){if(t.lockCommit===t.resolvedCommit&&n){P.item(F.warn,t.id,`${k.dim("rules changed")} ${k.gray(i)}`);continue}P.item(F.warn,t.id,`${k.dim("changed")} ${k.gray(o)} ${k.dim("->")} ${k.gray(i)}`);continue}P.item(F.warn,t.id,`${k.dim("missing")} ${k.gray(i)}`)}},Tt={__proto__:null,getSyncPlan:ve,printSyncPlan:$e,runSync:Ce};export{te as a,$e as b,Ce as c,me as e,de as p,j as r,Tt as s};
9
- //# sourceMappingURL=sync.mjs.map
@@ -1,2 +0,0 @@
1
- import{stat as N,access as z}from"node:fs/promises";import h from"node:path";import{b as $,r as v,u as l,a as m}from"../shared/docs-cache.Oi01HUbh.mjs";import{l as M,b as j}from"../shared/docs-cache.bWkgSdUq.mjs";import{createReadStream as k}from"node:fs";import C from"node:readline";const T=t=>typeof t=="object"&&t!==null&&"code"in t&&(typeof t.code=="string"||typeof t.code=="number"||t.code===void 0),y=t=>T(t)&&typeof t.code=="string"?t.code:void 0,_=t=>{if(!t||typeof t!="object")throw new Error("Manifest entry must be an object.");const e=t;if(typeof e.path!="string"||e.path.length===0)throw new Error("Manifest entry path must be a non-empty string.");if(typeof e.size!="number"||Number.isNaN(e.size))throw new Error("Manifest entry size must be a number.");if(e.size<0)throw new Error("Manifest entry size must be zero or greater.");return{path:e.path,size:e.size}},w=".manifest.jsonl",I=async function*(t){const e=h.join(t,w),a=k(e,{encoding:"utf8"}),s=C.createInterface({input:a,crlfDelay:1/0});try{for await(const u of s){const f=u.trim();f&&(yield _(JSON.parse(f)))}}finally{s.close(),a.destroy()}},O=async t=>{try{return await z(t),!0}catch{return!1}},E=async t=>{const{config:e,resolvedPath:a,sources:s}=await M(t.configPath),u=$(a,e.cacheDir??j,t.cacheDirOverride),f=async(i,n)=>{if(!await O(i))return{ok:!1,issues:[n==="source"?"missing source directory":"missing target directory"]};try{let r=0,o=0;for await(const g of I(i)){const D=h.join(i,g.path);try{(await N(D)).size!==g.size&&(o+=1)}catch(p){const d=y(p);if(d==="ENOENT"||d==="ENOTDIR"){r+=1;continue}throw p}}const c=[];return r>0&&c.push(n==="source"?`missing files: ${r}`:`target missing files: ${r}`),o>0&&c.push(n==="source"?`size mismatch: ${o}`:`target size mismatch: ${o}`),{ok:c.length===0,issues:c}}catch(r){const o=y(r);if(o==="ENOENT"||o==="ENOTDIR")return{ok:!1,issues:[n==="source"?"missing manifest":"missing target manifest"]};throw r}},b=await Promise.all(s.map(async i=>{const n=h.join(u,i.id),r=[...(await f(n,"source")).issues];if(i.targetDir&&i.targetMode==="copy"){const o=v(a,i.targetDir),c=await f(o,"target");r.push(...c.issues)}return{id:i.id,ok:r.length===0,issues:r}}));return{cacheDir:u,results:b}},R=t=>{const e=t.results.filter(s=>s.ok).length,a=t.results.length-e;if(t.results.length===0){l.line(`${m.warn} No sources to verify.`);return}l.line(`${m.info} Verified ${t.results.length} sources (${e} ok, ${a} failed)`);for(const s of t.results)s.ok?l.item(m.success,s.id):l.item(m.warn,s.id,s.issues.join(", "))},A={__proto__:null,printVerify:R,verifyCache:E};export{w as M,A as a,y as g,E as v};
2
- //# sourceMappingURL=verify.mjs.map
@@ -1,2 +0,0 @@
1
- const h=f=>{const e=f.trim(),p=e.match(/^git@([^:]+):(.+)$/);if(p){const t=p[1],r=p[2],[o,n]=r.split("#",2),i=o.replace(/^\//,""),c=i.split("/").filter(Boolean).pop()?.replace(/\.git$/i,""),s=`git@${t}:${i}`,a=n?.trim()||void 0;return{repoUrl:s,ref:a,inferredId:c}}const d=e.match(/^([^\s/:]+)\/([^\s#]+)(?:#(.+))?$/);if(d){const[,t,r,o]=d;return{repoUrl:`https://github.com/${`${t}/${r}`.replace(/\.git$/i,"")}.git`,ref:o?.trim()||void 0,inferredId:r.replace(/\.git$/i,"")}}const l=e.match(/^(github|gitlab):(.+)$/i);if(l){const t=l[1].toLowerCase(),r=l[2],[o,n]=r.split("#",2),i=o.replace(/^\//,""),c=i.split("/").filter(Boolean).pop()?.replace(/\.git$/i,""),s=t==="gitlab"?"gitlab.com":"github.com",a=i.endsWith(".git")?"":".git",g=`https://${s}/${i}${a}`,$=n?.trim()||void 0;return{repoUrl:g,ref:$,inferredId:c}}try{const t=new URL(e);if(t.protocol==="https:"||t.protocol==="ssh:"){const r=t.pathname.split("/").filter(Boolean).pop()?.replace(/\.git$/i,"");return{repoUrl:e,ref:void 0,inferredId:r}}}catch{}return{repoUrl:e,ref:void 0,inferredId:void 0}};export{h as r};
2
- //# sourceMappingURL=docs-cache.BSvQNKuf.mjs.map
@@ -1,5 +0,0 @@
1
- import{readFile as o,writeFile as f,access as P}from"node:fs/promises";import a from"node:path";import{t as p}from"./docs-cache.Oi01HUbh.mjs";const g=async n=>{try{return await P(n),!0}catch{return!1}},l=n=>{const r=n.trim();if(!r||r.startsWith("#")||r.startsWith("!"))return"";let t=r.replace(/^\//,"");return t=t.replace(/^\.\//,""),t=t.replace(/\/+$/,""),p(t)},d=(n,r)=>{const t=a.isAbsolute(r)?a.resolve(r):a.resolve(n,r),e=a.relative(n,t);return e===".."||e.startsWith(`..${a.sep}`)||a.isAbsolute(e)?null:e.length===0?".":e},u=async(n,r)=>{const t=a.resolve(n,".gitignore"),e=d(n,r);if(!e)return{gitignorePath:t,entry:null,hasEntry:!1};const i=l(e);if(!i)return{gitignorePath:t,entry:null,hasEntry:!1};let s="";await g(t)&&(s=await o(t,"utf8"));const h=s.split(/\r?\n/),c=new Set(h.map(y=>l(y)).filter(Boolean));return{gitignorePath:t,entry:`${i}/`,hasEntry:c.has(i)}},w=async(n,r)=>{const t=await u(n,r);if(!t.entry)return{updated:!1,gitignorePath:t.gitignorePath,entry:null};if(t.hasEntry)return{updated:!1,gitignorePath:t.gitignorePath,entry:t.entry};let e="";await g(t.gitignorePath)&&(e=await o(t.gitignorePath,"utf8"));const i=e.length===0||e.endsWith(`
2
- `)?"":`
3
- `,s=`${e}${i}${t.entry}
4
- `;return await f(t.gitignorePath,s,"utf8"),{updated:!0,gitignorePath:t.gitignorePath,entry:t.entry}};export{w as e,u as g};
5
- //# sourceMappingURL=docs-cache.DH8jN6rl.mjs.map
@@ -1,6 +0,0 @@
1
- import p from"node:process";import d from"cac";import i from"node:path";import s from"picocolors";var a=(o=>(o[o.Success=0]="Success",o[o.FatalError=1]="FatalError",o[o.InvalidArgument=9]="InvalidArgument",o))(a||{});const m=["add","remove","sync","status","clean","clean-cache","prune","verify","init"],g=(o=p.argv)=>{try{const r=d("docs-cache");r.option("--source <repo>","Source repo (add only)").option("--target <dir>","Target directory for source (add only)").option("--config <path>","Path to config file").option("--cache-dir <path>","Override cache directory").option("--offline","Disable network access").option("--fail-on-miss","Fail when required sources are missing").option("--lock-only","Update lock without materializing files").option("--prune","Prune cache on remove").option("--target-dir <path>","Target directory for add").option("--concurrency <n>","Concurrency limit").option("--json","Output JSON").option("--timeout-ms <n>","Network timeout in milliseconds").option("--silent","Suppress non-error output").help();const e=r.parse(o,{run:!1}),t=e.args[0];if(t&&!m.includes(t))throw new Error(`Unknown command '${t}'.`);const n={config:e.options.config,cacheDir:e.options.cacheDir,offline:!!e.options.offline,failOnMiss:!!e.options.failOnMiss,lockOnly:!!e.options.lockOnly,prune:!!e.options.prune,targetDir:e.options.targetDir,concurrency:e.options.concurrency?Number(e.options.concurrency):void 0,json:!!e.options.json,timeoutMs:e.options.timeoutMs?Number(e.options.timeoutMs):void 0,silent:!!e.options.silent};if(n.concurrency!==void 0&&n.concurrency<1)throw new Error("--concurrency must be a positive number.");if(n.timeoutMs!==void 0&&n.timeoutMs<1)throw new Error("--timeout-ms must be a positive number.");const l=o.slice(2);return{command:t??null,options:n,positionals:e.args.slice(1),rawArgs:l,help:!!e.options.help,parsed:{command:t??null,args:e.args.slice(1),options:n}}}catch(r){const e=r instanceof Error?r.message:String(r);console.error(e),p.exit(a.InvalidArgument)}},h="TOC.md",u=o=>o.replace(/\\/g,"/"),f=(o,r)=>{const e=i.dirname(i.resolve(o)),t=i.resolve(e,r),n=i.relative(e,t);if(n===".."||n.startsWith(`..${i.sep}`)||i.isAbsolute(n))throw new Error(`targetDir '${r}' escapes project directory. Must be within ${e}.`);if(u(n).split("/").filter(Boolean).includes(".git"))throw new Error("targetDir cannot be within .git directory.");return t},y=(o,r,e)=>{if(e)return i.resolve(e);const t=i.dirname(o);return i.resolve(t,r)},w=(o,r)=>{i.join(o,"repos");const e=i.join(o,r);return{cacheDir:o,sourceDir:e}},v={error:s.red("\u2716"),success:s.green("\u2714"),info:s.blue("\u2139"),warn:s.yellow("\u26A0")};let c=!1;const b=o=>{c=o},E={path:o=>{const r=i.relative(process.cwd(),o),e=r.length<o.length?r:o;return u(e)},hash:o=>o?o.slice(0,7):"-",pad:(o,r)=>o.padEnd(r),line:(o="")=>{c||process.stdout.write(`${o}
2
- `)},header:(o,r)=>{c||process.stdout.write(`${s.blue("\u2139")} ${o.padEnd(10)} ${r}
3
- `)},item:(o,r,e)=>{if(c)return;const t=s.bold(r),n=e?s.gray(e):"";process.stdout.write(` ${o} ${t} ${n}
4
- `)},step:(o,r,e)=>{if(c)return;const t=s.cyan("\u2192");process.stdout.write(` ${t} ${o} ${s.bold(r)}${e?` ${s.dim(e)}`:""}
5
- `)}};export{h as D,a as E,v as a,y as b,w as g,g as p,f as r,b as s,u as t,E as u};
6
- //# sourceMappingURL=docs-cache.Oi01HUbh.mjs.map
@@ -1,3 +0,0 @@
1
- import{writeFile as I,readFile as T,access as z}from"node:fs/promises";import w from"node:path";import{z as t}from"zod";import{r as L}from"./docs-cache.Oi01HUbh.mjs";const x=t.enum(["symlink","copy"]),M=t.enum(["materialize"]),F=t.enum(["tree","compressed"]),U=t.object({type:t.enum(["commit","manifest"]),value:t.string().nullable()}).strict(),_=t.object({ref:t.string().min(1),mode:M,include:t.array(t.string().min(1)).min(1),exclude:t.array(t.string().min(1)).optional(),targetMode:x.optional(),required:t.boolean(),maxBytes:t.number().min(1),maxFiles:t.number().min(1).optional(),ignoreHidden:t.boolean(),allowHosts:t.array(t.string().min(1)).min(1),toc:t.union([t.boolean(),F]).optional(),unwrapSingleRootDir:t.boolean().optional()}).strict(),P=t.object({id:t.string().min(1),repo:t.string().min(1),targetDir:t.string().min(1).optional(),targetMode:x.optional(),ref:t.string().min(1).optional(),mode:M.optional(),include:t.array(t.string().min(1)).optional(),exclude:t.array(t.string().min(1)).optional(),required:t.boolean().optional(),maxBytes:t.number().min(1).optional(),maxFiles:t.number().min(1).optional(),ignoreHidden:t.boolean().optional(),integrity:U.optional(),toc:t.union([t.boolean(),F]).optional(),unwrapSingleRootDir:t.boolean().optional()}).strict(),J=t.object({$schema:t.string().min(1).optional(),cacheDir:t.string().min(1).optional(),targetMode:x.optional(),defaults:_.partial().optional(),sources:t.array(P)}).strict(),G=/^[a-zA-Z0-9_-]+$/,V=new Set([".","..","CON","PRN","AUX","NUL","COM1","LPT1"]),H=(e,r)=>{if(typeof e!="string"||e.length===0)throw new Error(`${r} must be a non-empty string.`);if(e.length>200)throw new Error(`${r} exceeds maximum length of 200.`);if(!G.test(e))throw new Error(`${r} must contain only alphanumeric characters, hyphens, and underscores.`);if(V.has(e.toUpperCase()))throw new Error(`${r} uses reserved name '${e}'.`);return e},j="docs.config.json",v=".docs",A="package.json",X=process.platform==="win32"?"copy":"symlink",f={cacheDir:v,defaults:{ref:"HEAD",mode:"materialize",include:["**/*.{md,mdx,markdown,mkd,txt,rst,adoc,asciidoc}"],exclude:[],targetMode:X,required:!0,maxBytes:2e8,ignoreHidden:!1,allowHosts:["github.com","gitlab.com","visualstudio.com"],toc:!0,unwrapSingleRootDir:!1},sources:[]},Z=(e,r)=>!e||!r?e===r:e.length!==r.length?!1:e.every((o,a)=>o===r[a]),C=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),R=(e,r)=>{const o={};for(const[a,i]of Object.entries(e)){const d=r[a];if(Array.isArray(i)&&Array.isArray(d)){Z(i,d)||(o[a]=i);continue}if(C(i)&&C(d)){const s=R(i,d);Object.keys(s).length>0&&(o[a]=s);continue}i!==d&&(o[a]=i)}return o},K=e=>{const r={...f,$schema:e.$schema,defaults:{...f.defaults,...e.targetMode?{targetMode:e.targetMode}:void 0}},o=R(e,r),a={$schema:o.$schema,cacheDir:o.cacheDir,targetMode:o.targetMode,defaults:o.defaults,sources:e.sources};return(!a.defaults||Object.keys(a.defaults).length===0)&&delete a.defaults,a},y=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),m=(e,r)=>{if(typeof e!="string"||e.length===0)throw new Error(`${r} must be a non-empty string.`);return e},g=(e,r)=>{if(typeof e!="boolean")throw new Error(`${r} must be a boolean.`);return e},Q=(e,r)=>{if(typeof e!="number"||Number.isNaN(e))throw new Error(`${r} must be a number.`);return e},h=(e,r)=>{const o=Q(e,r);if(o<1)throw new Error(`${r} must be greater than zero.`);return o},p=(e,r)=>{if(!Array.isArray(e)||e.length===0)throw new Error(`${r} must be a non-empty array of strings.`);for(const o of e)if(typeof o!="string"||o.length===0)throw new Error(`${r} must contain non-empty strings.`);return e},k=(e,r)=>{const o=m(e,r);if(o!=="symlink"&&o!=="copy")throw new Error(`${r} must be "symlink" or "copy".`);return o},q=(e,r)=>{if(e!=="materialize")throw new Error(`${r} must be "materialize".`);return e},W=(e,r)=>{if(!y(e))throw new Error(`${r} must be an object.`);const o=e.type;if(o!=="commit"&&o!=="manifest")throw new Error(`${r}.type must be "commit" or "manifest".`);const a=e.value;if(typeof a!="string"&&a!==null)throw new Error(`${r}.value must be a string or null.`);return{type:o,value:a}},B=e=>{if(!y(e))throw new Error("Config must be a JSON object.");const r=J.safeParse(e);if(!r.success){const n=r.error.issues.map(c=>`${c.path.join(".")||"config"} ${c.message}`).join("; ");throw new Error(`Config does not match schema: ${n}.`)}const o=r.data,a=o.cacheDir?m(o.cacheDir,"cacheDir"):v,i=o.defaults,d=o.targetMode!==void 0?k(o.targetMode,"targetMode"):void 0,s=f.defaults;let l=s;if(i!==void 0){if(!y(i))throw new Error("defaults must be an object.");l={ref:i.ref!==void 0?m(i.ref,"defaults.ref"):s.ref,mode:i.mode!==void 0?q(i.mode,"defaults.mode"):s.mode,include:i.include!==void 0?p(i.include,"defaults.include"):s.include,exclude:i.exclude!==void 0?p(i.exclude,"defaults.exclude"):s.exclude,targetMode:i.targetMode!==void 0?k(i.targetMode,"defaults.targetMode"):d??s.targetMode,required:i.required!==void 0?g(i.required,"defaults.required"):s.required,maxBytes:i.maxBytes!==void 0?h(i.maxBytes,"defaults.maxBytes"):s.maxBytes,maxFiles:i.maxFiles!==void 0?h(i.maxFiles,"defaults.maxFiles"):s.maxFiles,ignoreHidden:i.ignoreHidden!==void 0?g(i.ignoreHidden,"defaults.ignoreHidden"):s.ignoreHidden,allowHosts:i.allowHosts!==void 0?p(i.allowHosts,"defaults.allowHosts"):s.allowHosts,toc:i.toc!==void 0?i.toc:s.toc,unwrapSingleRootDir:i.unwrapSingleRootDir!==void 0?g(i.unwrapSingleRootDir,"defaults.unwrapSingleRootDir"):s.unwrapSingleRootDir}}else d!==void 0&&(l={...s,targetMode:d});const E=o.sources.map((n,c)=>{if(!y(n))throw new Error(`sources[${c}] must be an object.`);const u={id:H(n.id,`sources[${c}].id`),repo:m(n.repo,`sources[${c}].repo`)};if(n.targetDir!==void 0&&(u.targetDir=m(n.targetDir,`sources[${c}].targetDir`)),n.targetMode!==void 0){const b=m(n.targetMode,`sources[${c}].targetMode`);if(b!=="symlink"&&b!=="copy")throw new Error(`sources[${c}].targetMode must be "symlink" or "copy".`);u.targetMode=b}return n.ref!==void 0&&(u.ref=m(n.ref,`sources[${c}].ref`)),n.mode!==void 0&&(u.mode=q(n.mode,`sources[${c}].mode`)),n.include!==void 0&&(u.include=p(n.include,`sources[${c}].include`)),n.exclude!==void 0&&(u.exclude=p(n.exclude,`sources[${c}].exclude`)),n.required!==void 0&&(u.required=g(n.required,`sources[${c}].required`)),n.maxBytes!==void 0&&(u.maxBytes=h(n.maxBytes,`sources[${c}].maxBytes`)),n.maxFiles!==void 0&&(u.maxFiles=h(n.maxFiles,`sources[${c}].maxFiles`)),n.ignoreHidden!==void 0&&(u.ignoreHidden=g(n.ignoreHidden,`sources[${c}].ignoreHidden`)),n.integrity!==void 0&&(u.integrity=W(n.integrity,`sources[${c}].integrity`)),n.toc!==void 0&&(u.toc=n.toc),n.unwrapSingleRootDir!==void 0&&(u.unwrapSingleRootDir=g(n.unwrapSingleRootDir,`sources[${c}].unwrapSingleRootDir`)),u}),S=new Set,$=[];for(const n of E)S.has(n.id)&&$.push(n.id),S.add(n.id);if($.length>0)throw new Error(`Duplicate source IDs found: ${$.join(", ")}. Each source must have a unique ID.`);return{cacheDir:a,targetMode:d,defaults:l,sources:E}},Y=e=>{const r=e.defaults??f.defaults;return e.sources.map(o=>({id:o.id,repo:o.repo,targetDir:o.targetDir,targetMode:o.targetMode??r.targetMode,ref:o.ref??r.ref,mode:o.mode??r.mode,include:o.include??r.include,exclude:o.exclude??r.exclude,required:o.required??r.required,maxBytes:o.maxBytes??r.maxBytes,maxFiles:o.maxFiles??r.maxFiles,ignoreHidden:o.ignoreHidden??r.ignoreHidden,integrity:o.integrity,toc:o.toc??r.toc,unwrapSingleRootDir:o.unwrapSingleRootDir??r.unwrapSingleRootDir}))},N=e=>e?w.resolve(e):w.resolve(process.cwd(),j),ee=()=>w.resolve(process.cwd(),A),O=async e=>{try{return await z(e),!0}catch{return!1}},D=async(e,r)=>{let o;try{o=await T(e,"utf8")}catch(s){const l=s instanceof Error?s.message:String(s);throw new Error(`Failed to read config at ${e}: ${l}`)}let a;try{a=JSON.parse(o)}catch(s){const l=s instanceof Error?s.message:String(s);throw new Error(`Invalid JSON in ${e}: ${l}`)}const i=r==="package"?a?.["docs-cache"]:a;if(r==="package"&&i===void 0)throw new Error(`Missing docs-cache config in ${e}.`);const d=B(i);for(const s of d.sources)s.targetDir&&L(e,s.targetDir);return{config:d,resolvedPath:e,sources:Y(d)}},re=async(e,r)=>{const o=`${JSON.stringify(r,null,2)}
2
- `;await I(e,o,"utf8")},oe=async e=>{const r=N(e),o=w.basename(r)===A;if(e)return D(r,o?"package":"config");if(await O(r))return D(r,"config");const a=ee();if(await O(a))try{return await D(a,"package")}catch{}throw new Error(`No docs.config.json found at ${r} and no docs-cache config in ${a}.`)};export{f as D,H as a,v as b,j as c,oe as l,N as r,K as s,B as v,re as w};
3
- //# sourceMappingURL=docs-cache.bWkgSdUq.mjs.map
@@ -1,2 +0,0 @@
1
- import{access as s}from"node:fs/promises";import{homedir as a}from"node:os";import e from"node:path";const c=()=>{const r=a();switch(process.platform){case"darwin":return e.join(r,"Library","Caches");case"win32":return process.env.LOCALAPPDATA||e.join(r,"AppData","Local");default:return process.env.XDG_CACHE_HOME||e.join(r,".cache")}},t=()=>process.env.DOCS_CACHE_GIT_DIR||e.join(c(),"docs-cache-git"),o=async r=>{try{return await s(r),!0}catch{return!1}};export{o as e,t as r};
2
- //# sourceMappingURL=docs-cache.kK1DPQIQ.mjs.map