chore(server,cli,web): housekeeping and stricter code style (#6751)

* add unicorn to eslint

* fix lint errors for cli

* fix merge

* fix album name extraction

* Update cli/src/commands/upload.command.ts

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>

* es2k23

* use lowercase os

* return undefined album name

* fix bug in asset response dto

* auto fix issues

* fix server code style

* es2022 and formatting

* fix compilation error

* fix test

* fix config load

* fix last lint errors

* set string type

* bump ts

* start work on web

* web formatting

* Fix UUIDParamDto as UUIDParamDto

* fix library service lint

* fix web errors

* fix errors

* formatting

* wip

* lints fixed

* web can now start

* alphabetical package json

* rename error

* chore: clean up

---------

Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Jonathan Jogenfors
2024-02-02 04:18:00 +01:00
committed by GitHub
parent e4d0560d49
commit f44fa45aa0
218 changed files with 2471 additions and 1244 deletions

View File

@@ -18,11 +18,11 @@ import {
SwaggerModule,
} from '@nestjs/swagger';
import { NextFunction, Response } from 'express';
import { writeFileSync } from 'fs';
import { access, constants } from 'fs/promises';
import _ from 'lodash';
import path, { isAbsolute } from 'path';
import { promisify } from 'util';
import { writeFileSync } from 'node:fs';
import { access, constants } from 'node:fs/promises';
import path, { isAbsolute } from 'node:path';
import { promisify } from 'node:util';
import { applyDecorators, UsePipes, ValidationPipe } from '@nestjs/common';
import { SchemaObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';
@@ -55,13 +55,15 @@ export const sendFile = async (
try {
const file = await handler();
switch (file.cacheControl) {
case CacheControl.PRIVATE_WITH_CACHE:
case CacheControl.PRIVATE_WITH_CACHE: {
res.set('Cache-Control', 'private, max-age=86400, no-transform');
break;
}
case CacheControl.PRIVATE_WITHOUT_CACHE:
case CacheControl.PRIVATE_WITHOUT_CACHE: {
res.set('Cache-Control', 'private, no-cache, no-transform');
break;
}
}
res.header('Content-Type', file.contentType);
@@ -94,21 +96,21 @@ export const asStreamableFile = ({ stream, type, length }: ImmichReadStream) =>
return new StreamableFile(stream, { type, length });
};
function sortKeys<T>(obj: T): T {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
return obj;
function sortKeys<T>(target: T): T {
if (!target || typeof target !== 'object' || Array.isArray(target)) {
return target;
}
const result: Partial<T> = {};
const keys = Object.keys(obj).sort() as Array<keyof T>;
const keys = Object.keys(target).sort() as Array<keyof T>;
for (const key of keys) {
result[key] = sortKeys(obj[key]);
result[key] = sortKeys(target[key]);
}
return result as T;
}
export const routeToErrorMessage = (methodName: string) =>
'Failed to ' + methodName.replace(/[A-Z]+/g, (letter) => ` ${letter.toLowerCase()}`);
'Failed to ' + methodName.replaceAll(/[A-Z]+/g, (letter) => ` ${letter.toLowerCase()}`);
const patchOpenAPI = (document: OpenAPIObject) => {
document.paths = sortKeys(document.paths);
@@ -152,7 +154,7 @@ const patchOpenAPI = (document: OpenAPIObject) => {
continue;
}
if ((operation.security || []).find((item) => !!item[Metadata.PUBLIC_SECURITY])) {
if ((operation.security || []).some((item) => !!item[Metadata.PUBLIC_SECURITY])) {
delete operation.security;
}
@@ -177,7 +179,7 @@ const patchOpenAPI = (document: OpenAPIObject) => {
return document;
};
export const useSwagger = (app: INestApplication, isDev: boolean) => {
export const useSwagger = (app: INestApplication, isDevelopment: boolean) => {
const config = new DocumentBuilder()
.setTitle('Immich')
.setDescription('Immich API')
@@ -203,7 +205,7 @@ export const useSwagger = (app: INestApplication, isDev: boolean) => {
operationIdFactory: (controllerKey: string, methodKey: string) => methodKey,
};
const doc = SwaggerModule.createDocument(app, config, options);
const specification = SwaggerModule.createDocument(app, config, options);
const customOptions: SwaggerCustomOptions = {
swaggerOptions: {
@@ -212,11 +214,11 @@ export const useSwagger = (app: INestApplication, isDev: boolean) => {
customSiteTitle: 'Immich API Documentation',
};
SwaggerModule.setup('doc', app, doc, customOptions);
SwaggerModule.setup('doc', app, specification, customOptions);
if (isDev) {
if (isDevelopment) {
// Generate API Documentation only in development mode
const outputPath = path.resolve(process.cwd(), '../open-api/immich-openapi-specs.json');
writeFileSync(outputPath, JSON.stringify(patchOpenAPI(doc), null, 2), { encoding: 'utf8' });
writeFileSync(outputPath, JSON.stringify(patchOpenAPI(specification), null, 2), { encoding: 'utf8' });
}
};