[REQ][typescript-fetch] Name downloaded files from Content-Disposition (return a File instead of an anonymous Blob)

未关闭
#24,956 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
3/5
预计耗时
1-2 天
新手友好度
35/100
Issue 类型
功能
描述清晰度
描述清楚
活跃度
停滞
技术栈
typescript
领域
api, tooling

调研方向

首先检查 typescript-fetch 中的 BlobApiResponse 实现,以及 typescript/http/http.mustache 中现有的文件名处理。查看生成的方法如何使用 BlobApiResponse.value(),然后验证完成后的行为是否保留 Blob 兼容性、公开所请求的文件名,并处理 Content-Disposition 的两种 filename 形式。

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

描述

Enhancement: Feature

For an operation whose response is a file (isResponseFile), the typescript-fetch runtime returns the body through BlobApiResponse.value():

export class BlobApiResponse {
    constructor(public raw: Response) {}
    async value(): Promise<Blob> {
        return await this.raw.blob();
    };
}

The name the server advertises in Content-Disposition (attachment; filename="invoice-2026-09.pdf") is dropped. Any client that wants to save the download under its real name has to bypass the generated method, call the xxxRaw() variant, read raw.headers and parse the header itself, and every project ends up with its own copy of that parsing.

Every other runtime in this repository already does it for the user:

  • typescript generator: ResponseContext.getBodyAsFile() returns new File([data], fileName, { type }) with fileName read from content-disposition (typescript/http/http.mustache).
  • Java (okhttp-gson, jersey2/3, apache-httpclient, feign, native, vertx): prepareDownloadFile names the temp file from Content-Disposition.
  • Python (api_client.mustache, __deserialize_file): idem.
  • C# (ClientUtils, FileParameter): idem.

typescript-fetch is the exception.

Describe the solution you'd like

Keep BlobApiResponse, make it return a File named after Content-Disposition (empty name when the header is absent, type taken from the blob):

async value(): Promise<File> {
    const blob = await this.raw.blob();
    return new File([blob], parseContentDispositionFilename(this.raw.headers) ?? '', { type: blob.type });
}

plus an exported parseContentDispositionFilename(headers) handling the RFC 5987 filename*=UTF-8''... form first and the plain filename= form otherwise.

Backward compatible: File extends Blob, so the generated methods still satisfy their declared Promise<Blob> return type and existing callers keep working; callers that want the name read file.name.

Describe alternatives you've considered

  • A new FileApiResponse next to BlobApiResponse: forces a template change in apis.mustache and a choice for the user, for no benefit since a File is a Blob.
  • Exposing only the helper and leaving value() unchanged: still leaves every user to call the raw variant.
  • Doing it in application code: that is what we do today, duplicated per project.

Additional context

File is a global in browsers and in Node.js 20+ (the CI matrix of the typescript-fetch samples runs Node 20).

PR: https://github.com/OpenAPITools/openapi-generator/pull/24957

主要语言
Java
星标
26.9k
派生
7.8k
平均合并
2 天 10 小时
30 天内合并 PR
180

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

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

OpenAPITools/openapi-generator 的其他 Issue

查看 OpenAPITools/openapi-generator 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

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