# @crabcrop/url 中文文档

规范地址：https://npmcn.com/package/%40crabcrop/url/

版本：0\.10\.1
npm 元数据更新时间：2026-11-09T13:59:38.984Z
中文译文更新时间：2026-11-10T22:49:28.991Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40crabcrop/url
原文对照：https://npmcn.com/package/%40crabcrop/url/?lang=original
项目主页：https://github.com/dayvson/crabcrop#readme
源码仓库：https://github.com/dayvson/crabcrop

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

- 包体积（解压后）：159 kB，20 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- 首次发布：2026-10-25T01:15:38.703Z
- 最新版本发布：2026-11-09T13:59:38.793Z
- 近 30 天下载量：5735（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：31（近 12 个月 31 个）

## 中文简介

构建并签名蟹类作物图像 URL

## 安装

```sh
npm install @crabcrop/url
```

也可以使用：`pnpm add @crabcrop/url`、`yarn add @crabcrop/url`、`bun add @crabcrop/url`

## README

# @crabcrop/url (英语)

构建和签名 [蟹类](https://github.com/dayvson/crabcrop) 来自TypeScript或JavaScript,在节点或浏览器中的URL. 无依赖关系:结点标志和封条 `node:crypto`,浏览器捆绑则获得相同功能的内置 TypeScript 执行(参见 [浏览器和捆绑器](https://npmcn.com/package/%40crabcrop/url/#readme-browsers-and-bundlers)) (中文(简体) ). 签名方案在 [`spec/url-signing.md`](https://npmcn.com/package/spec/url-signing.md)签名由峡谷支撑 [`spec/test-vectors.json`](https://npmcn.com/package/spec/test-vectors.json),这个软件包作为测试运行,解释者的判决和打字的构建者由共享语法公司在 [`spec/explain-verdicts.json`](https://npmcn.com/package/spec/explain-verdicts.json) 财务报告和审定财务报表 [`spec/operation-vectors.json`](https://npmcn.com/package/spec/operation-vectors.json)游乐场的套房 和服务器板条箱的差别测试也一样.

## 使用量

```ts
import { buildSealedURL, buildURL, buildSrcSet, purgeGroupSignature, purgeSignature, seal, sign, unseal, uploadSignature, verifyUrlSignature } from "@crabcrop/url";

// A signed URL. The operation string is passed verbatim and may
// contain several segments and preset: references.
const url = buildURL(
  "https://images.example.com",
  "your-secret",
  "crop:1200x630:smart/filters:format(webp)",
  "https://example.com/photo.jpg",
);

// An expiring URL (unix seconds), emitted as a leading exp: segment.
const expiring = buildURL(
  "https://images.example.com",
  "your-secret",
  "300x200",
  "https://example.com/photo.jpg",
  { expires: 1893456000 },
);

// A responsive srcset: one {width}x0 URL per width.
const srcset = buildSrcSet(
  "https://images.example.com",
  "your-secret",
  "https://example.com/photo.jpg",
  [400, 800, 1200],
);

// The raw signature for a remainder, if you assemble URLs yourself.
const signature = sign("your-secret", "300x200/https://example.com/photo.jpg");

// Verify a signed URL's signature locally, in constant time
// (unsigned or malformed URLs return null).
const ok = verifyUrlSignature("your-secret", url);

// Purge signatures for the server's /purge and /purge-group endpoints
// are domain-separated under a derived subkey; the helpers sign the
// right strings so callers never assemble them by hand.
const purge = purgeSignature("your-secret", "300x200/https://example.com/photo.jpg");
const group = purgeGroupSignature("your-secret", "thumb");

// Upload signatures for the server's PUT /upload/<signature>/<name>
// endpoint live in a third domain, under their own derived subkey.
// Pass an expiry (unix seconds) for a token that stops working
// then; its path is /upload/<signature>/exp:<expiry>/<name>.
const upload = uploadSignature("your-secret", "heroes/photo.jpg");
const expiringUpload = uploadSignature("your-secret", "heroes/photo.jpg", 1893456000);

// Sealed URLs (issue #255): the whole remainder encrypted into an
// opaque token in the signature slot, for public links whose recipe
// should stay unreadable. The server serves the sealed and plain
// forms of one render from the same cache entry.
const sealedUrl = buildSealedURL(
  "https://images.example.com",
  "your-secret",
  "300x200",
  "https://example.com/photo.jpg",
  { name: "photo.jpg" },
);
const remainder = unseal("your-secret", seal("your-secret", "300x200/https://example.com/photo.jpg"));
```

过 `null` 作为产生文字的秘密 `unsafe` 签名段,用于运行于 `CRABCROP_ALLOW_UNSAFE` 或以预设模式.

建造者投放操作或源 永远无法验证 : `?`, (中文(简体) ), `#`,白空间,控制和非ASCII字符,以及 `"` `<` `>` `\` `^` `` ` `` `{` `|` `}`,浏览器重写于 `<img src>` 或者说 `fetch()` 请求离开页面( e)`\` 变成 `/`其余的都是编码的 将源代码编码为第一(`x{y}.jpg` 作为 `x%7By%7D.jpg`);错误名称为编码。 全部规则在 [`spec/url-signing.md`](https://npmcn.com/package/spec/url-signing.md#building-urls)。 。 。 .

## 类型操作

操作字符串是 spec,通过它逐字保持主API. 对于那些更愿意建造它的召唤者来说, `ops` 财务报告和审定财务报表 `filter` 被键入的构建器可以验证每个反对服务器语法的论据并返回词条拼写,所以被键入和手写的形式会标出字节-等同的URL(测试套接字会以此来比对词条). 数字和名称也是空想:一个十进制参数是服务器打印它的方式所拼写出来的,对于每个参数,但演化内核的64位值是最短的十进制,可以读回相同的32位浮点数(C`ops.focalPoint(0.1 + 0.2, 0.4, 2)` 实值 `focalpoint:0.3x0.4:2`),一个类名被拼写为修饰(`ops.cropObjects(100, 100, [" person "])` 实值 `crop:100x100:objects(person):1`) (中文(简体) ). 例如:

```ts
import { buildURL, filter, joinOps, ops } from "@crabcrop/url";

const operations = joinOps(
  ops.crop(1200, 630, "smart"),
  ops.filters(filter.format("webp"), filter.quality(80)),
);
// operations === "crop:1200x630:smart/filters:format(webp):quality(80)"
const url = buildURL("https://images.example.com", "your-secret", operations, "https://example.com/photo.jpg");
```

服务器拒绝的值( A)`filter.quality(0)`, (中文(简体) ), `filter.brighten(256)`, (中文(简体) ), `ops.crop(0, 100)`)在构建时抛出,而不是在边缘刻出一个失败的 URL 。 关闭的套件作为类型导出( Q)`ImageFormat`, (中文(简体) ), `PerFormatQualityFormat`, (中文(简体) ), `CropAlign`, (中文(简体) ), `Anchor`, (中文(简体) ), `BlendMode`, (中文(简体) ), `MaskShape`, (中文(简体) ), `CurveChannel`, (中文(简体) ), `StudioMode`, (中文(简体) ), `StudioShadow`, (中文(简体) ), `Dimension`),选项对象也是如此(`FormatOptions` 页:1 `filter.format`, (中文(简体) ), `StudioOptions` 页:1 `filter.studio`) (中文(简体) ). `MAX_DIMENSION` 是服务器的每轴像素盖,16383. 大小、盒子、区域、边框、半径和像素建构器对照它(如 `ops.cropRect` 财务报告和审定财务报表 `ops.focal`,没有封顶) [框架整合](https://npmcn.com/package/frameworks) 输入他们自己的支票. `FILTER_DESCRIPTIONS` 是解释者使用的过滤元数据表.

```ts
import { filter, MAX_DIMENSION, ops, type FormatOptions } from "@crabcrop/url";

const jpeg: FormatOptions = { progressive: true, subsampling: 420 };
filter.format("jpeg", jpeg); // "format(jpeg,progressive,subsampling:420)"
ops.size(Math.min(requestedWidth, MAX_DIMENSION), 0); // clamp rather than throw
```

## 浏览器和捆绑器

包通过一个内部分解器导入密码, `#crypto`,哪个 `package.json` 按条件分列的地图 :

| 条件 | 后端 | 谁解决它 |
| --- | --- | --- |
| `browser` | `dist/crypto/portable.js`: SHA-256, HMAC-SHA-256, 和 AES-256-GCM 平面类型脚本 | 客户端从读取的捆绑器构建 `imports` 条件(Vite、Webpack 5、esbuild、Rollup) |
| `node` | `dist/crypto/node.js`数字 : `node:crypto` (开放SSL) | 节点和服务器构建目标 |
| `default` | 便携式后端 | 任何其他运行时间, 如边缘工人不兼容节点 |

软件包的其余部分使用Node Globals(无) `Buffer`,没有 `process`),因此客户端捆绑从不拉入已建节点. 每个函数在后端保持同步; WebCrypto 的 `crypto.subtle` 是同步的,无法保留 API 。 两个后端都产生相同的字节: 测试套件检查可移植字节与 `node:crypto` 数以千计的随机输入,并运行每一个光谱矢量 [`tests/browser-bundles`](https://npmcn.com/package/tests/browser-bundles) 与Vite建立框架集成,并运行没有节点环球的捆绑.

便携式后端速度较慢:每个签名约5 μs,对接2 μs左右 `node:crypto` (22号口),并用约四分之一毫秒来封存2个KB剩余部分,最大允许. 密封需要 `crypto.getRandomValues`,每个浏览器和边缘运行时间都可以提供。 它的AES回合通过密钥依赖字节来索引S-box,一个缓存刻度观察者原则上可以测量;节点为此原因和速度保持了OpenSSL.

浏览器代码中的秘密是公开的:任何装入页面的人都可以读取. 浏览器构建的存在使得客户端代码可以完全导入包:构建未签名并预设的URL,解释URL,并签名该秘密属于使用该页面的人的地方(一个游乐场式的工具). 只在服务器代码中以部署密钥签名 [框架整合](https://npmcn.com/package/frameworks) 绝不在浏览器中签名.

## 运行时间

已发布的软件包是编译的 JavaScript ()`dist/`)为节点 22. 出处为TypeScript并直接运行于22.18节点或更新(或23.6或更新)上,其中类型的剥取默认进行,这也是测试如何运行的:

```bash
npm test
```

`npm test` 正在建设 `dist/` (第一个) `#crypto` 导入解析处)和类型检查 [`test/exports.test.ts`](https://npmcn.com/package/%40crabcrop/url/test/exports.test.ts),它用它自己的名字导入包, 对照已建的申报, 所以在公共指数中缺失的类型在这里失效。 然后它运行 套房两次: `node:crypto`,然后再次在 `--conditions=browser` 在便携式后端.

在此寄存器中, 框架加载器和 MCP 服务器解析 `@crabcrop/url` 至这些源,所以一次构建软件包(`npm run build`在运行测试之前; 独立安装来自 npm 发布后, 或来自寄存器 `"@crabcrop/url": "file:../typescript"` 如此 repo 中的 MCP 软件包.

## 常见问题

### @crabcrop/url 是什么？

构建并签名蟹类作物图像 URL

### 如何安装 @crabcrop/url？

在项目目录运行 npm install @crabcrop/url，或使用 pnpm add / yarn add / bun add。

### @crabcrop/url 支持 TypeScript 吗？

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

### @crabcrop/url 支持 ESM 还是 CommonJS？

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

### @crabcrop/url 需要什么版本的 Node\.js？

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

### @crabcrop/url 可以商用吗？

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

### @crabcrop/url 的下载量有多少？

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

### @crabcrop/url 还在维护吗？

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

