From 7e5592fec5aada38ae8ef4532d86848a08fea1e5 Mon Sep 17 00:00:00 2001 From: Min Idzelis Date: Sat, 24 Jan 2026 00:18:02 -0500 Subject: [PATCH] feat: make progressive system config optional (#25486) --- ...m_config_generated_fullsize_image_dto.dart | Bin 4021 -> 4009 bytes .../system_config_generated_image_dto.dart | Bin 3854 -> 3842 bytes open-api/immich-openapi-specs.json | 4 +-- open-api/typescript-sdk/src/fetch-client.ts | 4 +-- .../system-config.controller.spec.ts | 28 ++++++++++++++++++ server/src/dtos/system-config.dto.ts | 8 ++--- server/src/types.ts | 4 +-- 7 files changed, 38 insertions(+), 10 deletions(-) diff --git a/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart b/mobile/openapi/lib/model/system_config_generated_fullsize_image_dto.dart index f36105f590aa5570b5430a56b72369a09ea13f35..e7111771bdec9b174e2d359fe2a9ae928764774d 100644 GIT binary patch delta 55 zcmdlgzfyj~4@U8ljLc%af};HNqSWHz%(7GkTZOd5oZ`&_Ou1~F3ikG3Uh3vL4k7l* Hi}{5BKBf}V delta 50 ycmZ1}zg2$255~!2Onh7gMfvGPsl~;aWt;h#a@iOaH@9*Kv2!DYQz!THO924BnGqfU diff --git a/mobile/openapi/lib/model/system_config_generated_image_dto.dart b/mobile/openapi/lib/model/system_config_generated_image_dto.dart index 7dd5b2be7e20069914f7b4d798e00b828c7134a0..a46fc13d275e7c0eb451630d0f802e5aa08f9273 100644 GIT binary patch delta 55 zcmeB^Ym(b=lu^7SBePhqpeR4RD7Cmavn*A?Rv|4hr+D*SMoBhK1$%oiFLm>G_GfI9 IKk&%`066FrY5)KL delta 60 zcmZpY>yz7Xlu@E6wXig^C^bc)BqOs}ub?PDy(qP~IJ0c?9Y#quM#atl*q^a+BZN~Y I-{DgO0L2RzasU7T diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index 1129dd486..5f133b4f8 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -22625,6 +22625,7 @@ ] }, "progressive": { + "default": false, "type": "boolean" }, "quality": { @@ -22636,7 +22637,6 @@ "required": [ "enabled", "format", - "progressive", "quality" ], "type": "object" @@ -22651,6 +22651,7 @@ ] }, "progressive": { + "default": false, "type": "boolean" }, "quality": { @@ -22665,7 +22666,6 @@ }, "required": [ "format", - "progressive", "quality", "size" ], diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index a6bbf5cdd..52f6621d9 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -1538,12 +1538,12 @@ export type SystemConfigFFmpegDto = { export type SystemConfigGeneratedFullsizeImageDto = { enabled: boolean; format: ImageFormat; - progressive: boolean; + progressive?: boolean; quality: number; }; export type SystemConfigGeneratedImageDto = { format: ImageFormat; - progressive: boolean; + progressive?: boolean; quality: number; size: number; }; diff --git a/server/src/controllers/system-config.controller.spec.ts b/server/src/controllers/system-config.controller.spec.ts index 48b8c1bcf..bbd1241dc 100644 --- a/server/src/controllers/system-config.controller.spec.ts +++ b/server/src/controllers/system-config.controller.spec.ts @@ -70,5 +70,33 @@ describe(SystemConfigController.name, () => { expect(body).toEqual(errorDto.badRequest(['nightlyTasks.databaseCleanup must be a boolean value'])); }); }); + + describe('image', () => { + it('should accept config without optional progressive property', async () => { + const config = _.cloneDeep(defaults); + delete config.image.thumbnail.progressive; + delete config.image.preview.progressive; + delete config.image.fullsize.progressive; + const { status } = await request(ctx.getHttpServer()).put('/system-config').send(config); + expect(status).toBe(200); + }); + + it('should accept config with progressive set to true', async () => { + const config = _.cloneDeep(defaults); + config.image.thumbnail.progressive = true; + config.image.preview.progressive = true; + config.image.fullsize.progressive = true; + const { status } = await request(ctx.getHttpServer()).put('/system-config').send(config); + expect(status).toBe(200); + }); + + it('should reject invalid progressive value', async () => { + const config = _.cloneDeep(defaults); + (config.image.thumbnail.progressive as any) = 'invalid'; + const { status, body } = await request(ctx.getHttpServer()).put('/system-config').send(config); + expect(status).toBe(400); + expect(body).toEqual(errorDto.badRequest(['image.thumbnail.progressive must be a boolean value'])); + }); + }); }); }); diff --git a/server/src/dtos/system-config.dto.ts b/server/src/dtos/system-config.dto.ts index 4301d7193..b0d5a0646 100644 --- a/server/src/dtos/system-config.dto.ts +++ b/server/src/dtos/system-config.dto.ts @@ -586,8 +586,8 @@ class SystemConfigGeneratedImageDto { @ApiProperty({ type: 'integer' }) size!: number; - @ValidateBoolean() - progressive!: boolean; + @ValidateBoolean({ optional: true, default: false }) + progressive?: boolean; } class SystemConfigGeneratedFullsizeImageDto { @@ -604,8 +604,8 @@ class SystemConfigGeneratedFullsizeImageDto { @ApiProperty({ type: 'integer' }) quality!: number; - @ValidateBoolean() - progressive!: boolean; + @ValidateBoolean({ optional: true, default: false }) + progressive?: boolean; } export class SystemConfigImageDto { diff --git a/server/src/types.ts b/server/src/types.ts index 9f8c8011e..f851ebd99 100644 --- a/server/src/types.ts +++ b/server/src/types.ts @@ -36,14 +36,14 @@ export type FullsizeImageOptions = { format: ImageFormat; quality: number; enabled: boolean; - progressive: boolean; + progressive?: boolean; }; export type ImageOptions = { format: ImageFormat; quality: number; size: number; - progressive: boolean; + progressive?: boolean; }; export type RawImageInfo = {