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