mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-06-01 13:21:41 +02:00
fix: improve error message for folders
This commit is contained in:
@@ -2,7 +2,7 @@ import { join, basename } from "path";
|
|||||||
import { Response } from "express";
|
import { Response } from "express";
|
||||||
import { Readable } from "stream";
|
import { Readable } from "stream";
|
||||||
import Repository from "./Repository";
|
import Repository from "./Repository";
|
||||||
import { Tree, TreeElement, TreeFile } from "./types";
|
import { FILE_TYPE, Tree, TreeElement, TreeFile } from "./types";
|
||||||
import storage from "./storage";
|
import storage from "./storage";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
import {
|
import {
|
||||||
@@ -175,8 +175,14 @@ export default class AnonymizedFile {
|
|||||||
httpStatus: 403,
|
httpStatus: 403,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (await storage.exists(this.originalCachePath)) {
|
const exist = await storage.exists(this.originalCachePath);
|
||||||
|
if (exist == FILE_TYPE.FILE) {
|
||||||
return storage.read(this.originalCachePath);
|
return storage.read(this.originalCachePath);
|
||||||
|
} else if (exist == FILE_TYPE.FOLDER) {
|
||||||
|
throw new AnonymousError("folder_not_supported", {
|
||||||
|
object: this,
|
||||||
|
httpStatus: 400,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return await this.repository.source?.getFileContent(this);
|
return await this.repository.source?.getFileContent(this);
|
||||||
}
|
}
|
||||||
@@ -223,7 +229,7 @@ export default class AnonymizedFile {
|
|||||||
// unable to get file size
|
// unable to get file size
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const anonymizer = new AnonymizeTransformer(this);
|
const anonymizer = new AnonymizeTransformer(this);
|
||||||
|
|
||||||
anonymizer.once("transform", (data) => {
|
anonymizer.once("transform", (data) => {
|
||||||
|
|||||||
+11
-2
@@ -1,6 +1,13 @@
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import storage from "./storage";
|
import storage from "./storage";
|
||||||
import { RepositoryStatus, Source, Tree, TreeElement, TreeFile } from "./types";
|
import {
|
||||||
|
FILE_TYPE,
|
||||||
|
RepositoryStatus,
|
||||||
|
Source,
|
||||||
|
Tree,
|
||||||
|
TreeElement,
|
||||||
|
TreeFile,
|
||||||
|
} from "./types";
|
||||||
import { Readable } from "stream";
|
import { Readable } from "stream";
|
||||||
import User from "./User";
|
import User from "./User";
|
||||||
import GitHubStream from "./source/GitHubStream";
|
import GitHubStream from "./source/GitHubStream";
|
||||||
@@ -333,7 +340,9 @@ export default class Repository {
|
|||||||
async removeCache() {
|
async removeCache() {
|
||||||
this.model.isReseted = true;
|
this.model.isReseted = true;
|
||||||
await this.model.save();
|
await this.model.save();
|
||||||
if (await storage.exists(this._model.repoId + "/")) {
|
if (
|
||||||
|
(await storage.exists(this._model.repoId + "/")) !== FILE_TYPE.NOT_FOUND
|
||||||
|
) {
|
||||||
return storage.rm(this._model.repoId + "/");
|
return storage.rm(this._model.repoId + "/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import storage from "../storage";
|
|||||||
import Repository from "../Repository";
|
import Repository from "../Repository";
|
||||||
import GitHubBase from "./GitHubBase";
|
import GitHubBase from "./GitHubBase";
|
||||||
import AnonymizedFile from "../AnonymizedFile";
|
import AnonymizedFile from "../AnonymizedFile";
|
||||||
import { RepositoryStatus, SourceBase } from "../types";
|
import { FILE_TYPE, RepositoryStatus, SourceBase } from "../types";
|
||||||
import AnonymousError from "../AnonymousError";
|
import AnonymousError from "../AnonymousError";
|
||||||
import { tryCatch } from "bullmq";
|
import { tryCatch } from "bullmq";
|
||||||
|
|
||||||
@@ -132,8 +132,14 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getFileContent(file: AnonymizedFile): Promise<Readable> {
|
async getFileContent(file: AnonymizedFile): Promise<Readable> {
|
||||||
if (await storage.exists(file.originalCachePath)) {
|
const exists = await storage.exists(file.originalCachePath);
|
||||||
|
if (exists === FILE_TYPE.FILE) {
|
||||||
return storage.read(file.originalCachePath);
|
return storage.read(file.originalCachePath);
|
||||||
|
} else if (exists === FILE_TYPE.FOLDER) {
|
||||||
|
throw new AnonymousError("folder_not_supported", {
|
||||||
|
httpStatus: 400,
|
||||||
|
object: file,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// will throw an error if the file is not in the repository
|
// will throw an error if the file is not in the repository
|
||||||
await file.originalPath();
|
await file.originalPath();
|
||||||
@@ -145,7 +151,7 @@ export default class GitHubDownload extends GitHubBase implements SourceBase {
|
|||||||
|
|
||||||
async getFiles() {
|
async getFiles() {
|
||||||
const folder = this.repository.originalCachePath;
|
const folder = this.repository.originalCachePath;
|
||||||
if (!(await storage.exists(folder))) {
|
if ((await storage.exists(folder)) === FILE_TYPE.NOT_FOUND) {
|
||||||
await this.download();
|
await this.download();
|
||||||
}
|
}
|
||||||
return storage.listFiles(folder);
|
return storage.listFiles(folder);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { SourceBase, StorageBase, Tree } from "../types";
|
import { FILE_TYPE, SourceBase, StorageBase, Tree } from "../types";
|
||||||
import config from "../../config";
|
import config from "../../config";
|
||||||
|
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
@@ -17,8 +17,15 @@ export default class FileSystem implements StorageBase {
|
|||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async exists(p: string): Promise<boolean> {
|
async exists(p: string): Promise<FILE_TYPE> {
|
||||||
return fs.existsSync(join(config.FOLDER, p));
|
try {
|
||||||
|
const stat = await fs.promises.stat(join(config.FOLDER, p));
|
||||||
|
if (stat.isDirectory()) return FILE_TYPE.FOLDER;
|
||||||
|
if (stat.isFile()) return FILE_TYPE.FILE;
|
||||||
|
} catch (_) {
|
||||||
|
// ignore file not found or not downloaded
|
||||||
|
}
|
||||||
|
return FILE_TYPE.NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
@@ -49,11 +56,7 @@ export default class FileSystem implements StorageBase {
|
|||||||
file?: AnonymizedFile,
|
file?: AnonymizedFile,
|
||||||
source?: SourceBase
|
source?: SourceBase
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!(await this.exists(dirname(p)))) {
|
await this.mk(dirname(p));
|
||||||
await fs.promises.mkdir(dirname(join(config.FOLDER, p)), {
|
|
||||||
recursive: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return fs.promises.writeFile(join(config.FOLDER, p), data);
|
return fs.promises.writeFile(join(config.FOLDER, p), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +70,7 @@ export default class FileSystem implements StorageBase {
|
|||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async mk(dir: string): Promise<void> {
|
async mk(dir: string): Promise<void> {
|
||||||
if (!(await this.exists(dir)))
|
if ((await this.exists(dir)) === FILE_TYPE.NOT_FOUND)
|
||||||
fs.promises.mkdir(join(config.FOLDER, dir), { recursive: true });
|
fs.promises.mkdir(join(config.FOLDER, dir), { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
import { SourceBase, StorageBase, Tree, TreeFile } from "../types";
|
import { FILE_TYPE, SourceBase, StorageBase, Tree, TreeFile } from "../types";
|
||||||
import {
|
import {
|
||||||
GetObjectCommand,
|
GetObjectCommand,
|
||||||
ListObjectsV2CommandOutput,
|
ListObjectsV2CommandOutput,
|
||||||
@@ -44,14 +44,12 @@ export default class S3Storage implements StorageBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async exists(path: string): Promise<boolean> {
|
async exists(path: string): Promise<FILE_TYPE> {
|
||||||
if (!config.S3_BUCKET) throw new Error("S3_BUCKET not set");
|
if (!config.S3_BUCKET) throw new Error("S3_BUCKET not set");
|
||||||
try {
|
try {
|
||||||
await this.client().headObject({
|
// if we can get the file info, it is a file
|
||||||
Bucket: config.S3_BUCKET,
|
await this.fileInfo(path);
|
||||||
Key: path,
|
return FILE_TYPE.FILE;
|
||||||
});
|
|
||||||
return true;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// check if it is a directory
|
// check if it is a directory
|
||||||
const data = await this.client().listObjectsV2({
|
const data = await this.client().listObjectsV2({
|
||||||
@@ -59,7 +57,9 @@ export default class S3Storage implements StorageBase {
|
|||||||
Prefix: path,
|
Prefix: path,
|
||||||
MaxKeys: 1,
|
MaxKeys: 1,
|
||||||
});
|
});
|
||||||
return (data.Contents?.length || 0) > 0;
|
return (data.Contents?.length || 0) > 0
|
||||||
|
? FILE_TYPE.FOLDER
|
||||||
|
: FILE_TYPE.NOT_FOUND;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -32,6 +32,12 @@ export interface SourceBase {
|
|||||||
|
|
||||||
export type Source = GitHubDownload | GitHubStream | Zip;
|
export type Source = GitHubDownload | GitHubStream | Zip;
|
||||||
|
|
||||||
|
export enum FILE_TYPE {
|
||||||
|
FILE = "file",
|
||||||
|
FOLDER = "folder",
|
||||||
|
NOT_FOUND = "not_found",
|
||||||
|
}
|
||||||
|
|
||||||
export interface StorageBase {
|
export interface StorageBase {
|
||||||
/**
|
/**
|
||||||
* The type of storage
|
* The type of storage
|
||||||
@@ -42,7 +48,7 @@ export interface StorageBase {
|
|||||||
* check if the path exists
|
* check if the path exists
|
||||||
* @param path the path to check
|
* @param path the path to check
|
||||||
*/
|
*/
|
||||||
exists(path: string): Promise<boolean>;
|
exists(path: string): Promise<FILE_TYPE>;
|
||||||
|
|
||||||
send(p: string, res: Response): Promise<void>;
|
send(p: string, res: Response): Promise<void>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user