Relax field constraints to match OpenAPI spec

Remove length, url format, and minimum value validations to align with
the upstream OpenAPI specification. Adjust field optionality in
BaseVersion so that CreatableVersion and Version can differ correctly.
This commit is contained in:
CPTProgrammer 2026-07-06 08:02:40 +08:00
parent 044ec153bc
commit 5dbca049b6
No known key found for this signature in database
2 changed files with 33 additions and 17 deletions

View File

@ -1,12 +1,20 @@
import { z } from "zod"; import { z } from "zod";
import { BaseVersionSchema, FileTypeEnumSchema } from "./version"; import {
BaseVersionSchema,
FileTypeEnumSchema,
VersionDependencySchema,
} from "./version";
// region CreatableVersion — 创建版本请求中的 data JSON // region CreatableVersion — 创建版本请求中的 data JSON
// OpenAPI CreatableVersion.required: file_parts, project_id, name, version_number,
// game_versions, version_type, loaders, featured, dependencies
export const CreatableVersionSchema = BaseVersionSchema.extend({ export const CreatableVersionSchema = BaseVersionSchema.extend({
/** 目标项目的 ID8 位 base62 */ /** 目标项目的 ID */
project_id: z.string().length(8), project_id: z.string(),
/** 所有承载文件的 multipart 字段名列表 */ /** 所有承载文件的 multipart 字段名列表 */
file_parts: z.array(z.string()), file_parts: z.array(z.string()),
/** 依赖列表。override BaseVersion 的 optional → required */
dependencies: z.array(VersionDependencySchema),
/** 主文件的 multipart 字段名;不提供时推断第一个文件为主文件 */ /** 主文件的 multipart 字段名;不提供时推断第一个文件为主文件 */
primary_file: z.string().optional(), primary_file: z.string().optional(),
/** 目标环境 */ /** 目标环境 */

View File

@ -40,29 +40,30 @@ export const VersionFileSchema = z.object({
/** 文件哈希,包含 sha512 和 sha1 */ /** 文件哈希,包含 sha512 和 sha1 */
hashes: VersionFileHashesSchema, hashes: VersionFileHashesSchema,
/** 文件直链下载地址 */ /** 文件直链下载地址 */
url: z.string().url(), url: z.string(),
/** 文件名 */ /** 文件名 */
filename: z.string(), filename: z.string(),
/** 是否为主文件。每版本最多一个主文件;若无则为第一个文件 */ /** 是否为主文件。每版本最多一个主文件;若无则为第一个文件 */
primary: z.boolean(), primary: z.boolean(),
/** 文件大小(字节) */ /** 文件大小(字节) */
size: z.number().int().min(0), size: z.number().int(),
/** 文件类型;普通主 jar 为 null */ /** 文件类型;普通主 jar 为 null */
file_type: FileTypeEnumSchema.nullable(), file_type: FileTypeEnumSchema.nullable(),
}); });
export type VersionFile = z.infer<typeof VersionFileSchema>; export type VersionFile = z.infer<typeof VersionFileSchema>;
// endregion // endregion
// region BaseVersion — 版本基础字段Version 和 CreatableVersion 的公共基类) // region BaseVersion — 版本基础字段
// OpenAPI BaseVersion 无 required 数组,以下按 "同时在两个子类都 required" 的字段设为必填
export const BaseVersionSchema = z.object({ export const BaseVersionSchema = z.object({
/** 版本名称 */ /** 版本名称 */
name: z.string(), name: z.string(),
/** 版本号,建议遵循语义化版本 */ /** 版本号,建议遵循语义化版本 */
version_number: z.string(), version_number: z.string(),
/** 更新日志Markdown/纯文本);使用 include_changelog=false 时为 null */ /** 更新日志Markdown/纯文本);使用 include_changelog=false 时为 null */
changelog: z.string().nullable(), changelog: z.string().nullable().optional(),
/** 依赖列表 */ /** 依赖列表。CreatableVersion 中必填Version 响应中可选;子类通过 override 差异化 */
dependencies: z.array(VersionDependencySchema), dependencies: z.array(VersionDependencySchema).optional(),
/** 支持的 Minecraft 版本列表 */ /** 支持的 Minecraft 版本列表 */
game_versions: z.array(z.string()), game_versions: z.array(z.string()),
/** 发布渠道 */ /** 发布渠道 */
@ -72,25 +73,32 @@ export const BaseVersionSchema = z.object({
/** 是否为精选版本 */ /** 是否为精选版本 */
featured: z.boolean(), featured: z.boolean(),
/** 版本状态 */ /** 版本状态 */
status: z.enum(["listed", "archived", "draft", "unlisted", "scheduled"]), status: z
.enum(["listed", "archived", "draft", "unlisted", "scheduled", "unknown"])
.default("listed"),
/** 请求的状态(用于审核流程) */ /** 请求的状态(用于审核流程) */
requested_status: z.enum(["listed", "archived", "draft", "unlisted"]).nullable(), requested_status: z
.enum(["listed", "archived", "draft", "unlisted"])
.nullable()
.optional(),
}); });
export type BaseVersion = z.infer<typeof BaseVersionSchema>; export type BaseVersion = z.infer<typeof BaseVersionSchema>;
// endregion // endregion
// region Version — 版本完整响应体GET /version/{id}、GET /project/{id}/version 等返回) // region Version — 版本完整响应体
// OpenAPI Version.required: id, project_id, author_id, date_published, downloads, files,
// name, version_number, game_versions, version_type, loaders, featured
export const VersionSchema = BaseVersionSchema.extend({ export const VersionSchema = BaseVersionSchema.extend({
/** 版本唯一 ID8 位 base62 */ /** 版本唯一 ID8 位 base62 */
id: z.string().length(8), id: z.string(),
/** 所属项目 ID8 位 base62 */ /** 所属项目 ID */
project_id: z.string().length(8), project_id: z.string(),
/** 发布者用户 ID */ /** 发布者用户 ID */
author_id: z.string(), author_id: z.string(),
/** 发布时间ISO-8601 */ /** 发布时间ISO-8601 */
date_published: z.string().datetime(), date_published: z.string(),
/** 下载次数 */ /** 下载次数 */
downloads: z.number().int().min(0), downloads: z.number().int(),
/** changelog URL已废弃始终为 null */ /** changelog URL已废弃始终为 null */
changelog_url: z.string().nullable(), changelog_url: z.string().nullable(),
/** 该版本的所有文件列表 */ /** 该版本的所有文件列表 */