-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
/
domain.constant.ts
121 lines (107 loc) · 4.08 KB
/
domain.constant.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { AssetType } from '@app/infra/entities';
import { Duration } from 'luxon';
import { extname } from 'node:path';
import pkg from 'src/../../package.json';
export const AUDIT_LOG_MAX_DURATION = Duration.fromObject({ days: 100 });
const [major, minor, patch] = pkg.version.split('.');
export interface IServerVersion {
major: number;
minor: number;
patch: number;
}
export const serverVersion: IServerVersion = {
major: Number(major),
minor: Number(minor),
patch: Number(patch),
};
export const SERVER_VERSION = `${serverVersion.major}.${serverVersion.minor}.${serverVersion.patch}`;
export const APP_MEDIA_LOCATION = process.env.IMMICH_MEDIA_LOCATION || './upload';
const image: Record<string, string[]> = {
'.3fr': ['image/3fr', 'image/x-hasselblad-3fr'],
'.ari': ['image/ari', 'image/x-arriflex-ari'],
'.arw': ['image/arw', 'image/x-sony-arw'],
'.avif': ['image/avif'],
'.cap': ['image/cap', 'image/x-phaseone-cap'],
'.cin': ['image/cin', 'image/x-phantom-cin'],
'.cr2': ['image/cr2', 'image/x-canon-cr2'],
'.cr3': ['image/cr3', 'image/x-canon-cr3'],
'.crw': ['image/crw', 'image/x-canon-crw'],
'.dcr': ['image/dcr', 'image/x-kodak-dcr'],
'.dng': ['image/dng', 'image/x-adobe-dng'],
'.erf': ['image/erf', 'image/x-epson-erf'],
'.fff': ['image/fff', 'image/x-hasselblad-fff'],
'.gif': ['image/gif'],
'.heic': ['image/heic'],
'.heif': ['image/heif'],
'.iiq': ['image/iiq', 'image/x-phaseone-iiq'],
'.insp': ['image/jpeg'],
'.jpeg': ['image/jpeg'],
'.jpg': ['image/jpeg'],
'.jxl': ['image/jxl'],
'.k25': ['image/k25', 'image/x-kodak-k25'],
'.kdc': ['image/kdc', 'image/x-kodak-kdc'],
'.mrw': ['image/mrw', 'image/x-minolta-mrw'],
'.nef': ['image/nef', 'image/x-nikon-nef'],
'.orf': ['image/orf', 'image/x-olympus-orf'],
'.ori': ['image/ori', 'image/x-olympus-ori'],
'.pef': ['image/pef', 'image/x-pentax-pef'],
'.png': ['image/png'],
'.psd': ['image/psd', 'image/vnd.adobe.photoshop'],
'.raf': ['image/raf', 'image/x-fuji-raf'],
'.raw': ['image/raw', 'image/x-panasonic-raw'],
'.rwl': ['image/rwl', 'image/x-leica-rwl'],
'.sr2': ['image/sr2', 'image/x-sony-sr2'],
'.srf': ['image/srf', 'image/x-sony-srf'],
'.srw': ['image/srw', 'image/x-samsung-srw'],
'.tif': ['image/tiff'],
'.tiff': ['image/tiff'],
'.webp': ['image/webp'],
'.x3f': ['image/x3f', 'image/x-sigma-x3f'],
};
const profileExtensions = ['.avif', '.dng', '.heic', '.heif', '.jpeg', '.jpg', '.png', '.webp'];
const profile: Record<string, string[]> = Object.fromEntries(
Object.entries(image).filter(([key]) => profileExtensions.includes(key)),
);
const video: Record<string, string[]> = {
'.3gp': ['video/3gpp'],
'.avi': ['video/avi', 'video/msvideo', 'video/vnd.avi', 'video/x-msvideo'],
'.flv': ['video/x-flv'],
'.insv': ['video/mp4'],
'.m2ts': ['video/mp2t'],
'.m4v': ['video/x-m4v'],
'.mkv': ['video/x-matroska'],
'.mov': ['video/quicktime'],
'.mp4': ['video/mp4'],
'.mpg': ['video/mpeg'],
'.mts': ['video/mp2t'],
'.webm': ['video/webm'],
'.wmv': ['video/x-ms-wmv'],
};
const sidecar: Record<string, string[]> = {
'.xmp': ['application/xml', 'text/xml'],
};
const isType = (filename: string, r: Record<string, string[]>) => extname(filename).toLowerCase() in r;
const lookup = (filename: string) =>
({ ...image, ...video, ...sidecar })[extname(filename).toLowerCase()]?.[0] ?? 'application/octet-stream';
export const mimeTypes = {
image,
profile,
sidecar,
video,
isAsset: (filename: string) => isType(filename, image) || isType(filename, video),
isImage: (filename: string) => isType(filename, image),
isProfile: (filename: string) => isType(filename, profile),
isSidecar: (filename: string) => isType(filename, sidecar),
isVideo: (filename: string) => isType(filename, video),
lookup,
assetType: (filename: string) => {
const contentType = lookup(filename);
if (contentType.startsWith('image/')) {
return AssetType.IMAGE;
} else if (contentType.startsWith('video/')) {
return AssetType.VIDEO;
}
return AssetType.OTHER;
},
getSupportedFileExtensions: () => Object.keys(image).concat(Object.keys(video)),
};