--- title: 存储 Adapter description: 将查询、上传、变更、URL 解析和分页连接到产品基础设施。 order: 20 toc: - id: implement-the-contract title: 实现完整契约 - id: separate-display-and-reference-urls title: 区分展示与引用 URL - id: preserve-query-semantics title: 保持查询语义 --- ## 实现完整契约 {#implement-the-contract} `MediaAdapter` 是这个包完整的持久化边界。通过产品的存储服务实现资源查询、目录操作、上传、更新和删除。 ```ts import type { MediaAdapter } from "@workspace/media" export const mediaAdapter: MediaAdapter = { listAssets: (query) => api.media.list(query), listFolders: () => api.media.listFolders(), upload: (input) => api.media.upload(input), createFolder: (input) => api.media.createFolder(input), updateFolder: (input) => api.media.updateFolder(input), deleteFolder: (id) => api.media.deleteFolder(id), moveAsset: (id, folderId) => api.media.move(id, folderId), renameAsset: (id, name) => api.media.rename(id, name), updateFavorite: (id, favorite) => api.media.favorite(id, favorite), deleteAsset: (id) => api.media.delete(id), } ``` ## 区分展示与引用 URL {#separate-display-and-reference-urls} 使用 `resolveUrl` 返回渲染时需要的短期签名 URL 或图片转换地址。使用 `resolveReference` 返回选择器写入其他文档的值。未提供 `resolveReference` 时,图片会使用 `defaultMediaReference`,在 URL 中保留固有尺寸。 ## 保持查询语义 {#preserve-query-semantics} 将 `MediaAssetQuery` 当作不可变请求。在分页前依次应用 `allowedKinds`、`filter`、`folder` 和 `keyword`,然后根据筛选后的结果返回 `hasNextPage`。这样可以保持桌面端与移动端筛选行为一致。