import type { SetOptional } from 'type-fest'; import type { StorageHash } from '@cloudpss/object-storage'; import type { ResourceRevisionOf } from './known-resource-types.js'; import { isResourceId, type ResourceId } from './resource-id.js'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import type { ResourcePermissions, ResourcePermission } from './permission.js'; import type { Page } from './page.js'; import type { ResourceTag } from './tag.js'; /** * 表示一个资源 */ export interface Resource = ResourceRevisionOf> { /** RID,空表示尚未保存过 {@link ResourcePermission.READ_META} */ rid: ResourceId; /** 名称 {@link ResourcePermission.READ_META}/{@link ResourcePermission.WRITE_META} */ name: string; /** 描述 {@link ResourcePermission.READ_META}/{@link ResourcePermission.WRITE_META} */ description: string; /** 资源的标签 {@link ResourcePermission.READ_META}/{@link ResourcePermission.WRITE_META} */ tags: ResourceTag[]; /** 资源的关键词 {@link ResourcePermission.READ_META}/{@link ResourcePermission.WRITE_META} */ keywords: string[]; /** 资源权限 {@link ResourcePermission.READ_META}/{@link ResourcePermission.ADMIN} */ permissions: ResourcePermissions; /** 资源的数据 {@link ResourcePermission.READ}/{@link ResourcePermission.WRITE} */ revision: TRevision; /** 资源的附加存储 {@link ResourcePermission.READ}/{@link ResourcePermission.WRITE} */ storage?: StorageHash[]; /** 资源关联的发布页面 {@link ResourcePermission.READ_META}/{@link ResourcePermission.PUBLISH} */ pages?: Page[]; } /** 检查是否为资源 */ export function isResource< AllowUnsaved extends boolean = false, T extends string = string, TRevision extends ResourceRevisionOf = ResourceRevisionOf, >( value: unknown, allowUnsaved?: AllowUnsaved, ): value is AllowUnsaved extends true ? SetOptional, 'rid'> : Resource { if (value == null || typeof value != 'object') return false; const res = value as Resource; if (typeof res.name != 'string') return false; if (typeof res.description != 'string') return false; if (!Array.isArray(res.tags) || !res.tags.every((v) => typeof v == 'string')) return false; if (!Array.isArray(res.keywords) || !res.keywords.every((v) => typeof v == 'string')) return false; if (res.revision == null || typeof res.revision != 'object') return false; if (allowUnsaved && !res.rid) return true; return isResourceId(res.rid); } /** 检查资源是否未保存 */ export function isResourceUnsaved(value: Resource): boolean { return !value.rid; }