home
github
02 Jun 2024

download a directory from a github repository

parse url ex : https://github.com / owner / repo / tree / branch / path
owner
repo
branch
path
this url can be visited with the following query parameters
https://javascript-2020.github.io/utils/download-a-directory-from-a-github-repository/download-a-directory-from-a-github-repository.html?
owner={owner}
repo={repo}
branch={branch}
path={path}
if the parameter download is present, the download will be started automatically
example
https://javascript-2020.github.io/utils/download-a-directory-from-a-github-repository/download-a-directory-from-a-github-repository.html ?owner=javascript-2020&repo=code-projects&branch=main&path=http-file-upload https://javascript-2020.github.io/utils/download-a-directory-from-a-github-repository/download-a-directory-from-a-github-repository.html ?owner=javascript-2020&repo=code-projects&branch=main&path=http-file-upload&download
browser code
<script type=module> import jszip from 'https://cdn.jsdelivr.net/npm/jszip/+esm'; var zip = new jszip(); var owner = 'javascript-2020'; var repo = 'javascript-2020.github.io'; var branch = 'main'; var path = 'code-projects'; if(path.slice(-1)!='/')path+='/'; var file = `${path.split('/').filter(Boolean).at(-1)||repo}.zip`; var url = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}?recursive=true`; var json = await fetch(url).then(res=>res.json()); await Promise.all(json.tree.map(async item=>{ if(!item.path.startsWith(path))return; var fn = item.path.slice(path.length); if(item.type=='tree'){ zip.folder(fn); }else{ var blob = await fetch(item.url).then(res=>res.blob()); zip.file(fn,blob); } })); var blob = await zip.generateAsync({type:'blob'}); var url = window.URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = file; a.click(); </script>
node.js code
//download-repo-dir.mjs import fs from 'fs'; var owner = 'javascript-2020'; var repo = 'javascript-2020.github.io'; var branch = 'main'; var path = 'code-projects'; if(path.slice(-1)!='/')path+='/'; var file = `${path.split('/').filter(Boolean).at(-1)||repo}/`; fs.mkdirSync(file); var url = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}?recursive=true`; var json = await fetch(url).then(res=>res.json()); await Promise.all(json.tree.map(async item=>{ if(!item.path.startsWith(path))return; var fn = item.path.slice(path.length); if(item.type=='tree'){ fs.mkdirSync(file+fn); }else{ var res = await fetch(item.url); var txt = await res.text(); fs.writeFileSync(file+fn,txt); } }));