68 lines
1.8 KiB
TypeScript
68 lines
1.8 KiB
TypeScript
import { z } from 'zod';
|
||
|
||
const checksum = z
|
||
.string()
|
||
.regex(/^[a-f0-9]{64}$/, '必须是 SHA-256 十六进制摘要');
|
||
export const createMediaUploadIntentRequestSchema = z
|
||
.object({
|
||
purpose: z.literal('watermark_image'),
|
||
filename: z.string().trim().min(1).max(255),
|
||
content_type: z.enum(['image/png', 'image/jpeg', 'image/webp']),
|
||
byte_size: z
|
||
.number()
|
||
.int()
|
||
.min(1)
|
||
.max(5 * 1024 * 1024),
|
||
checksum_sha256: checksum,
|
||
})
|
||
.strict();
|
||
export const completeMediaUploadIntentRequestSchema = z
|
||
.object({
|
||
checksum_sha256: checksum,
|
||
})
|
||
.strict();
|
||
export const createMediaAccessUrlRequestSchema = z
|
||
.object({
|
||
purpose: z.literal('preview'),
|
||
})
|
||
.strict();
|
||
|
||
export type CreateMediaUploadIntentRequest = z.infer<
|
||
typeof createMediaUploadIntentRequestSchema
|
||
>;
|
||
export type CompleteMediaUploadIntentRequest = z.infer<
|
||
typeof completeMediaUploadIntentRequestSchema
|
||
>;
|
||
|
||
// ── 只读响应类型(由前端 AI 按 docs/api/watermarks-and-assets.md §1 补充,后端请复核) ──
|
||
|
||
/** 预签名直传端点:前端必须按返回的 method/url/headers 原样上传 */
|
||
export type MediaUploadEndpoint = {
|
||
method: string;
|
||
url: string;
|
||
headers: Record<string, string>;
|
||
};
|
||
|
||
/** POST /api/media/upload-intents 响应 */
|
||
export type MediaUploadIntent = {
|
||
upload_id: string;
|
||
expires_at: string;
|
||
upload: MediaUploadEndpoint;
|
||
};
|
||
|
||
/** 校验通过后创建/复用的素材 */
|
||
export type MediaAsset = {
|
||
id: string;
|
||
content_type: string;
|
||
byte_size: number;
|
||
width_px: number | null;
|
||
height_px: number | null;
|
||
created_at: string;
|
||
};
|
||
|
||
/** POST /api/media-assets/{asset_id}/access-urls 响应(短时预览 URL) */
|
||
export type MediaAccessUrl = {
|
||
url: string;
|
||
expires_at: string;
|
||
};
|