refactor(server)*: tsconfigs (#2689)

* refactor(server): tsconfigs

* chore: dummy commit

* fix: start.sh

* chore: restore original entry scripts
This commit is contained in:
Jason Rasmussen
2023-06-08 11:01:07 -04:00
committed by GitHub
parent a2130aa6c5
commit 8ebac41318
465 changed files with 209 additions and 332 deletions

View File

@@ -0,0 +1,3 @@
export * from './storage.core';
export * from './storage.repository';
export * from './storage.service';

View File

@@ -0,0 +1,27 @@
import { join } from 'node:path';
import { APP_MEDIA_LOCATION } from '../domain.constant';
export enum StorageFolder {
ENCODED_VIDEO = 'encoded-video',
LIBRARY = 'library',
UPLOAD = 'upload',
PROFILE = 'profile',
THUMBNAILS = 'thumbs',
}
export class StorageCore {
getFolderLocation(
folder: StorageFolder.ENCODED_VIDEO | StorageFolder.UPLOAD | StorageFolder.PROFILE | StorageFolder.THUMBNAILS,
userId: string,
) {
return join(this.getBaseFolder(folder), userId);
}
getLibraryFolder(user: { storageLabel: string | null; id: string }) {
return join(this.getBaseFolder(StorageFolder.LIBRARY), user.storageLabel || user.id);
}
getBaseFolder(folder: StorageFolder) {
return join(APP_MEDIA_LOCATION, folder);
}
}

View File

@@ -0,0 +1,26 @@
import { ReadStream } from 'fs';
export interface ImmichReadStream {
stream: ReadStream;
type: string;
length: number;
}
export interface DiskUsage {
available: number;
free: number;
total: number;
}
export const IStorageRepository = 'IStorageRepository';
export interface IStorageRepository {
createReadStream(filepath: string, mimeType: string): Promise<ImmichReadStream>;
unlink(filepath: string): Promise<void>;
unlinkDir(folder: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;
removeEmptyDirs(folder: string): Promise<void>;
moveFile(source: string, target: string): Promise<void>;
checkFileExists(filepath: string, mode?: number): Promise<boolean>;
mkdirSync(filepath: string): void;
checkDiskUsage(folder: string): Promise<DiskUsage>;
}

View File

@@ -0,0 +1,46 @@
import { newStorageRepositoryMock } from '@test';
import { IStorageRepository } from '.';
import { StorageService } from './storage.service';
describe(StorageService.name, () => {
let sut: StorageService;
let storageMock: jest.Mocked<IStorageRepository>;
beforeEach(async () => {
storageMock = newStorageRepositoryMock();
sut = new StorageService(storageMock);
});
it('should work', () => {
expect(sut).toBeDefined();
});
describe('init', () => {
it('should create the library folder on initialization', () => {
sut.init();
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/library');
});
});
describe('handleDeleteFiles', () => {
it('should handle null values', async () => {
await sut.handleDeleteFiles({ files: [undefined, null] });
expect(storageMock.unlink).not.toHaveBeenCalled();
});
it('should handle an error removing a file', async () => {
storageMock.unlink.mockRejectedValue(new Error('something-went-wrong'));
await sut.handleDeleteFiles({ files: ['path/to/something'] });
expect(storageMock.unlink).toHaveBeenCalledWith('path/to/something');
});
it('should remove the file', async () => {
await sut.handleDeleteFiles({ files: ['path/to/something'] });
expect(storageMock.unlink).toHaveBeenCalledWith('path/to/something');
});
});
});

View File

@@ -0,0 +1,36 @@
import { Inject, Injectable, Logger } from '@nestjs/common';
import { IDeleteFilesJob } from '../job';
import { StorageCore, StorageFolder } from './storage.core';
import { IStorageRepository } from './storage.repository';
@Injectable()
export class StorageService {
private logger = new Logger(StorageService.name);
private storageCore = new StorageCore();
constructor(@Inject(IStorageRepository) private storageRepository: IStorageRepository) {}
init() {
const libraryBase = this.storageCore.getBaseFolder(StorageFolder.LIBRARY);
this.storageRepository.mkdirSync(libraryBase);
}
async handleDeleteFiles(job: IDeleteFilesJob) {
const { files } = job;
// TODO: one job per file
for (const file of files) {
if (!file) {
continue;
}
try {
await this.storageRepository.unlink(file);
} catch (error: any) {
this.logger.warn('Unable to remove file from disk', error);
}
}
return true;
}
}