From 53fe26593c1e4d2ae410e816077484909b35b3c3 Mon Sep 17 00:00:00 2001 From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Date: Thu, 18 Jun 2026 15:30:34 +0200 Subject: [PATCH] fix: asset type filter (#29190) --- packages/plugin-core/manifest.json | 16 ++++++------ packages/plugin-core/src/index.d.ts | 1 + packages/plugin-core/src/index.ts | 8 +++++- .../workflow/workflow-core-plugin.spec.ts | 26 ++++++++++++++++++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/packages/plugin-core/manifest.json b/packages/plugin-core/manifest.json index db6ab203bf..0ca98a83bc 100644 --- a/packages/plugin-core/manifest.json +++ b/packages/plugin-core/manifest.json @@ -184,22 +184,22 @@ "uiHints": ["Filter"] }, { - "name": "filterFileType", - "title": "Filter by file type", - "description": "Filter assets by file type", + "name": "assetTypeFilter", + "title": "Filter by asset type", + "description": "Filter assets by type", "types": ["AssetV1"], "schema": { "type": "object", "properties": { - "fileTypes": { - "title": "File types", - "description": "Allowed file types", + "allowedTypes": { + "title": "Asset types", + "description": "Allowed asset types", "type": "string", "array": true, - "enum": ["image", "video"] + "enum": ["IMAGE", "VIDEO", "AUDIO", "OTHER"] } }, - "required": ["fileTypes"] + "required": ["types"] }, "uiHints": ["Filter"] }, diff --git a/packages/plugin-core/src/index.d.ts b/packages/plugin-core/src/index.d.ts index 2ce414e84f..107bcc7aa0 100644 --- a/packages/plugin-core/src/index.d.ts +++ b/packages/plugin-core/src/index.d.ts @@ -14,6 +14,7 @@ declare module 'main' { export function assetFileFilter(): I32; export function assetMissingTimeZoneFilter(): I32; export function assetLocationFilter(): I32; + export function assetTypeFilter(): I32; // updates export function assetFavorite(): I32; diff --git a/packages/plugin-core/src/index.ts b/packages/plugin-core/src/index.ts index e67434bb54..fa956b8cec 100644 --- a/packages/plugin-core/src/index.ts +++ b/packages/plugin-core/src/index.ts @@ -1,5 +1,5 @@ import { wrapper } from '@immich/plugin-sdk'; -import { AssetVisibility, WorkflowType } from '@immich/sdk'; +import { AssetTypeEnum, AssetVisibility, WorkflowType } from '@immich/sdk'; type AssetFileFilterConfig = { pattern: string; @@ -95,6 +95,12 @@ export const assetLocationFilter = () => { }); }; +export const assetTypeFilter = () => { + return wrapper(({ config, data }) => { + return { workflow: { continue: config.allowedTypes.includes(data.asset.type) } }; + }); +}; + export const assetFavorite = () => { return wrapper(({ config, data }) => { const target = config.inverse ? false : true; diff --git a/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts b/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts index 7b1859e4c3..02556f66aa 100644 --- a/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts +++ b/server/test/medium/specs/workflow/workflow-core-plugin.spec.ts @@ -2,7 +2,7 @@ import { WorkflowStepConfig, WorkflowTrigger } from '@immich/plugin-sdk'; import { Kysely } from 'kysely'; import { readFileSync } from 'node:fs'; import { PluginManifestDto } from 'src/dtos/plugin-manifest.dto'; -import { AssetVisibility, LogLevel } from 'src/enum'; +import { AssetType, AssetVisibility, LogLevel } from 'src/enum'; import { AccessRepository } from 'src/repositories/access.repository'; import { AlbumRepository } from 'src/repositories/album.repository'; import { AssetRepository } from 'src/repositories/asset.repository'; @@ -403,4 +403,28 @@ describe('core plugin', () => { await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ isFavorite: true }); }); }); + + describe('assetTypeFilter', () => { + it('should favorite asset if it is a video', async () => { + const { user } = await ctx.newUser(); + const { asset } = await ctx.newAsset({ ownerId: user.id, type: AssetType.Video }); + + const workflow = await createWorkflow({ + ownerId: user.id, + trigger: WorkflowTrigger.AssetCreate, + steps: [ + { + method: 'immich-plugin-core#assetTypeFilter', + config: { allowedTypes: ['VIDEO'] }, + }, + { + method: 'immich-plugin-core#assetFavorite', + }, + ], + }); + + await expect(ctx.sut.handleAssetTrigger({ workflowId: workflow.id, assetId: asset.id })).resolves.toBeUndefined(); + await expect(ctx.get(AssetRepository).getById(asset.id)).resolves.toMatchObject({ isFavorite: true }); + }); + }); });