mirror of
https://github.com/kmc7468/arkvault.git
synced 2026-11-04 08:10:28 +09:00
서버, 클라이언트, 서비스 워커 공용 코드를 lib/shared로 분리하고 브라우저 전용 모듈을 lib/client로 재구성
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a6aa1765b
commit
aee87fd9b6
82 files changed
+326
-221
No files matched your search
@@ -2,10 +2,9 @@ import { FileRepo, MediaRepo } from "#lib/server/db/index.js";
|
||||
import type { Ciphertext } from "#lib/server/db/schema/index.js";
|
||||
import { AppError } from "#lib/server/errors.js";
|
||||
import { createEncContentStream } from "#lib/server/storage/index.js";
|
||||
import type { RangeRequest } from "#lib/shared/http.js";
|
||||
import { schedulePendingFileDeletions } from "./fileDeletion";
|
||||
|
||||
type Range = { start?: number; end?: number };
|
||||
|
||||
export const getFile = async (userId: number, fileId: number) => {
|
||||
const file = await FileRepo.getFile(userId, fileId);
|
||||
if (!file) {
|
||||
@@ -68,7 +67,7 @@ export const getFileThumbnail = async (userId: number, fileId: number) => {
|
||||
|
||||
const decodeIv = (iv: string | null) => (iv ? Buffer.from(iv, "base64") : undefined);
|
||||
|
||||
export const getFileStream = async (userId: number, fileId: number, range?: Range) => {
|
||||
export const getFileStream = async (userId: number, fileId: number, range?: RangeRequest) => {
|
||||
const file = await FileRepo.getFile(userId, fileId);
|
||||
if (!file) {
|
||||
throw new AppError("NOT_FOUND", "File not found");
|
||||
@@ -76,7 +75,11 @@ export const getFileStream = async (userId: number, fileId: number, range?: Rang
|
||||
return await createEncContentStream(file.path, decodeIv(file.encContentIv), range);
|
||||
};
|
||||
|
||||
export const getFileThumbnailStream = async (userId: number, fileId: number, range?: Range) => {
|
||||
export const getFileThumbnailStream = async (
|
||||
userId: number,
|
||||
fileId: number,
|
||||
range?: RangeRequest,
|
||||
) => {
|
||||
const thumbnail = await getFileThumbnail(userId, fileId);
|
||||
return await createEncContentStream(thumbnail.path, decodeIv(thumbnail.encContentIv), range);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import { open } from "fs/promises";
|
||||
import type { Readable } from "stream";
|
||||
import { ENCRYPTION_OVERHEAD, ENCRYPTED_CHUNK_SIZE } from "#lib/constants/index.js";
|
||||
import { AppError } from "#lib/server/errors.js";
|
||||
import { ENCRYPTION_OVERHEAD, ENCRYPTED_CHUNK_SIZE } from "#lib/shared/format/index.js";
|
||||
|
||||
const invalidChunkSize = () => new AppError("BAD_REQUEST", "Invalid chunk size");
|
||||
|
||||
|
||||
@@ -2,22 +2,22 @@ import { createReadStream } from "fs";
|
||||
import { stat } from "fs/promises";
|
||||
import { Readable } from "stream";
|
||||
import { AppError } from "#lib/server/errors.js";
|
||||
import { resolveRange, type RangeRequest } from "#lib/shared/http.js";
|
||||
|
||||
export const createEncContentStream = async (
|
||||
path: string,
|
||||
iv?: Buffer,
|
||||
range?: { start?: number; end?: number },
|
||||
rangeRequest?: RangeRequest,
|
||||
) => {
|
||||
const { size: fileSize } = await stat(path);
|
||||
const ivSize = iv?.byteLength ?? 0;
|
||||
const totalSize = fileSize + ivSize;
|
||||
|
||||
const start = range?.start ?? 0;
|
||||
const end = range?.end ?? totalSize - 1;
|
||||
if (start > end || start < 0 || end >= totalSize) {
|
||||
const range = resolveRange(rangeRequest, fileSize + ivSize);
|
||||
if (!range) {
|
||||
throw new AppError("RANGE_NOT_SATISFIABLE", "Invalid range");
|
||||
}
|
||||
|
||||
const { start, end } = range;
|
||||
return {
|
||||
encContentStream: Readable.toWeb(
|
||||
Readable.from(
|
||||
@@ -34,7 +34,7 @@ export const createEncContentStream = async (
|
||||
})(),
|
||||
),
|
||||
),
|
||||
range: { start, end, total: totalSize },
|
||||
isRangeRequest: !!range,
|
||||
range,
|
||||
isRangeRequest: !!rangeRequest,
|
||||
};
|
||||
};
|
||||
Reference in new issue
Block a user