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