IOweb/node_modules/@iconify/tools/lib/download/github/index.cjs
2026-07-03 15:07:38 -05:00

105 lines
3.4 KiB
JavaScript

'use strict';
const fs = require('fs');
const export_helpers_prepare = require('../../export/helpers/prepare.cjs');
const download_github_hash = require('./hash.cjs');
const download_api_download = require('../api/download.cjs');
const download_helpers_unzip = require('../helpers/unzip.cjs');
require('pathe');
require('../api/index.cjs');
require('../api/cache.cjs');
require('crypto');
require('../../misc/scan.cjs');
require('../api/config.cjs');
require('../api/fetch.cjs');
require('fs/promises');
require('extract-zip');
async function findMatchingDirs(rootDir, hash) {
const matches = [];
const files = await fs.promises.readdir(rootDir);
for (let i = 0; i < files.length; i++) {
const file = files[i];
const lastChunk = file.split("-").pop();
if (lastChunk.length < 4 || lastChunk !== hash.slice(0, lastChunk.length)) {
continue;
}
const stat = await fs.promises.stat(rootDir + "/" + file);
if (stat.isDirectory()) {
matches.push(file);
}
}
return matches;
}
async function downloadGitHubRepo(options) {
const hash = await download_github_hash.getGitHubRepoHash(options);
const ifModifiedSince = options.ifModifiedSince;
if (ifModifiedSince) {
const expectedHash = typeof ifModifiedSince === "string" ? ifModifiedSince : ifModifiedSince.downloadType === "github" ? ifModifiedSince.hash : null;
if (hash === expectedHash) {
return "not_modified";
}
}
options.target = options.target.replace("{hash}", hash);
const rootDir = options.target = await export_helpers_prepare.prepareDirectoryForExport(options);
const archiveTarget = rootDir + "/" + hash + ".zip";
let exists = false;
try {
const stat = await fs.promises.stat(archiveTarget);
exists = stat.isFile();
} catch (err) {
}
if (!exists) {
const uri = `https://api.github.com/repos/${options.user}/${options.repo}/zipball/${hash}`;
await download_api_download.downloadFile(
{
uri,
headers: {
Accept: "application/vnd.github.v3+json",
Authorization: "token " + options.token
}
},
archiveTarget
);
}
const files = await fs.promises.readdir(rootDir);
const hashSearch = "-" + hash;
for (let i = 0; i < files.length; i++) {
const file = files[i];
if (file === hash + ".zip") {
continue;
}
const filename = rootDir + "/" + files[i];
const stat = await fs.promises.lstat(filename);
const isDir = stat.isDirectory();
if (
// Remove symbolic links
stat.isSymbolicLink() || // Remove if directory matches hash to avoid errors extracting zip
isDir && filename.slice(0 - hashSearch.length) === hashSearch || // Remove if directory and cleanupOldDirectories is not disabled
isDir && options.cleanupOldDirectories !== false || // Remove if file and cleanupOldFiles is enabled
!isDir && options.cleanupOldFiles
) {
try {
await fs.promises.rm(filename, {
force: true,
recursive: true
});
} catch (err) {
}
}
}
await download_helpers_unzip.unzip(archiveTarget, rootDir);
const matchingDirs = await findMatchingDirs(rootDir, hash);
if (matchingDirs.length !== 1) {
throw new Error(`Error unpacking ${hash}.zip`);
}
const contentsDir = rootDir + "/" + matchingDirs[0];
return {
downloadType: "github",
rootDir,
contentsDir,
hash
};
}
exports.downloadGitHubRepo = downloadGitHubRepo;