1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-28 06:31:58 +00:00

fix(server): keep system config transformations (#13796)

This commit is contained in:
Jason Rasmussen 2024-10-29 11:59:35 -04:00 committed by GitHub
parent 2c86da07c6
commit 37e437a568
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 5 deletions

View file

@ -237,6 +237,24 @@ describe(SystemConfigService.name, () => {
expect(systemMock.readFile).toHaveBeenCalledWith('immich-config.json'); expect(systemMock.readFile).toHaveBeenCalledWith('immich-config.json');
}); });
it('should transform booleans', async () => {
configMock.getEnv.mockReturnValue(mockEnvData({ configFile: 'immich-config.json' }));
systemMock.readFile.mockResolvedValue(JSON.stringify({ ffmpeg: { twoPass: 'false' } }));
await expect(sut.getSystemConfig()).resolves.toMatchObject({
ffmpeg: expect.objectContaining({ twoPass: false }),
});
});
it('should transform numbers', async () => {
configMock.getEnv.mockReturnValue(mockEnvData({ configFile: 'immich-config.json' }));
systemMock.readFile.mockResolvedValue(JSON.stringify({ ffmpeg: { threads: '42' } }));
await expect(sut.getSystemConfig()).resolves.toMatchObject({
ffmpeg: expect.objectContaining({ threads: 42 }),
});
});
it('should log errors with the config file', async () => { it('should log errors with the config file', async () => {
configMock.getEnv.mockReturnValue(mockEnvData({ configFile: 'immich-config.json' })); configMock.getEnv.mockReturnValue(mockEnvData({ configFile: 'immich-config.json' }));

View file

@ -1,5 +1,5 @@
import AsyncLock from 'async-lock'; import AsyncLock from 'async-lock';
import { plainToInstance } from 'class-transformer'; import { instanceToPlain, plainToInstance } from 'class-transformer';
import { validate } from 'class-validator'; import { validate } from 'class-validator';
import { load as loadYaml } from 'js-yaml'; import { load as loadYaml } from 'js-yaml';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -87,13 +87,13 @@ const buildConfig = async (repos: RepoDeps) => {
: await metadataRepo.get(SystemMetadataKey.SYSTEM_CONFIG); : await metadataRepo.get(SystemMetadataKey.SYSTEM_CONFIG);
// merge with defaults // merge with defaults
const config = _.cloneDeep(defaults); const rawConfig = _.cloneDeep(defaults);
for (const property of getKeysDeep(partial)) { for (const property of getKeysDeep(partial)) {
_.set(config, property, _.get(partial, property)); _.set(rawConfig, property, _.get(partial, property));
} }
// check for extra properties // check for extra properties
const unknownKeys = _.cloneDeep(config); const unknownKeys = _.cloneDeep(rawConfig);
for (const property of getKeysDeep(defaults)) { for (const property of getKeysDeep(defaults)) {
unsetDeep(unknownKeys, property); unsetDeep(unknownKeys, property);
} }
@ -103,7 +103,8 @@ const buildConfig = async (repos: RepoDeps) => {
} }
// validate full config // validate full config
const errors = await validate(plainToInstance(SystemConfigDto, config)); const instance = plainToInstance(SystemConfigDto, rawConfig);
const errors = await validate(instance);
if (errors.length > 0) { if (errors.length > 0) {
if (configFile) { if (configFile) {
throw new Error(`Invalid value(s) in file: ${errors}`); throw new Error(`Invalid value(s) in file: ${errors}`);
@ -112,6 +113,9 @@ const buildConfig = async (repos: RepoDeps) => {
} }
} }
// return config with class-transform changes
const config = instanceToPlain(instance) as SystemConfig;
if (config.server.externalDomain.length > 0) { if (config.server.externalDomain.length > 0) {
config.server.externalDomain = new URL(config.server.externalDomain).origin; config.server.externalDomain = new URL(config.server.externalDomain).origin;
} }