Skip to content

Plugin API: resolve media asset ids to public URLs #224

Description

@seltzdesign

Problem

Plugin server entrypoints can read content via api.cms.content.table(slug).list() and getPublishedSnapshot(), but media-typed cells (e.g. featuredMedia) come back as bare media asset ids. There is no way for a plugin to turn an id into its public URL:

  • api.cms.media.* only covers storage adapters / URL transformers / variant delegates — no read/resolve.
  • content.list() and getPublishedSnapshot() return raw cells (ids, not paths).
  • The public path (/uploads/<storage_path>) is not derivable from the id, and there is no serve-by-id route.

The built-in data.rows loop source resolves featuredMediaPath via internal SQL (resolveMediaIdsToPaths), but a sandboxed plugin loop source cannot run SQL — so a plugin-provided source can return titles/links but not thumbnails.

Concretely this blocks a fairly common plugin: a loop source that filters rows by a field/tag value (the built-in data.rows only filters by tableId) and renders an image grid.

Proposed solution

Add a read-only batch resolver to the plugin server API:

api.cms.media.resolve(ids: string[]):
  Promise<Record<string, { url: string; width: number | null; height: number | null }>>
  • Absent/deleted ids omitted from the result.
  • Gated by a light read permission (or the existing content-read grant).
  • Can reuse the exported resolveMediaIdsToPaths(db, ids) in src/core/loops/sources/dataRows.ts, wired through the existing plugin RPC dispatch (server/plugins/host/handlers/media.ts, server/plugins/protocol/schemas/media.ts, apiDispatch.ts).

Alternative shape: resolve media-typed cells directly in content.list() / getPublishedSnapshot() results (a resolvedMedia: Record<fieldId, { url, width, height }> map per entry).

Happy to send a PR for whichever shape you prefer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions