mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-13 00:02:37 +10:00
feat: fs object metadata cache and validation
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import type { ObjectMetadata, ObjectReference, Source } from "./objectHandler";
|
||||
import { ObjectBackend } from "./objectHandler";
|
||||
import { ObjectBackend, objectMetadata } from "./objectHandler";
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
@ -8,12 +8,15 @@ import { createHash } from "crypto";
|
||||
import prisma from "../db/database";
|
||||
import cacheHandler from "../cache";
|
||||
import { systemConfig } from "../config/sys-conf";
|
||||
import { type } from "arktype";
|
||||
|
||||
export class FsObjectBackend extends ObjectBackend {
|
||||
private baseObjectPath: string;
|
||||
private baseMetadataPath: string;
|
||||
|
||||
private hashStore = new FsHashStore();
|
||||
private metadataCache =
|
||||
cacheHandler.createCache<ObjectMetadata>("ObjectMetadata");
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@ -102,17 +105,27 @@ export class FsObjectBackend extends ObjectBackend {
|
||||
const metadataPath = path.join(this.baseMetadataPath, `${id}.json`);
|
||||
if (!fs.existsSync(metadataPath)) return true;
|
||||
fs.rmSync(metadataPath);
|
||||
// remove item from cache
|
||||
// remove item from caches
|
||||
await this.metadataCache.remove(id);
|
||||
await this.hashStore.delete(id);
|
||||
return true;
|
||||
}
|
||||
async fetchMetadata(
|
||||
id: ObjectReference,
|
||||
): Promise<ObjectMetadata | undefined> {
|
||||
const cacheResult = await this.metadataCache.get(id);
|
||||
if (cacheResult !== null) return cacheResult;
|
||||
|
||||
const metadataPath = path.join(this.baseMetadataPath, `${id}.json`);
|
||||
if (!fs.existsSync(metadataPath)) return undefined;
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
||||
return metadata as ObjectMetadata;
|
||||
const metadataRaw = JSON.parse(fs.readFileSync(metadataPath, "utf-8"));
|
||||
const metadata = objectMetadata(metadataRaw);
|
||||
if (metadata instanceof type.errors) {
|
||||
console.error("FsObjectBackend#fetchMetadata", metadata.summary);
|
||||
return undefined;
|
||||
}
|
||||
await this.metadataCache.set(id, metadata);
|
||||
return metadata;
|
||||
}
|
||||
async writeMetadata(
|
||||
id: ObjectReference,
|
||||
@ -121,6 +134,7 @@ export class FsObjectBackend extends ObjectBackend {
|
||||
const metadataPath = path.join(this.baseMetadataPath, `${id}.json`);
|
||||
if (!fs.existsSync(metadataPath)) return false;
|
||||
fs.writeFileSync(metadataPath, JSON.stringify(metadata));
|
||||
await this.metadataCache.set(id, metadata);
|
||||
return true;
|
||||
}
|
||||
async fetchHash(id: ObjectReference): Promise<string | undefined> {
|
||||
|
||||
@ -14,17 +14,22 @@
|
||||
* anotherUserId:write
|
||||
*/
|
||||
|
||||
import { type } from "arktype";
|
||||
import { parse as getMimeTypeBuffer } from "file-type-mime";
|
||||
import type { Writable } from "stream";
|
||||
import { Readable } from "stream";
|
||||
import { getMimeType as getMimeTypeStream } from "stream-mime-type";
|
||||
|
||||
export type ObjectReference = string;
|
||||
export type ObjectMetadata = {
|
||||
mime: string;
|
||||
permissions: string[];
|
||||
userMetadata: { [key: string]: string };
|
||||
};
|
||||
|
||||
export const objectMetadata = type({
|
||||
mime: "string",
|
||||
permissions: "string[]",
|
||||
userMetadata: {
|
||||
"[string]": "string",
|
||||
},
|
||||
});
|
||||
export type ObjectMetadata = typeof objectMetadata.infer;
|
||||
|
||||
export enum ObjectPermission {
|
||||
Read = "read",
|
||||
|
||||
Reference in New Issue
Block a user