mirror of
https://github.com/immich-app/immich.git
synced 2026-06-05 14:25:16 -04:00
feat: workflows & plugins (#26727)
feat: plugins chore: better types feat: plugins
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { WorkflowTrigger, WorkflowType } from 'src/enum';
|
||||
import { isMethodCompatible } from 'src/utils/workflow';
|
||||
|
||||
const tests: Array<{ trigger: WorkflowTrigger; types: WorkflowType[]; expected: boolean }> = [
|
||||
{
|
||||
trigger: WorkflowTrigger.AssetCreate,
|
||||
types: [WorkflowType.AssetV1],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
trigger: WorkflowTrigger.AssetCreate,
|
||||
types: [WorkflowType.AssetPersonV1],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
trigger: WorkflowTrigger.PersonRecognized,
|
||||
types: [WorkflowType.AssetPersonV1],
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
trigger: WorkflowTrigger.PersonRecognized,
|
||||
types: [WorkflowType.AssetV1],
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
trigger: WorkflowTrigger.PersonRecognized,
|
||||
types: [WorkflowType.AssetV1, WorkflowType.AssetPersonV1],
|
||||
expected: true,
|
||||
},
|
||||
];
|
||||
|
||||
describe(isMethodCompatible.name, () => {
|
||||
it.each(tests)('should return $expected for trigger $trigger with types $types', ({ trigger, types, expected }) => {
|
||||
expect(isMethodCompatible({ types }, trigger)).toBe(expected);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
import { WorkflowTrigger, WorkflowType } from 'src/enum';
|
||||
import { PluginMethodSearchResponse } from 'src/repositories/plugin.repository';
|
||||
|
||||
export const triggerMap: Record<WorkflowTrigger, WorkflowType[]> = {
|
||||
[WorkflowTrigger.AssetCreate]: [WorkflowType.AssetV1],
|
||||
[WorkflowTrigger.PersonRecognized]: [WorkflowType.AssetPersonV1],
|
||||
};
|
||||
|
||||
export const getWorkflowTriggers = () =>
|
||||
Object.entries(triggerMap).map(([trigger, types]) => ({ trigger: trigger as WorkflowTrigger, types }));
|
||||
|
||||
/** some types extend other types and have implied compatibility */
|
||||
const inferredMap: Record<WorkflowType, WorkflowType[]> = {
|
||||
[WorkflowType.AssetV1]: [],
|
||||
[WorkflowType.AssetPersonV1]: [WorkflowType.AssetV1],
|
||||
};
|
||||
|
||||
const withImpliedItems = (type: WorkflowType): WorkflowType[] => {
|
||||
const childTypes = inferredMap[type];
|
||||
const results = [type];
|
||||
for (const child of childTypes) {
|
||||
results.push(...withImpliedItems(child));
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
export const isMethodCompatible = (pluginMethod: { types: WorkflowType[] }, trigger: WorkflowTrigger) => {
|
||||
const validTypes = triggerMap[trigger];
|
||||
const pluginCompatibility = pluginMethod.types.map((type) => withImpliedItems(type));
|
||||
for (const requested of validTypes) {
|
||||
for (const pluginCompatibilityGroup of pluginCompatibility) {
|
||||
if (pluginCompatibilityGroup.includes(requested)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const resolveMethod = (methods: PluginMethodSearchResponse[], method: string) => {
|
||||
const result = parseMethodString(method);
|
||||
if (!result) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { pluginName, methodName } = result;
|
||||
|
||||
return methods.find((method) => method.pluginName === pluginName && method.name === methodName);
|
||||
};
|
||||
|
||||
export const asMethodString = (method: { pluginName: string; methodName: string }) => {
|
||||
return `${method.pluginName}#${method.methodName}`;
|
||||
};
|
||||
|
||||
const METHOD_REGEX = /^(?<name>[^@#\s]+)(?:@(?<version>[^#\s]*))?#(?<method>[^@#\s]+)$/;
|
||||
export const parseMethodString = (method: string) => {
|
||||
const matches = METHOD_REGEX.exec(method);
|
||||
if (!matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pluginName = matches.groups?.name;
|
||||
const version = matches.groups?.version;
|
||||
const methodName = matches.groups?.method;
|
||||
return { pluginName, version, methodName };
|
||||
};
|
||||
Reference in New Issue
Block a user