wip: call host function from plugin

This commit is contained in:
Alex Tran
2026-01-20 22:10:21 +00:00
parent 92fae68253
commit bbb2f01aa7
5 changed files with 74 additions and 28 deletions
@@ -7,6 +7,7 @@ import { AlbumRepository } from 'src/repositories/album.repository';
import { AssetRepository } from 'src/repositories/asset.repository';
import { CryptoRepository } from 'src/repositories/crypto.repository';
import { LoggingRepository } from 'src/repositories/logging.repository';
import { PersonRepository } from 'src/repositories/person.repository';
import { AssetTable } from 'src/schema/tables/asset.table';
import { requireAccess } from 'src/utils/access';
@@ -20,6 +21,7 @@ export class PluginHostFunctions {
private albumRepository: AlbumRepository,
private accessRepository: AccessRepository,
private cryptoRepository: CryptoRepository,
private personRepository: PersonRepository,
private logger: LoggingRepository,
private pluginJwtSecret: string,
) {}
@@ -33,6 +35,7 @@ export class PluginHostFunctions {
'extism:host/user': {
updateAsset: (cp: CurrentPlugin, offs: bigint) => this.handleUpdateAsset(cp, offs),
addAssetToAlbum: (cp: CurrentPlugin, offs: bigint) => this.handleAddAssetToAlbum(cp, offs),
getFacesForAsset: (cp: CurrentPlugin, offs: bigint) => this.handleGetFacesForAsset(cp, offs),
},
};
}
@@ -117,4 +120,28 @@ export class PluginHostFunctions {
await this.albumRepository.addAssetIds(albumId, [assetId]);
return 0;
}
/**
* Host function wrapper for getFacesForAsset.
* Reads the input from the plugin, parses it, and returns faces data.
*/
private async handleGetFacesForAsset(cp: CurrentPlugin, offs: bigint) {
const input = JSON.parse(cp.read(offs)!.text());
const result = await this.getFacesForAsset(input);
return cp.store(JSON.stringify(result));
}
async getFacesForAsset(input: { authToken: string; assetId: string }) {
const { authToken, assetId } = input;
const auth = this.validateToken(authToken);
await requireAccess(this.accessRepository, {
auth: { user: { id: auth.userId } } as any,
permission: Permission.AssetRead,
ids: [assetId],
});
return this.personRepository.getFaces(assetId);
}
}
+8 -12
View File
@@ -17,7 +17,7 @@ import { IWorkflowJob, JobItem, JobOf, WorkflowData } from 'src/types';
interface WorkflowContext {
authToken: string;
asset: Asset;
faces?: { faceId: string; personId: string | null }[];
personId?: string;
}
interface PluginInput<T = unknown> {
@@ -25,7 +25,7 @@ interface PluginInput<T = unknown> {
config: T;
data: {
asset: Asset;
faces?: { faceId: string; personId: string | null }[];
personId?: string;
};
}
@@ -46,6 +46,7 @@ export class PluginService extends BaseService {
this.albumRepository,
this.accessRepository,
this.cryptoRepository,
this.personRepository,
this.logger,
this.pluginJwtSecret,
);
@@ -231,7 +232,7 @@ export class PluginService extends BaseService {
const authToken = this.cryptoRepository.signJwt({ userId: data.userId }, this.pluginJwtSecret);
const context = {
const context: WorkflowContext = {
authToken,
asset,
};
@@ -257,16 +258,10 @@ export class PluginService extends BaseService {
const authToken = this.cryptoRepository.signJwt({ userId: data.userId }, this.pluginJwtSecret);
const faces = await this.personRepository.getFaces(data.assetId);
const facePayload = faces.map((face) => ({
faceId: face.id,
personId: face.personId,
}));
const context = {
const context: WorkflowContext = {
authToken,
asset,
faces: facePayload,
personId: data.personId,
};
const filtersPassed = await this.executeFilters(workflowFilters, context);
@@ -309,7 +304,7 @@ export class PluginService extends BaseService {
config: workflowFilter.filterConfig,
data: {
asset: context.asset,
faces: context.faces,
personId: context.personId,
},
};
@@ -352,6 +347,7 @@ export class PluginService extends BaseService {
config: workflowAction.actionConfig,
data: {
asset: context.asset,
personId: context.personId,
},
};