withValidator({ query }) keeps only the last value of a repeated query key

已关闭 适合新手
#645 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

已经有一个关联 PR 被合并了。

  • #652 来自 @Dazzanova —— 已合并

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
typescript

调研方向

从 src/runtime/validator.ts 中的 runValidation 开始,issue 指出查询参数是逐个键复制的。检查 c.req.queries() 如何表示重复键,并将其行为与 Hono 的查询验证器进行比较。当重复键以数组形式传递给 schema、单个键仍为字符串,并且相关测试覆盖现有查询验证行为时,即为完成。

由索引模型根据 Issue 内容生成。

描述

What happens

When a query key appears more than once, withValidator({ query }) passes only its last value to the schema. The earlier values are dropped without any error.

export const loader = defineHandler(
  withValidator({ query: z.object({ tag: z.union([z.string(), z.array(z.string())]) }) }),
  (c) => c.input.query,
);

GET /notes?tag=work&tag=urgent

  • Expected: { tag: ['work', 'urgent'] }
  • Actual: { tag: 'urgent' }

A schema that expects an array, like z.object({ tag: z.array(z.string()) }), never passes: Void always gives it a string.

Cause

runValidation in src/runtime/validator.ts copies the search params one key at a time, so each repeated key overwrites the one before:

const raw = {};
for (const [key, value] of url.searchParams) raw[key] = value;
Suggested fix

Do what Hono's validator('query') does: a key that appears once stays a string, and a key that repeats becomes an array.

const raw = {};
for (const [key, values] of Object.entries(c.req.queries())) {
  raw[key] = values.length === 1 ? values[0] : values;
}

For keys that appear once, this works exactly as before, so existing schemas aren't affected.

Why it matters

Multi-select filters (?tag=a&tag=b) are a common pattern, and HTML forms send a <select multiple> or a group of checkboxes this way. Other frameworks keep every value: Hono's own validator and Nuxt's getQuery() return arrays, and React Router and SvelteKit have searchParams.getAll().

Version: void 1.4.0

主要语言
TypeScript
星标
627
派生
66
平均合并
14 小时 38 分钟
30 天内合并 PR
179

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

voidzero-dev/void 的其他 Issue

查看 voidzero-dev/void 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。