Add Zod schemas and types for CurseForge and Modrinth APIs
This commit is contained in:
parent
307b0cd4d4
commit
8071c2f8a7
199
src/types/curseforge/files.ts
Normal file
199
src/types/curseforge/files.ts
Normal file
@ -0,0 +1,199 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// region FileStatus — 文件状态
|
||||
export const FileStatusSchema = z.union([
|
||||
z.literal(1), // Processing
|
||||
z.literal(4), // Approved
|
||||
z.literal(10), // Released
|
||||
z.literal(12), // Deprecated
|
||||
]);
|
||||
export type FileStatus = z.infer<typeof FileStatusSchema>;
|
||||
// endregion
|
||||
|
||||
// region FileReleaseType — 文件的发布类型(数值枚举)
|
||||
export const FileReleaseTypeSchema = z.union([
|
||||
z.literal(1), // Release
|
||||
z.literal(2), // Beta
|
||||
z.literal(3), // Alpha
|
||||
]);
|
||||
export type FileReleaseType = z.infer<typeof FileReleaseTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region HashAlgo — 哈希算法
|
||||
export const HashAlgoSchema = z.union([
|
||||
z.literal(1), // Sha1
|
||||
z.literal(2), // Md5
|
||||
]);
|
||||
export type HashAlgo = z.infer<typeof HashAlgoSchema>;
|
||||
// endregion
|
||||
|
||||
// region FileRelationType — 依赖关系类型(数值枚举)
|
||||
export const FileRelationTypeSchema = z.union([
|
||||
z.literal(1), // EmbeddedLibrary
|
||||
z.literal(2), // OptionalDependency
|
||||
z.literal(3), // RequiredDependency
|
||||
z.literal(4), // Tool
|
||||
z.literal(5), // Incompatible
|
||||
z.literal(6), // Include
|
||||
]);
|
||||
export type FileRelationType = z.infer<typeof FileRelationTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region ModLoaderType — Mod Loader 类型(查询参数用)
|
||||
export const ModLoaderTypeSchema = z.union([
|
||||
z.literal(0), // Any
|
||||
z.literal(1), // Forge
|
||||
z.literal(2), // Cauldron
|
||||
z.literal(3), // LiteLoader
|
||||
z.literal(4), // Fabric
|
||||
z.literal(5), // Quilt
|
||||
z.literal(6), // NeoForge
|
||||
]);
|
||||
export type ModLoaderType = z.infer<typeof ModLoaderTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region FileHash — 文件哈希
|
||||
export const FileHashSchema = z.object({
|
||||
/** 哈希值 */
|
||||
value: z.string(),
|
||||
/** 哈希算法 */
|
||||
algo: HashAlgoSchema,
|
||||
});
|
||||
export type FileHash = z.infer<typeof FileHashSchema>;
|
||||
// endregion
|
||||
|
||||
// region SortableGameVersion — 排序用版本信息
|
||||
export const SortableGameVersionSchema = z.object({
|
||||
/** 游戏版本名称,如 "1.21.5" */
|
||||
gameVersionName: z.string(),
|
||||
/** 补齐前缀的游戏版本号,用于排序,如 "0000000001.0000000021.0000000005" */
|
||||
gameVersionPadded: z.string(),
|
||||
/** 游戏版本,如 "1.21.5" */
|
||||
gameVersion: z.string(),
|
||||
/** 游戏版本发布日期(ISO-8601) */
|
||||
gameVersionReleaseDate: z.string(),
|
||||
/** 版本类型 ID,对应 Game Version Types API 中的 id */
|
||||
gameVersionTypeId: z.number().int(),
|
||||
});
|
||||
export type SortableGameVersion = z.infer<typeof SortableGameVersionSchema>;
|
||||
// endregion
|
||||
|
||||
// region FileDependency — 文件依赖
|
||||
export const FileDependencySchema = z.object({
|
||||
/** 依赖的项目 ID */
|
||||
modId: z.number().int(),
|
||||
/** 关系类型 */
|
||||
relationType: FileRelationTypeSchema,
|
||||
});
|
||||
export type FileDependency = z.infer<typeof FileDependencySchema>;
|
||||
// endregion
|
||||
|
||||
// region FileModule — 文件模块
|
||||
export const FileModuleSchema = z.object({
|
||||
/** 模块名称 */
|
||||
name: z.string(),
|
||||
/** 模块指纹 */
|
||||
fingerprint: z.number().int(),
|
||||
});
|
||||
export type FileModule = z.infer<typeof FileModuleSchema>;
|
||||
// endregion
|
||||
|
||||
// region CurseForgeFile — CurseForge 文件完整对象
|
||||
export const CurseForgeFileSchema = z.object({
|
||||
/** 文件 ID */
|
||||
id: z.number().int(),
|
||||
/** 游戏 ID */
|
||||
gameId: z.number().int(),
|
||||
/** 所属项目 ID */
|
||||
modId: z.number().int(),
|
||||
/** 是否可下载 */
|
||||
isAvailable: z.boolean(),
|
||||
/** 显示名称 */
|
||||
displayName: z.string(),
|
||||
/** 文件名 */
|
||||
fileName: z.string(),
|
||||
/** 发布类型 */
|
||||
releaseType: FileReleaseTypeSchema,
|
||||
/** 文件状态 */
|
||||
fileStatus: FileStatusSchema,
|
||||
/** 文件哈希列表 */
|
||||
hashes: z.array(FileHashSchema),
|
||||
/** 文件时间戳(ISO-8601) */
|
||||
fileDate: z.string(),
|
||||
/** 文件大小(字节) */
|
||||
fileLength: z.number().int(),
|
||||
/** 下载次数 */
|
||||
downloadCount: z.number().int(),
|
||||
/** 磁盘占用(字节) */
|
||||
fileSizeOnDisk: z.number().int(),
|
||||
/** 下载地址 */
|
||||
downloadUrl: z.string(),
|
||||
/** 关联的游戏版本(字符串列表) */
|
||||
gameVersions: z.array(z.string()),
|
||||
/** 排序用版本信息 */
|
||||
sortableGameVersions: z.array(SortableGameVersionSchema),
|
||||
/** 依赖关系列表 */
|
||||
dependencies: z.array(FileDependencySchema),
|
||||
/** 是否作为替代文件暴露 */
|
||||
exposeAsAlternative: z.boolean(),
|
||||
/** 父项目文件 ID,无则为 null */
|
||||
parentProjectFileId: z.number().int().nullable(),
|
||||
/** 替代文件 ID,无则为 null */
|
||||
alternateFileId: z.number().int().nullable(),
|
||||
/** 是否为服务端整合包 */
|
||||
isServerPack: z.boolean(),
|
||||
/** 服务端整合包文件 ID,无则为 null */
|
||||
serverPackFileId: z.number().int().nullable(),
|
||||
/** 是否为抢先体验内容 */
|
||||
isEarlyAccessContent: z.boolean(),
|
||||
/** 抢先体验截止日期(ISO-8601),无则为 null */
|
||||
earlyAccessEndDate: z.string().nullable(),
|
||||
/** 文件指纹 */
|
||||
fileFingerprint: z.number().int(),
|
||||
/** 文件模块列表 */
|
||||
modules: z.array(FileModuleSchema),
|
||||
});
|
||||
export type CurseForgeFile = z.infer<typeof CurseForgeFileSchema>;
|
||||
// endregion
|
||||
|
||||
// region Pagination — 分页信息
|
||||
export const PaginationSchema = z.object({
|
||||
/** 本次返回的起始索引 */
|
||||
index: z.number().int(),
|
||||
/** 请求的页大小 */
|
||||
pageSize: z.number().int(),
|
||||
/** 本次实际返回数量 */
|
||||
resultCount: z.number().int(),
|
||||
/** 总文件数 */
|
||||
totalCount: z.number().int(),
|
||||
});
|
||||
export type Pagination = z.infer<typeof PaginationSchema>;
|
||||
// endregion
|
||||
|
||||
// region GetModFilesParams — GET /v1/mods/{modId}/files 查询参数
|
||||
export const GetModFilesParamsSchema = z.object({
|
||||
/** 项目 ID(路径参数) */
|
||||
modId: z.number().int(),
|
||||
/** 按游戏版本过滤 */
|
||||
gameVersion: z.string().optional(),
|
||||
/** 按 Mod Loader 类型过滤 */
|
||||
modLoaderType: ModLoaderTypeSchema.optional(),
|
||||
/** 按 gameVersionTypeId 过滤 */
|
||||
gameVersionTypeId: z.number().int().optional(),
|
||||
/** 分页起始索引(从 0 开始) */
|
||||
index: z.number().int().optional(),
|
||||
/** 每页数量,默认/最大 50 */
|
||||
pageSize: z.number().int().optional(),
|
||||
});
|
||||
export type GetModFilesParams = z.infer<typeof GetModFilesParamsSchema>;
|
||||
// endregion
|
||||
|
||||
// region GetModFilesResponse — GET /v1/mods/{modId}/files 成功响应体
|
||||
export const GetModFilesResponseSchema = z.object({
|
||||
/** 文件列表 */
|
||||
data: z.array(CurseForgeFileSchema),
|
||||
/** 分页信息 */
|
||||
pagination: PaginationSchema,
|
||||
});
|
||||
export type GetModFilesResponse = z.infer<typeof GetModFilesResponseSchema>;
|
||||
// endregion
|
||||
29
src/types/curseforge/game.ts
Normal file
29
src/types/curseforge/game.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// region GameVersionType — GET /api/game/version-types 响应元素
|
||||
export const GameVersionTypeSchema = z.object({
|
||||
/** 版本类型 ID(即 gameVersionTypeID) */
|
||||
id: z.number().int(),
|
||||
/** 类型名称,如 "Modloader"、"Environment" */
|
||||
name: z.string(),
|
||||
/** 类型标识 */
|
||||
slug: z.string(),
|
||||
});
|
||||
export type GameVersionType = z.infer<typeof GameVersionTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region GameVersion — GET /api/game/versions 响应元素
|
||||
export const GameVersionSchema = z.object({
|
||||
/** 版本 ID(用于上传时的 gameVersions 字段) */
|
||||
id: z.number().int(),
|
||||
/** 版本类型 ID,对应 GameVersionType.id */
|
||||
gameVersionTypeID: z.number().int(),
|
||||
/** 版本名称,如 "1.21.5" */
|
||||
name: z.string(),
|
||||
/** 版本标识,如 "1-21-5" */
|
||||
slug: z.string(),
|
||||
/** API 版本号,无则为 null */
|
||||
apiVersion: z.number().int().nullable(),
|
||||
});
|
||||
export type GameVersion = z.infer<typeof GameVersionSchema>;
|
||||
// endregion
|
||||
54
src/types/curseforge/index.ts
Normal file
54
src/types/curseforge/index.ts
Normal file
@ -0,0 +1,54 @@
|
||||
export {
|
||||
FileStatusSchema,
|
||||
FileReleaseTypeSchema,
|
||||
HashAlgoSchema,
|
||||
FileRelationTypeSchema,
|
||||
ModLoaderTypeSchema,
|
||||
FileHashSchema,
|
||||
SortableGameVersionSchema,
|
||||
FileDependencySchema,
|
||||
FileModuleSchema,
|
||||
CurseForgeFileSchema,
|
||||
PaginationSchema,
|
||||
GetModFilesParamsSchema,
|
||||
GetModFilesResponseSchema,
|
||||
type FileStatus,
|
||||
type FileReleaseType,
|
||||
type HashAlgo,
|
||||
type FileRelationType,
|
||||
type ModLoaderType,
|
||||
type FileHash,
|
||||
type SortableGameVersion,
|
||||
type FileDependency,
|
||||
type FileModule,
|
||||
type CurseForgeFile,
|
||||
type Pagination,
|
||||
type GetModFilesParams,
|
||||
type GetModFilesResponse,
|
||||
} from "./files";
|
||||
|
||||
export {
|
||||
GameVersionTypeSchema,
|
||||
GameVersionSchema,
|
||||
type GameVersionType,
|
||||
type GameVersion,
|
||||
} from "./game";
|
||||
|
||||
export {
|
||||
UploadReleaseTypeSchema,
|
||||
ChangelogTypeSchema,
|
||||
UploadRelationTypeSchema,
|
||||
RelationProjectSchema,
|
||||
RelationsSchema,
|
||||
UploadMetadataSchema,
|
||||
UpdateMetadataSchema,
|
||||
UploadResponseSchema,
|
||||
type UploadReleaseType,
|
||||
type ChangelogType,
|
||||
type UploadRelationType,
|
||||
type RelationProject,
|
||||
type Relations,
|
||||
type UploadMetadata,
|
||||
type UpdateMetadata,
|
||||
type UploadResponse,
|
||||
} from "./upload";
|
||||
103
src/types/curseforge/upload.ts
Normal file
103
src/types/curseforge/upload.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// region UploadReleaseType — 上传时的发布类型(字符串枚举)
|
||||
export const UploadReleaseTypeSchema = z.enum([
|
||||
"alpha",
|
||||
"beta",
|
||||
"release",
|
||||
]);
|
||||
export type UploadReleaseType = z.infer<typeof UploadReleaseTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region ChangelogType — 更新日志格式
|
||||
export const ChangelogTypeSchema = z.enum([
|
||||
"text",
|
||||
"html",
|
||||
"markdown",
|
||||
]);
|
||||
export type ChangelogType = z.infer<typeof ChangelogTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region UploadRelationType — 上传时的依赖关系类型(字符串枚举)
|
||||
export const UploadRelationTypeSchema = z.enum([
|
||||
"embeddedLibrary",
|
||||
"incompatible",
|
||||
"optionalDependency",
|
||||
"requiredDependency",
|
||||
"tool",
|
||||
]);
|
||||
export type UploadRelationType = z.infer<typeof UploadRelationTypeSchema>;
|
||||
// endregion
|
||||
|
||||
// region RelationProject — 关联项目
|
||||
export const RelationProjectSchema = z.object({
|
||||
/** 关联项目的 slug */
|
||||
slug: z.string(),
|
||||
/** 关联项目的 ID(精确匹配),可选 */
|
||||
projectID: z.string().optional(),
|
||||
/** 关联类型 */
|
||||
type: UploadRelationTypeSchema,
|
||||
});
|
||||
export type RelationProject = z.infer<typeof RelationProjectSchema>;
|
||||
// endregion
|
||||
|
||||
// region Relations — 关联项目集合
|
||||
export const RelationsSchema = z.object({
|
||||
projects: z.array(RelationProjectSchema),
|
||||
});
|
||||
export type Relations = z.infer<typeof RelationsSchema>;
|
||||
// endregion
|
||||
|
||||
// region UploadMetadata — POST /api/projects/{projectId}/upload-file 的 metadata JSON
|
||||
export const UploadMetadataSchema = z.object({
|
||||
/** 更新日志内容,必填 */
|
||||
changelog: z.string(),
|
||||
/** 更新日志格式,默认 "text" */
|
||||
changelogType: ChangelogTypeSchema.optional(),
|
||||
/** 站点上显示的文件友好名称 */
|
||||
displayName: z.string().optional(),
|
||||
/** 父文件 ID */
|
||||
parentFileID: z.number().int().optional(),
|
||||
/**
|
||||
* 支持的 Game Version ID 列表(通过 Game Versions API 获取)。
|
||||
* 若提供 parentFileID 则不支持此字段。
|
||||
*/
|
||||
gameVersions: z.array(z.number().int()).optional(),
|
||||
/** 发布类型,必填 */
|
||||
releaseType: UploadReleaseTypeSchema,
|
||||
/** 若为 true,审核通过后不会立即发布,可手动选择发布时间 */
|
||||
isMarkedForManualRelease: z.boolean().optional(),
|
||||
/** 关联项目 */
|
||||
relations: RelationsSchema.optional(),
|
||||
});
|
||||
export type UploadMetadata = z.infer<typeof UploadMetadataSchema>;
|
||||
// endregion
|
||||
|
||||
// region UpdateMetadata — POST /api/projects/{projectId}/update-file 的 metadata JSON
|
||||
export const UpdateMetadataSchema = z.object({
|
||||
/** 要更新的文件 ID,必填 */
|
||||
fileID: z.number().int(),
|
||||
|
||||
/** 更新日志内容 */
|
||||
changelog: z.string().optional(),
|
||||
/** 更新日志格式 */
|
||||
changelogType: ChangelogTypeSchema.optional(),
|
||||
/** 站点上显示的文件友好名称 */
|
||||
displayName: z.string().optional(),
|
||||
/** 支持的 Game Version ID 列表 */
|
||||
gameVersions: z.array(z.number().int()).optional(),
|
||||
/** 发布类型 */
|
||||
releaseType: UploadReleaseTypeSchema.optional(),
|
||||
/** 关联项目 */
|
||||
relations: RelationsSchema.optional(),
|
||||
});
|
||||
export type UpdateMetadata = z.infer<typeof UpdateMetadataSchema>;
|
||||
// endregion
|
||||
|
||||
// region UploadResponse — 上传 / 更新文件的成功响应体
|
||||
export const UploadResponseSchema = z.object({
|
||||
/** 新建 / 被更新文件的 ID */
|
||||
id: z.number().int(),
|
||||
});
|
||||
export type UploadResponse = z.infer<typeof UploadResponseSchema>;
|
||||
// endregion
|
||||
3
src/types/index.ts
Normal file
3
src/types/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from "./modrinth";
|
||||
export * from "./curseforge";
|
||||
// export * from "./config"; // TODO
|
||||
49
src/types/modrinth/create-version.ts
Normal file
49
src/types/modrinth/create-version.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { z } from "zod";
|
||||
import { BaseVersionSchema, FileTypeEnumSchema } from "./version";
|
||||
|
||||
// region CreatableVersion — 创建版本请求中的 data JSON
|
||||
export const CreatableVersionSchema = BaseVersionSchema.extend({
|
||||
/** 目标项目的 ID(8 位 base62) */
|
||||
project_id: z.string().length(8),
|
||||
/** 所有承载文件的 multipart 字段名列表 */
|
||||
file_parts: z.array(z.string()),
|
||||
/** 主文件的 multipart 字段名;不提供时推断第一个文件为主文件 */
|
||||
primary_file: z.string().optional(),
|
||||
/** 目标环境 */
|
||||
environment: z
|
||||
.enum([
|
||||
"unknown",
|
||||
"client_only",
|
||||
"server_only",
|
||||
"dedicated_server_only",
|
||||
"client_and_server",
|
||||
"server_only_client_optional",
|
||||
"client_only_server_optional",
|
||||
"client_or_server_prefers_both",
|
||||
"client_or_server",
|
||||
"singleplayer_only",
|
||||
])
|
||||
.optional(),
|
||||
/** multipart 字段名 → 文件类型的映射,用于标记 sources-jar 等附属文件 */
|
||||
file_types: z.record(FileTypeEnumSchema).optional(),
|
||||
});
|
||||
export type CreatableVersion = z.infer<typeof CreatableVersionSchema>;
|
||||
// endregion
|
||||
|
||||
// region CreateVersionBody — multipart/form-data 请求的最外层包装
|
||||
export const CreateVersionBodySchema = z.object({
|
||||
/** JSON 字符串形式的 CreatableVersion 元数据 */
|
||||
data: CreatableVersionSchema,
|
||||
});
|
||||
export type CreateVersionBody = z.infer<typeof CreateVersionBodySchema>;
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* POST /version 的实际请求体为 multipart/form-data,结构如下:
|
||||
*
|
||||
* - `data`(文本字段):JSON 字符串 → 解析为 {@link CreatableVersion}
|
||||
* - 若干个文件字段:字段名需与 `file_parts` / `primary_file` / `file_types` 中的值一致
|
||||
*
|
||||
* 因此 Zod schema 仅校验 `data` 字段的结构。
|
||||
* 文件字段的校验(大小、格式等)需在运行时单独处理。
|
||||
*/
|
||||
31
src/types/modrinth/index.ts
Normal file
31
src/types/modrinth/index.ts
Normal file
@ -0,0 +1,31 @@
|
||||
export {
|
||||
LoaderTagSchema,
|
||||
GameVersionTagSchema,
|
||||
CategoryTagSchema,
|
||||
type LoaderTag,
|
||||
type GameVersionTag,
|
||||
type CategoryTag,
|
||||
type ProjectTypeTag,
|
||||
} from "./tags";
|
||||
|
||||
export {
|
||||
VersionDependencySchema,
|
||||
FileTypeEnumSchema,
|
||||
VersionFileHashesSchema,
|
||||
VersionFileSchema,
|
||||
BaseVersionSchema,
|
||||
VersionSchema,
|
||||
type VersionDependency,
|
||||
type FileTypeEnum,
|
||||
type VersionFileHashes,
|
||||
type VersionFile,
|
||||
type BaseVersion,
|
||||
type Version,
|
||||
} from "./version";
|
||||
|
||||
export {
|
||||
CreatableVersionSchema,
|
||||
CreateVersionBodySchema,
|
||||
type CreatableVersion,
|
||||
type CreateVersionBody,
|
||||
} from "./create-version";
|
||||
46
src/types/modrinth/tags.ts
Normal file
46
src/types/modrinth/tags.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// region /tag/loader — 加载器列表
|
||||
export const LoaderTagSchema = z.object({
|
||||
/** 加载器的 SVG 图标 */
|
||||
icon: z.string(),
|
||||
/** 加载器名称,如 "fabric"、"forge" */
|
||||
name: z.string(),
|
||||
/** 该加载器适用的项目类型列表 */
|
||||
supported_project_types: z.array(z.string()),
|
||||
});
|
||||
export type LoaderTag = z.infer<typeof LoaderTagSchema>;
|
||||
// endregion
|
||||
|
||||
// region /tag/game_version — 游戏版本列表
|
||||
export const GameVersionTagSchema = z.object({
|
||||
/** 游戏版本号,如 "1.18.1" */
|
||||
version: z.string(),
|
||||
/** 版本类型:release | snapshot | alpha | beta */
|
||||
version_type: z.enum(["release", "snapshot", "alpha", "beta"]),
|
||||
/** 版本发布日期(ISO-8601) */
|
||||
date: z.string().datetime(),
|
||||
/** 是否为主要版本,用于 Featured Versions 标记 */
|
||||
major: z.boolean(),
|
||||
});
|
||||
export type GameVersionTag = z.infer<typeof GameVersionTagSchema>;
|
||||
// endregion
|
||||
|
||||
// region /tag/category — 分类标签列表
|
||||
export const CategoryTagSchema = z.object({
|
||||
/** 分类的 SVG 图标 */
|
||||
icon: z.string(),
|
||||
/** 分类名称 */
|
||||
name: z.string(),
|
||||
/** 该分类适用的项目类型 */
|
||||
project_type: z.string(),
|
||||
/** 该分类所属的标题分组 */
|
||||
header: z.string(),
|
||||
});
|
||||
export type CategoryTag = z.infer<typeof CategoryTagSchema>;
|
||||
// endregion
|
||||
|
||||
// region /tag/project_type — 项目类型(纯字符串数组)
|
||||
/** GET /tag/project_type 的响应类型 */
|
||||
export type ProjectTypeTag = string[];
|
||||
// endregion
|
||||
100
src/types/modrinth/version.ts
Normal file
100
src/types/modrinth/version.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { z } from "zod";
|
||||
|
||||
// region VersionDependency — 依赖项
|
||||
export const VersionDependencySchema = z.object({
|
||||
/** 依赖的具体版本 ID;为 null 时匹配最新版 */
|
||||
version_id: z.string().nullable(),
|
||||
/** 依赖的项目 ID */
|
||||
project_id: z.string().nullable(),
|
||||
/** 依赖文件名,主要用于整合包中的外部依赖 */
|
||||
file_name: z.string().nullable(),
|
||||
/** 依赖类型 */
|
||||
dependency_type: z.enum(["required", "optional", "incompatible", "embedded"]),
|
||||
});
|
||||
export type VersionDependency = z.infer<typeof VersionDependencySchema>;
|
||||
// endregion
|
||||
|
||||
// region FileTypeEnum — 文件类型枚举
|
||||
export const FileTypeEnumSchema = z.enum([
|
||||
"required-resource-pack",
|
||||
"optional-resource-pack",
|
||||
"sources-jar",
|
||||
"dev-jar",
|
||||
"javadoc-jar",
|
||||
"unknown",
|
||||
"signature",
|
||||
]);
|
||||
export type FileTypeEnum = z.infer<typeof FileTypeEnumSchema>;
|
||||
// endregion
|
||||
|
||||
// region VersionFileHashes — 文件哈希
|
||||
export const VersionFileHashesSchema = z.object({
|
||||
sha512: z.string(),
|
||||
sha1: z.string(),
|
||||
});
|
||||
export type VersionFileHashes = z.infer<typeof VersionFileHashesSchema>;
|
||||
// endregion
|
||||
|
||||
// region VersionFile — 版本文件
|
||||
export const VersionFileSchema = z.object({
|
||||
/** 文件哈希,包含 sha512 和 sha1 */
|
||||
hashes: VersionFileHashesSchema,
|
||||
/** 文件直链下载地址 */
|
||||
url: z.string().url(),
|
||||
/** 文件名 */
|
||||
filename: z.string(),
|
||||
/** 是否为主文件。每版本最多一个主文件;若无则为第一个文件 */
|
||||
primary: z.boolean(),
|
||||
/** 文件大小(字节) */
|
||||
size: z.number().int().min(0),
|
||||
/** 文件类型;普通主 jar 为 null */
|
||||
file_type: FileTypeEnumSchema.nullable(),
|
||||
});
|
||||
export type VersionFile = z.infer<typeof VersionFileSchema>;
|
||||
// endregion
|
||||
|
||||
// region BaseVersion — 版本基础字段(Version 和 CreatableVersion 的公共基类)
|
||||
export const BaseVersionSchema = z.object({
|
||||
/** 版本名称 */
|
||||
name: z.string(),
|
||||
/** 版本号,建议遵循语义化版本 */
|
||||
version_number: z.string(),
|
||||
/** 更新日志(Markdown/纯文本);使用 include_changelog=false 时为 null */
|
||||
changelog: z.string().nullable(),
|
||||
/** 依赖列表 */
|
||||
dependencies: z.array(VersionDependencySchema),
|
||||
/** 支持的 Minecraft 版本列表 */
|
||||
game_versions: z.array(z.string()),
|
||||
/** 发布渠道 */
|
||||
version_type: z.enum(["release", "beta", "alpha"]),
|
||||
/** 支持的模组加载器列表 */
|
||||
loaders: z.array(z.string()),
|
||||
/** 是否为精选版本 */
|
||||
featured: z.boolean(),
|
||||
/** 版本状态 */
|
||||
status: z.enum(["listed", "archived", "draft", "unlisted", "scheduled"]),
|
||||
/** 请求的状态(用于审核流程) */
|
||||
requested_status: z.enum(["listed", "archived", "draft", "unlisted"]).nullable(),
|
||||
});
|
||||
export type BaseVersion = z.infer<typeof BaseVersionSchema>;
|
||||
// endregion
|
||||
|
||||
// region Version — 版本完整响应体(GET /version/{id}、GET /project/{id}/version 等返回)
|
||||
export const VersionSchema = BaseVersionSchema.extend({
|
||||
/** 版本唯一 ID(8 位 base62) */
|
||||
id: z.string().length(8),
|
||||
/** 所属项目 ID(8 位 base62) */
|
||||
project_id: z.string().length(8),
|
||||
/** 发布者用户 ID */
|
||||
author_id: z.string(),
|
||||
/** 发布时间(ISO-8601) */
|
||||
date_published: z.string().datetime(),
|
||||
/** 下载次数 */
|
||||
downloads: z.number().int().min(0),
|
||||
/** changelog URL(已废弃,始终为 null) */
|
||||
changelog_url: z.string().nullable(),
|
||||
/** 该版本的所有文件列表 */
|
||||
files: z.array(VersionFileSchema),
|
||||
});
|
||||
export type Version = z.infer<typeof VersionSchema>;
|
||||
// endregion
|
||||
Loading…
Reference in New Issue
Block a user