# @apicity/free-media-upload 中文文档

规范地址：https://npmcn.com/package/%40apicity/free-media-upload/

版本：0\.27\.0
npm 元数据更新时间：2026-11-06T09:55:02.250Z
中文译文更新时间：2026-11-06T10:13:31.552Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40apicity/free-media-upload
原文对照：https://npmcn.com/package/%40apicity/free-media-upload/?lang=original
项目主页：https://github.com/justintanner/apicity#readme
源码仓库：https://github.com/justintanner/apicity

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：101 kB，35 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.0\.0
- 运行依赖：1 个
- 首次发布：2026-05-10T07:46:36.040Z
- 最新版本发布：2026-11-06T09:55:01.960Z
- 近 30 天下载量：3818（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：90（近 12 个月 90 个）

## 中文简介

0-Auth文件托管包装器用于收件箱,gofile,ugu,filebin,垃圾箱,tirsh,tflink,和tmpfiles——一个打入的表面后面有8个提供者.

## 安装

```sh
npm install @apicity/free-media-upload
```

也可以使用：`pnpm add @apicity/free-media-upload`、`yarn add @apicity/free-media-upload`、`bun add @apicity/free-media-upload`

## README

# @apicity/ free- media- upload (帮助)

[![npm](https://img.shields.io/npm/v/@apicity/free-media-upload?color=cb0000)](https://www.npmjs.com/package/@apicity/free-media-upload) [![dependencies](https://img.shields.io/badge/dependencies-1-blue)](https://npmcn.com/package/%40apicity/free-media-upload/package.json) [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript&logoColor=white)](https://npmcn.com/package/%40apicity/free-media-upload/tsconfig.json)

0-Auth文件托管包装器用于收件箱,gofile,ugu,filebin,垃圾箱,tirsh,tflink,和tmpfiles——一个打入的表面后面有8个提供者.

运行时间依赖性 :

-   `zod@^4.6.6` - 请求在每一个 POST 端点上附加计划 `.schema`

## 安装

```bash
npm install @apicity/free-media-upload
# or
pnpm add @apicity/free-media-upload
```

## 快速启动

```typescript
import { createFreeMediaUpload } from "@apicity/free-media-upload";

const freeMediaUpload = createFreeMediaUpload();
```

## 真实世界的例子: 在四个免费主机之间比赛一张肖像

`@apicity/free-media-upload` 覆盖8个零自动、无账户文件托管端点 在一个打字的地表后面——胜利可以同样扇出 `Blob` 输出到并行的多个主机, 然后选择任何 URL 返回 首先(或任何幸存者)不重写四个不同的多部分 召来者. 下面的片段上传了单张84 KB JPEG 到四张 最富有的反应形状——收件箱(平面字符串),去文件(丰富的捆绑) 元数据),ugu(随机重命名+dupe检测),filebin(md5/sha256+) ——并显示如何在其中一种情况下使其正常化 `toUrl()` 帮手.

下面的每个 URL、字节数和散列都是从 [`tests/recordings/free_2578706139/`](https://npmcn.com/tests/recordings/free_2578706139/), (中文(简体) ), 重播者为 [`tests/integration/free-catbox.test.ts`](https://npmcn.com/tests/integration/free-catbox.test.ts), (中文(简体) ), [`tests/integration/free-gofile.test.ts`](https://npmcn.com/tests/integration/free-gofile.test.ts), (中文(简体) ), [`tests/integration/free-uguu.test.ts`](https://npmcn.com/tests/integration/free-uguu.test.ts), (中文(简体) ), [`tests/integration/free-filebin.test.ts`](https://npmcn.com/tests/integration/free-filebin.test.ts), (中文(简体) ), 财务报告和审定财务报表 [`tests/integration/free-litterbox.test.ts`](https://npmcn.com/tests/integration/free-litterbox.test.ts)。 。 。 .

```typescript
import { readFileSync } from "node:fs";
import { createFreeMediaUpload } from "@apicity/free-media-upload";
import type { GofileUploadResponse, UguuUploadResponse, FilebinUploadResponse } from "@apicity/free-media-upload";

// 1. The factory takes no api key — every host below is genuinely
//    auth-free and account-free. Pass `{ timeout: 60_000 }` or a
//    custom `fetch` if you need to override the defaults.
const freeMediaUpload = createFreeMediaUpload();

const bytes = readFileSync("./cat1.jpg"); // 83,558 bytes
const file = new Blob([bytes], { type: "image/jpeg" });

// 2. Race four hosts in parallel via Promise.all. Each returns a
//    different shape: catbox/litterbox/tempsh hand back a plain
//    `string` URL, gofile/tflink return a metadata bundle, uguu's
//    payload nests under `files[]`, and filebin splits things into
//    `bin` + `file` blocks. The factory keeps these distinctions in
//    the type system so the destructure below is statically checked.
const [catboxUrl, gofile, uguu, filebin] = (await Promise.all([
  freeMediaUpload.catbox.upload({ file, filename: "cat1.jpg" }),
  freeMediaUpload.gofile.upload({ file, filename: "cat1.jpg" }),
  freeMediaUpload.uguu.upload({ file, filename: "cat1.jpg" }),
  freeMediaUpload.filebin.upload({ file, filename: "cat1.jpg", bin: "apicity-test-img" }),
])) as [string, GofileUploadResponse, UguuUploadResponse, FilebinUploadResponse];

// 3. catbox is the simplest UX: text/plain response, just the URL,
//    permanent until the operator deletes it. Good for a 'host once,
//    forget' public asset.
console.log(catboxUrl);
// → "https://files.catbox.moe/0ufdor.jpg"

// 4. gofile is the only host that gives you a sharable download page
//    (suitable for human consumption) plus a CDN-direct id you can use
//    to build APIs against. The `parentFolderCode` is a 6-char folder
//    handle — every upload lands in a fresh anonymous folder unless
//    you authenticate.
console.log(gofile.data.downloadPage);
// → "https://gofile.io/d/hmoMxW"
console.log(gofile.data.id, gofile.data.md5, gofile.data.size);
// → "a7feccb4-96b4-4b2c-923a-832106388ad6" "391a26048ce697ba072acd83209923f7" 83558

// 5. uguu rewrites filenames to a random 8-char slug to stop URL
//    enumeration, and tells you whether your bytes were already on
//    the host (`dupe: true`) so you can skip a re-upload next time.
//    Note the `files[]` array — uguu accepts batched uploads via the
//    same endpoint, even though @apicity/free-media-upload only ships single-file.
console.log(uguu.files[0].url, uguu.files[0].dupe);
// → "https://n.uguu.se/GeNMsbBp.jpg" false

// 6. filebin verifies content integrity for you — it returns both
//    md5 and sha256, plus an expiry. The `bin` is a namespace you can
//    re-upload into to grow a multi-file bundle (omit `bin` and you
//    get an auto-generated one). Files in a bin expire together on
//    `bin.expired_at`.
console.log(filebin.file.md5, filebin.file.sha256);
// → "ORomBIzml7oHKs2DIJkj9w==" "561dbe5dcd0c931cd3b41705ebe00df9181560967cea8b17128373a06ab911a3"
console.log(`bin "${filebin.bin.id}" expires ${filebin.bin.expired_at}`);
// → 'bin "apicity-test-img" expires 2026-04-23T07:19:25.458442Z'

// 7. Hosts that return strings already give you a URL; hosts that
//    return JSON bury it under different keys. A tiny normaliser lets
//    downstream code stop caring which host won the race.
function toUrl(
  res: string | GofileUploadResponse | UguuUploadResponse | FilebinUploadResponse,
  bin?: string,
  filename?: string,
): string {
  if (typeof res === "string") return res;
  if ("data" in res) return res.data.downloadPage;       // gofile
  if ("files" in res) return res.files[0].url;           // uguu
  return `https://filebin.net/${bin}/${filename}`;       // filebin
}

console.log([
  toUrl(catboxUrl),
  toUrl(gofile),
  toUrl(uguu),
  toUrl(filebin, "apicity-test-img", "cat1.jpg"),
]);
// → [
//     "https://files.catbox.moe/0ufdor.jpg",
//     "https://gofile.io/d/hmoMxW",
//     "https://n.uguu.se/GeNMsbBp.jpg",
//     "https://filebin.net/apicity-test-img/cat1.jpg",
//   ]
```

### 跨时空主机失败

当您只需要一个 URL 就可以活上几个小时时 下游的型号 即将得到它一次,然后忘记.. `@apicity/free-media-upload` 船舶a `uploadToAnyHost` 随机移动主机列表并 返回第一个成功的 URL, 升起单个 `FreeMediaUploadError` 只有在 每个主机失败 。 当一个供应商是 Flashy 时有用( guu 的 CDN 可以 502) 不过你不在乎谁赢了.

```typescript
import { readFileSync } from "node:fs";
import { createFreeMediaUpload, uploadToAnyHost, FreeMediaUploadError } from "@apicity/free-media-upload";

const freeMediaUpload = createFreeMediaUpload();
const bytes = readFileSync("./cat1.jpg");
const file = new Blob([bytes], { type: "image/jpeg" });

// litterbox accepts a TTL; uguu and tflink are best-effort permanent.
// uploadToAnyHost shuffles the list and tries each host sequentially,
// so a single 502 from uguu falls through to tflink without your code
// ever seeing it. The returned URL is already normalised — string in,
// string out, regardless of which host responded.
try {
  const url = await uploadToAnyHost(freeMediaUpload, {
    file,
    filename: "cat1.jpg",
    hosts: ["litterbox", "uguu", "tflink"],
    time: "12h", // forwarded to litterbox if it wins the shuffle
  });
  console.log(url);
  // → "https://litter.catbox.moe/04obtk.jpg"  // example: litterbox won
} catch (err) {
  if (err instanceof FreeMediaUploadError) {
    // err.body.failures is a string[] of `<host>: <message>` lines —
    // useful for surfacing exactly which hosts misbehaved.
    console.error(err.status, err.body);
  }
}
```

**页:1**

-   所有8个终点 `{ file: Blob, filename?: string }`收发箱 和垃圾箱回复 `text/plain` (URL本身);tmp文件, uguu, gofile, filebin, and tflink 返回 JSON; 临时返回平原 语句。 工厂对每一个都进行了正确分析 这样你就不会看到原始的 身体——只是打入的形状.
-   `litterbox.upload` 唯一的终点是 `time` 字段 - `"1h" | "12h" | "24h" | "72h"`超过72小时的任何需要 永久托管兄弟姐妹(catbox, gofile, filebin).
-   `filebin.upload` 是个二进制 `POST` (无) 多块包装,所以 `Blob` 电线是... .. 服务器处理 `<bin>/<filename>` 作为上传目标。 重新装入 改为: `bin` 将文件添加到捆绑中而不是替换 它; 预创建一个稳定 `bin` shult来生长多文件集.
-   gofile (英语) `guestToken` 是这个供应商最接近的 认证手柄 – 如果您想稍后删除上传内容, 请保存它 gofile API (英语). 没有它,匿名上传只写.
-   每个端点都暴露出一个Zod计划: `freeMediaUpload.catbox.upload.schema.safeParse(input)` 验证有效载荷 在网络呼叫之前,它发现了最常见的错误 (通过a) `Buffer` 或者说 `string` 而不是一个 `Blob`) (中文(简体) ).
-   所有终点都接受 `AbortSignal` 第二个参数和作曲 与 `withRetry` 编号 : `withFallback` 从 `@apicity/free-media-upload`中间软件 再出口——用于出行429s的出行口袋或链式出行口袋—— 作为倒背的一对.
-   丢出错误 `FreeMediaUploadError` 与 `status` 和附着的解析体: `try { ... } catch (e) { if (e instanceof FreeMediaUploadError) console.error(e.status, e.body); }`。 。 。 .

## API 参考

8个终点横跨了8组. 每个方法都映射出上游的 URL 路径 .

### 纸箱

`POST` **`free-media-upload.catbox.upload`**

`POST [https://catbox.moe/user/api.php](https://catbox.moe/user/api.php)`

成本等级 : `cheap`

[上游区域](https://catbox.moe/tools.php)

```typescript
const res = await freeMediaUpload.catbox.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 文件编辑器

`POST` **`free-media-upload.filebin.upload`**

`POST https://filebin.net/{bin}/{filename}`

成本等级 : `cheap`

[上游区域](https://filebin.net/)

```typescript
const res = await freeMediaUpload.filebin.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 进程文件

`POST` **`free-media-upload.gofile.upload`**

`POST [https://upload.gofile.io/uploadfile](https://upload.gofile.io/uploadfile)`

成本等级 : `cheap`

[上游区域](https://gofile.io/api)

```typescript
const res = await freeMediaUpload.gofile.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 垃圾箱

`POST` **`free-media-upload.litterbox.upload`**

`POST [https://litterbox.catbox.moe/resources/internals/api.php](https://litterbox.catbox.moe/resources/internals/api.php)`

成本等级 : `cheap`

[上游区域](https://litterbox.catbox.moe/)

```typescript
const res = await freeMediaUpload.litterbox.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 临时

`POST` **`free-media-upload.tempsh.upload`**

`POST [https://temp.sh/upload](https://temp.sh/upload)`

成本等级 : `cheap`

[上游区域](https://temp.sh/)

```typescript
const res = await freeMediaUpload.tempsh.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 链接

`POST` **`free-media-upload.tflink.upload`**

`POST [https://tmpfile.link/api/upload](https://tmpfile.link/api/upload)`

成本等级 : `cheap`

[上游区域](https://tmpfile.link/)

```typescript
const res = await freeMediaUpload.tflink.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### tmp文件

`POST` **`free-media-upload.tmpfiles.api.v1.upload`**

`POST [https://tmpfiles.org/api/v1/upload](https://tmpfiles.org/api/v1/upload)`

成本等级 : `cheap`

[上游区域](https://tmpfiles.org/)

```typescript
const res = await freeMediaUpload.tmpfiles.api.v1.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

### 乌古

`POST` **`free-media-upload.uguu.upload`**

`POST [https://uguu.se/upload](https://uguu.se/upload)`

成本等级 : `cheap`

[上游区域](https://uguu.se/)

```typescript
const res = await freeMediaUpload.uguu.upload({ /* ... */ });
```

资料来源: [`packages/provider/free-media-upload/src/freeMediaUpload.ts`](https://npmcn.com/package/%40apicity/free-media-upload/src/freeMediaUpload.ts)

## 中间软件

```typescript
import { createFreeMediaUpload, withRetry } from "@apicity/free-media-upload";

const freeMediaUpload = createFreeMediaUpload();
const upload = withRetry(freeMediaUpload.uguu.upload, { retries: 3 });
```

部分 [辣点](https://github.com/justintanner/apicity) 单相机.

## 许可证

麻省理工学院——见 [自由主义](https://npmcn.com/package/%40apicity/free-media-upload/LICENSE)。 。 。 .

## 常见问题

### @apicity/free-media-upload 是什么？

0-Auth文件托管包装器用于收件箱,gofile,ugu,filebin,垃圾箱,tirsh,tflink,和tmpfiles——一个打入的表面后面有8个提供者\.

### 如何安装 @apicity/free-media-upload？

在项目目录运行 npm install @apicity/free-media-upload，或使用 pnpm add / yarn add / bun add。

### @apicity/free-media-upload 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @apicity/free-media-upload 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @apicity/free-media-upload 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @apicity/free-media-upload 可以商用吗？

@apicity/free-media-upload 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @apicity/free-media-upload 的下载量有多少？

根据 npm 官方下载统计，@apicity/free-media-upload 在 2026/10/06 – 2026/11/04 这 30 天内被下载 3,818 次，日均约 127 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @apicity/free-media-upload 还在维护吗？

最新版本 0\.27\.0 发布于 2026/11/06（今天）；至今共发布 90 个版本，其中过去 12 个月发布了 90 个；首次发布于 2026/05/10。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

