mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-05-20 16:34:44 +02:00
multiple fixes
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import got from "got";
|
||||
import { Parse } from "unzip-stream";
|
||||
import archiver = require("archiver");
|
||||
|
||||
import GitHubDownload from "./source/GitHubDownload";
|
||||
import { AnonymizeTransformer, anonymizePath } from "./anonymize-utils";
|
||||
|
||||
export interface StreamAnonymizedZipOptions {
|
||||
repoId: string;
|
||||
organization: string;
|
||||
repoName: string;
|
||||
commit: string;
|
||||
getToken: () => string | Promise<string>;
|
||||
anonymizerOptions: ConstructorParameters<typeof AnonymizeTransformer>[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stream the GitHub source zip for a repository, anonymize each entry on the
|
||||
* fly, and pipe the resulting archive into the provided writable response.
|
||||
*
|
||||
* No data is written to local storage — the zip flows GitHub → unzip → per
|
||||
* file anonymizer → archiver → response.
|
||||
*/
|
||||
export async function streamAnonymizedZip(
|
||||
opt: StreamAnonymizedZipOptions,
|
||||
res: NodeJS.WritableStream & {
|
||||
on(event: string, listener: (...args: unknown[]) => void): unknown;
|
||||
}
|
||||
): Promise<void> {
|
||||
const source = new GitHubDownload({
|
||||
repoId: opt.repoId,
|
||||
organization: opt.organization,
|
||||
repoName: opt.repoName,
|
||||
commit: opt.commit,
|
||||
getToken: opt.getToken,
|
||||
});
|
||||
|
||||
const response = await source.getZipUrl();
|
||||
const downloadStream = got.stream(response.url);
|
||||
|
||||
res.on("error", (error) => {
|
||||
console.error(error);
|
||||
downloadStream.destroy();
|
||||
});
|
||||
res.on("close", () => {
|
||||
downloadStream.destroy();
|
||||
});
|
||||
|
||||
const archive = archiver("zip", {});
|
||||
downloadStream
|
||||
.on("error", (error) => {
|
||||
console.error(error);
|
||||
try {
|
||||
archive.finalize();
|
||||
} catch {
|
||||
/* ignored */
|
||||
}
|
||||
})
|
||||
.on("close", () => {
|
||||
try {
|
||||
archive.finalize();
|
||||
} catch {
|
||||
/* ignored */
|
||||
}
|
||||
})
|
||||
.pipe(Parse())
|
||||
.on("entry", (entry: NodeJS.ReadableStream & { type: string; path: string; autodrain: () => void }) => {
|
||||
if (entry.type === "File") {
|
||||
try {
|
||||
const fileName = anonymizePath(
|
||||
entry.path.substring(entry.path.indexOf("/") + 1),
|
||||
opt.anonymizerOptions.terms || []
|
||||
);
|
||||
const anonymizer = new AnonymizeTransformer(opt.anonymizerOptions);
|
||||
anonymizer.opt.filePath = fileName;
|
||||
const st = entry.pipe(anonymizer);
|
||||
archive.append(st, { name: fileName });
|
||||
} catch (error) {
|
||||
entry.autodrain();
|
||||
console.error(error);
|
||||
}
|
||||
} else {
|
||||
entry.autodrain();
|
||||
}
|
||||
})
|
||||
.on("error", (error: Error) => {
|
||||
console.error(error);
|
||||
try {
|
||||
archive.finalize();
|
||||
} catch {
|
||||
/* ignored */
|
||||
}
|
||||
})
|
||||
.on("finish", () => {
|
||||
try {
|
||||
archive.finalize();
|
||||
} catch {
|
||||
/* ignored */
|
||||
}
|
||||
});
|
||||
|
||||
archive.pipe(res).on("error", (error) => {
|
||||
console.error(error);
|
||||
(res as { end?: () => void }).end?.();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user