Activate typescript strict mode for server
Build and publish docker image snapshot / build-and-publish (push) Successful in 1m16s Details

Should have been set from the start
This commit is contained in:
Stefan Forstenlechner 2024-09-04 20:29:23 +02:00
parent 272edc8f20
commit c6f374de8a
7 changed files with 49 additions and 26 deletions

View File

@ -34,7 +34,7 @@ An easy way to run simple picture gallery is with docker.
```shell ```shell
docker pull docker pull ghcr.io/t-h-e/simple-picture-gallery:latest docker pull docker pull ghcr.io/t-h-e/simple-picture-gallery:latest
docker run -p 3005:3001 -v /mnt/path/to/pictures:/usr/src/app/public --name my-picture-gallery ghcr.io/t-h-e/simple-picture-gallery:latest docker run -d -p 3005:3001 -v /mnt/path/to/pictures:/usr/src/app/public --name my-picture-gallery ghcr.io/t-h-e/simple-picture-gallery:latest
``` ```
#### Customization #### Customization
@ -44,13 +44,13 @@ Create an environment file `.env` containing any of the following properties to
```properties ```properties
VITE_TITLE=My Gallery VITE_TITLE=My Gallery
VITE_APPBAR_COLOR=#F8AB2D VITE_APPBAR_COLOR=#F8AB2D
VITE_FAVICON_HREF=<URL to your favicon> VITE_FAVICON_HREF=<URL to your favicon or remove this property>
``` ```
And run docker with `--env-file .env` And run docker with `--env-file .env`
```shell ```shell
docker run -p 3005:3001 -v /mnt/path/to/pictures:/usr/src/app/public --env-file .env --name my-picture-gallery ghcr.io/t-h-e/simple-picture-gallery:latest docker run -d -p 3005:3001 -v /mnt/path/to/pictures:/usr/src/app/public --env-file .env --name my-picture-gallery ghcr.io/t-h-e/simple-picture-gallery:latest
``` ```
### Docker Compose ### Docker Compose

View File

@ -1,16 +1,15 @@
{ {
"compilerOptions": { "compilerOptions": {
"strict": true,
"target": "es5", "target": "es5",
"lib": [ "lib": [
"dom", "dom",
"dom.iterable", "dom.iterable",
"esnext" "esnext"
], ],
"allowJs": true,
"skipLibCheck": true, "skipLibCheck": true,
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"module": "esnext", "module": "esnext",

View File

@ -38,3 +38,16 @@ export const notEmpty = <TValue>(
): value is TValue => { ): value is TValue => {
return value !== null && value !== undefined; return value !== null && value !== undefined;
}; };
export const definedOrError = <TValue>(
value: TValue | void | null | undefined,
): TValue => {
if (notEmpty(value)) {
return value;
}
throw Error("Value was not defined.");
};
export const definedOrZero = (
value: number | void | null | undefined,
): number => (notEmpty(value) ? value : 0);

View File

@ -4,7 +4,7 @@ import express from "express";
import { a, FolderPreview, Folders, Image } from "../models"; import { a, FolderPreview, Folders, Image } from "../models";
import { publicPath, thumbnailPath, thumbnailPublicPath } from "../paths"; import { publicPath, thumbnailPath, thumbnailPublicPath } from "../paths";
import { securityValidation } from "./securityChecks"; import { securityValidation } from "./securityChecks";
import { getRequestedPath, notEmpty } from "./common"; import { definedOrError, getRequestedPath, notEmpty } from "./common";
import { consoleLogger } from "../logging"; import { consoleLogger } from "../logging";
import { getImage } from "./images"; import { getImage } from "./images";
@ -35,7 +35,7 @@ const getFirstImageInFolder = async (
): Promise<Image | void> => { ): Promise<Image | void> => {
const dirs = [dirPath]; const dirs = [dirPath];
while (dirs.length > 0) { while (dirs.length > 0) {
const curPath = dirs.shift(); const curPath = definedOrError(dirs.shift());
const dirContent = fs.readdirSync(path.posix.join(publicPath, curPath), { const dirContent = fs.readdirSync(path.posix.join(publicPath, curPath), {
withFileTypes: true, withFileTypes: true,
}); });

View File

@ -8,6 +8,7 @@ import { a, Folder, Image } from "../models";
import { consoleLogger } from "../logging"; import { consoleLogger } from "../logging";
import { securityValidation } from "./securityChecks"; import { securityValidation } from "./securityChecks";
import { import {
definedOrZero,
getRequestedPath, getRequestedPath,
getSrc, getSrc,
getThumbnail, getThumbnail,
@ -21,12 +22,15 @@ const toImage = (
f: Dirent, f: Dirent,
thumbnailExists: boolean, thumbnailExists: boolean,
): Image => { ): Image => {
const widthAndHeightSwap = metadata.orientation > 4; // see https://exiftool.org/TagNames/EXIF.html const widthAndHeightSwap =
metadata.orientation !== undefined && metadata.orientation > 4; // see https://exiftool.org/TagNames/EXIF.html
return a<Image>({ return a<Image>({
src: getSrc(filePath, f), src: getSrc(filePath, f),
thumbnail: getThumbnail(filePath, f, thumbnailExists), thumbnail: getThumbnail(filePath, f, thumbnailExists),
width: widthAndHeightSwap ? metadata.height : metadata.width, width: definedOrZero(widthAndHeightSwap ? metadata.height : metadata.width),
height: widthAndHeightSwap ? metadata.width : metadata.height, height: definedOrZero(
widthAndHeightSwap ? metadata.width : metadata.height,
),
}); });
}; };

View File

@ -12,6 +12,9 @@ export const createThumbnailAsyncForImage = (image: string) => {
sharp(publicImagePath) sharp(publicImagePath)
.metadata() .metadata()
.then((info) => { .then((info) => {
if (info.width === undefined || info.height === undefined) {
return;
}
const width = Math.max( const width = Math.max(
Math.min(info.width, minimumPixelForThumbnail), Math.min(info.width, minimumPixelForThumbnail),
Math.round((info.width * percentage) / 100), Math.round((info.width * percentage) / 100),
@ -25,6 +28,9 @@ export const createThumbnailAsyncForImage = (image: string) => {
path.posix.join(thumbnailPublicPath, path.dirname(image)), path.posix.join(thumbnailPublicPath, path.dirname(image)),
{ recursive: true }, { recursive: true },
() => { () => {
if (info.width === undefined || info.height === undefined) {
return;
}
sharp(publicImagePath) sharp(publicImagePath)
.withMetadata() .withMetadata()
.resize(info.width > info.height ? { width } : { height }) .resize(info.width > info.height ? { width } : { height })

View File

@ -1,5 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"strict": true,
"module": "commonjs", "module": "commonjs",
"esModuleInterop": true, "esModuleInterop": true,
"target": "es6", "target": "es6",