Files
NianAIGC/lib/server/public-api-assets.ts
2026-07-03 11:25:25 +08:00

45 lines
1.6 KiB
TypeScript

import { getAsset, listAssets, listGenerationJobsFiltered } from "@/lib/server/data-store";
import { publicApiOwnerId } from "@/lib/server/public-api-auth";
import type { Asset, GenerationJob } from "@/lib/types";
const JOB_LOOKUP_LIMIT = 200;
export async function listPublicApiAssets(clientId: string): Promise<Asset[]> {
const ownerId = publicApiOwnerId(clientId);
const [assets, jobs] = await Promise.all([
listAssets(ownerId),
listGenerationJobsFiltered({
ownerId,
externalClientId: clientId,
limit: JOB_LOOKUP_LIMIT
})
]);
const accessibleIds = assetIdsFromJobs(jobs);
return assets.filter((asset) => canAccessAsset(clientId, asset, accessibleIds));
}
export async function getPublicApiAsset(clientId: string, assetId: string): Promise<Asset | null> {
const ownerId = publicApiOwnerId(clientId);
const asset = await getAsset(assetId);
if (!asset || asset.ownerId !== ownerId) return null;
if (asset.tags.includes(apiClientTag(clientId))) return asset;
const jobs = await listGenerationJobsFiltered({
ownerId,
externalClientId: clientId,
limit: JOB_LOOKUP_LIMIT
});
return assetIdsFromJobs(jobs).has(asset.id) ? asset : null;
}
function canAccessAsset(clientId: string, asset: Asset, accessibleIds: Set<string>): boolean {
return asset.tags.includes(apiClientTag(clientId)) || accessibleIds.has(asset.id);
}
function assetIdsFromJobs(jobs: GenerationJob[]): Set<string> {
return new Set(jobs.flatMap((job) => [...job.inputAssetIds, ...job.outputAssetIds]));
}
function apiClientTag(clientId: string): string {
return `api-client:${clientId}`;
}