# @cdxgen/cdx-purl 中文文档

规范地址：https://npmcn.com/package/%40cdxgen/cdx-purl/

版本：0\.0\.6
npm 元数据更新时间：2026-09-30T14:02:25.783Z
中文译文更新时间：2026-11-09T06:56:10.002Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40cdxgen/cdx-purl
原文对照：https://npmcn.com/package/%40cdxgen/cdx-purl/?lang=original
项目主页：http://github.com/cdxgen/cdx-purl
源码仓库：https://github.com/cdxgen/cdx-purl

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

- 包体积（解压后）：92.3 kB，5 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- Node.js 要求：\>=20
- 运行依赖：0 个
- 首次发布：2026-04-25T22:31:43.436Z
- 最新版本发布：2026-09-30T14:02:25.406Z
- 近 30 天下载量：50258（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 5 个）

## 中文简介

纯 JavaScript 软件包- url 解析器和构建器

## 安装

```sh
npm install @cdxgen/cdx-purl
```

也可以使用：`pnpm add @cdxgen/cdx-purl`、`yarn add @cdxgen/cdx-purl`、`bun add @cdxgen/cdx-purl`

## README

# cdx- purl (英语)

严格,由定义驱动的软件包-url 解析器/构建器用于节点.js.

-   纯 Java 脚本
-   没有运行时间依赖关系
-   ABNF 第一次严格剖析
-   类型规则来自 `specification/types/*-definition.json` 输入 `generated/type-rules.js`
-   断断续续的教条化和圆通行为

[![AI-DECLARATION: auto](https://img.shields.io/badge/%E4%B7%BC%20AI--DECLARATION-auto-ede9fe?labelColor=ede9fe)](https://npmcn.com/package/%40cdxgen/cdx-purl/AI-DECLARATION.md)

## 安装

```bash
pnpm add @cdxgen/cdx-purl
```

```bash
npm install @cdxgen/cdx-purl
```

```bash
bun add @cdxgen/cdx-purl
```

```bash
deno add npm:@cdxgen/cdx-purl
```

## 快开始

```js
import {
  parse,
  build,
  roundTrip,
  Purl,
  NpmPurl,
  MavenPurl,
  TypedPurlBuilders,
  TypedPurls,
} from "@cdxgen/cdx-purl";

const parsed = parse("pkg:npm/%40angular/animation@12.3.1");
const built = build(parsed);
const canonical = roundTrip(built);

const npmPurl = NpmPurl.builder()
  .setScope("@angular")
  .setName("animation")
  .setVersion("12.3.1")
  .build()
  .toString();

const MavenBuilder = TypedPurlBuilders.maven;
const mvn = new MavenBuilder()
  .setNamespace("org.apache.commons")
  .setName("io")
  .buildString();

console.log(parsed, canonical, npmPurl, mvn, !!TypedPurls.swift);
```

## API 密码

-   `parse(input)` 分析并验证严格的ABNF + 类型规则
-   `build(parts)` 进行严格验证的运河建设
-   `roundTrip(input)` 剖析然后构建条形输出
-   `Purl` 不可移动的严格值对象
-   `PurlBuilder` 流利的通用构建器
-   `TypedPurlBuilders` 生成按类型键的构建者类
-   `TypedPurls` 已生成按类型键的已键分类
-   `getTypedPurlBuilder(type)` 财务报告和审定财务报表 `getTypedPurlClass(type)` 寻找助手

运行时注释 : `index.js` 产生的进口 `TYPE_RULES_SOURCE` 从 `generated/type-rules.js`; 不读 `specification/types` JSON执行时的文件.

所有已命名的打出导出( 例如 ) `NpmPurlBuilder`, (中文(简体) ), `RpmPurl`, (中文(简体) ), `VscodeExtensionPurlBuilder`)是混凝土生成的类,而不是占位符.

## 验证行为(按设计限制)

### 保留字符必须是%- 编码

在分离器之外,只有字母,数字, `.`, (中文(简体) ), `-`, (中文(简体) ), `_`, (中文(简体) ), `~` 财务报告和审定财务报表 `:` 可能 字面上出现在 purl 组件中(`specification/purl-proposed-grammar.abnf`) (中文(简体) ). `parse` 而不是猜测什么,包括 页:1 `+` 和Debian或Go版本。 传出原始值 改为 `build` 它能逃避他们; `parse` 又解码了.

```js
import { build, parse } from "@cdxgen/cdx-purl";

build({ type: "npm", name: "app", version: "1.0.0+build.5" });
// "pkg:npm/app@1.0.0%2Bbuild.5"
parse("pkg:npm/app@1.0.0%2Bbuild.5").version; // "1.0.0+build.5"

parse("pkg:npm/app@1.0.0+build.5");
// throws E_INVALID_CHARACTER:
// Invalid character "+" in version at index 5; percent-encode it as %2B
```

`E_INVALID_CHARACTER` 财务报告和审定财务报表 `E_DISALLOWED_PERCENT_ENCODING` 错误带入 违法 `component` (单位:千美元)`name`, (中文(简体) ), `version`, (中文(简体) ), `namespace`, (中文(简体) ), `subpath` 或者说 `qualifier <key>`页:1 `index` 在该组件原始文本中 `character` (或逃跑)在那里发现,和为 `E_INVALID_CHARACTER` 页:1 `encoded` 表格来代替。 必须写入的字符逃避 字面上( 简写为`%41` 页:1 `A`和一个逃走的分离者`%2F` 在命名空间中或 (子路径)以 `E_DISALLOWED_PERCENT_ENCODING`。 。 。 .

上游测试套房有几套解析和圆通箱,其输入离开 (单位:千美元) `+` 未回避( n)`NSData+zlib`, (中文(简体) ), `Enterprise+Server`cdx-purl 拒绝这些 投入;其逃出的形式产生准确的上游期望 (单位:千美元)`test/reserved-character-errors.test.js`) (中文(简体) ).

### 未知的修饰键被拒绝

```js
import { build } from "@cdxgen/cdx-purl";

build({
  type: "maven",
  namespace: "org.apache.commons",
  name: "io",
  version: "1.3.4",
  qualifiers: { mykey: "value" }, // throws E_UNKNOWN_QUALIFIER
  subpath: null,
});
```

### 只接受明确允许的多值限定符

```js
import { build } from "@cdxgen/cdx-purl";

// throws E_MULTIVALUE_QUALIFIER
build({
  type: "maven",
  namespace: "org.apache.commons",
  name: "io",
  version: "1.3.4",
  qualifiers: { classifier: "sources,docs" },
  subpath: null,
});

// allowed: checksum supports comma-delimited values
build({
  type: "generic",
  namespace: null,
  name: "openssl",
  version: "1.1.1w",
  qualifiers: {
    checksum:
      "sha1:da39a3ee5e6b4b0d3255bfef95601890afd80709,sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  },
  subpath: null,
});
```

### 校验和值通过算法验证

校验和必须使用 `algorithm:digest` 形式。 库会对照内部算法映射来验证每个条目,并拒绝缺少一个算法,非hex,或选定算法错误长度的文摘.

```js
import { parse } from "@cdxgen/cdx-purl";

// success: valid lengths for each algorithm
parse(
  "pkg:generic/openssl@1.1.1w?checksum=" +
    "sha1:da39a3ee5e6b4b0d3255bfef95601890afd80709," +
    "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
);

// throws E_CHECKSUM_MISSING_ALGORITHM
parse(
  "pkg:generic/openssl@1.1.1w?checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709",
);

// throws E_CHECKSUM_INVALID_DIGEST_FOR_ALGORITHM (wrong length)
parse("pkg:generic/openssl@1.1.1w?checksum=sha256:abc123");

// throws E_CHECKSUM_INVALID_DIGEST_FOR_ALGORITHM (non-hex)
parse(
  "pkg:generic/openssl@1.1.1w?checksum=" +
    "sha1:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
);
```

### 要求的和被禁的类别字段得到执行

```js
import { build } from "@cdxgen/cdx-purl";

// swift namespace is required and must contain host/owner
build({
  type: "swift",
  namespace: null, // throws E_REQUIRED_COMPONENT / E_SWIFT_NAMESPACE
  name: "alamofire",
  version: null,
  qualifiers: null,
  subpath: null,
});
```

### 虚空模块路径没有命名空间被接受

皮尔 `golang` 定义日期 访问模块并按要求标记命名空间 . 单块虚空模块路径, 如 `go.opencensus.io` 无效的 Go 模块 namespace,所以当名称类似主机(dot-separated 标签)时它们会被接受. 不类似主机的去名仍需要命名空间 .

```js
import { parse } from "@cdxgen/cdx-purl";

parse("pkg:golang/go.opencensus.io@v0.24.0"); // ok, namespace is null
parse("pkg:golang/k8s.io"); // ok
parse("pkg:golang/context"); // throws E_REQUIRED_COMPONENT
```

### 构建器和对象流中的子路径验证

当您直接提供 purl 部件时(`build`, (中文(简体) ), `Purl.from`,键入的构建者), `subpath` 必须是相对的. 绝对类型值被拒绝 `E_INVALID_SUBPATH` 和一个可操作的信息. 这包括领导 `/` 和 Windows 绝对形式 `C:\\docs\\api` 或者说 `\\\\server\\share\\docs`。 。 。 .

```js
import { build, parse } from "@cdxgen/cdx-purl";

// throws E_INVALID_SUBPATH
build({
  type: "generic",
  namespace: null,
  name: "openssl",
  version: "1.1.1w",
  qualifiers: null,
  subpath: "/docs/api",
});

// accepted: relative subpath
build({
  type: "generic",
  namespace: null,
  name: "openssl",
  version: "1.1.1w",
  qualifiers: null,
  subpath: "docs/api",
});

// parser compatibility: raw purl subpaths are canonicalized
// `//docs///api/` -> `docs/api`
parse("pkg:generic/openssl@1.1.1w#//docs///api/"); // => { type: "generic", namespace: null, name: "openssl", version: "1.1.1w", qualifiers: null, subpath: "docs/api" }
```

## 支持的 purl 类型

库在生成时生成每类定义的打入类/构建器 `specification/types/*-definition.json`数字 :

`alpm`, (中文(简体) ), `apk`, (中文(简体) ), `bazel`, (中文(简体) ), `bitbucket`, (中文(简体) ), `bitnami`, (中文(简体) ), `cargo`, (中文(简体) ), `chrome-extension`, (中文(简体) ), `cocoapods`, (中文(简体) ), `composer`, (中文(简体) ), `conan`, (中文(简体) ), `conda`, (中文(简体) ), `cpan`, (中文(简体) ), `cran`, (中文(简体) ), `deb`, (中文(简体) ), `docker`, (中文(简体) ), `gem`, (中文(简体) ), `generic`, (中文(简体) ), `github`, (中文(简体) ), `golang`, (中文(简体) ), `hackage`, (中文(简体) ), `hex`, (中文(简体) ), `huggingface`, (中文(简体) ), `julia`, (中文(简体) ), `luarocks`, (中文(简体) ), `maven`, (中文(简体) ), `mlflow`, (中文(简体) ), `npm`, (中文(简体) ), `nuget`, (中文(简体) ), `oci`, (中文(简体) ), `opam`, (中文(简体) ), `otp`, (中文(简体) ), `pub`, (中文(简体) ), `pypi`, (中文(简体) ), `qpkg`, (中文(简体) ), `rpm`, (中文(简体) ), `swid`, (中文(简体) ), `swift`, (中文(简体) ), `vscode-extension`, (中文(简体) ), `yocto`。 。 。 .

| 需求领域 | 官方光谱来源 | 这个图书馆执行什么 | 主错误代码 |
| --- | --- | --- | --- |
| 标记类型和限定键外壳 | `specification/purl-proposed-grammar.abnf` + 类型定义 | 键入并修饰到小写; 决定修饰顺序 | `E_INVALID_TYPE`, (中文(简体) ), `E_INVALID_QUALIFIER_KEY`, (中文(简体) ), `E_DUPLICATE_QUALIFIER` |
| ABNF 严格解析规则 | `specification/purl-proposed-grammar.abnf` | 计划必须是 `pkg`; 严格的分隔符使用; 严格的%编码接受和解码 | `E_INVALID_SCHEME`, (中文(简体) ), `E_INVALID_QUALIFIERS`, (中文(简体) ), `E_BAD_PERCENT_ENCODING`, (中文(简体) ), `E_DISALLOWED_PERCENT_ENCODING`, (中文(简体) ), `E_INVALID_SUBPATH` |
| 构成部分所需经费`namespace`, (中文(简体) ), `name`, (中文(简体) ), `version`, (中文(简体) ), `subpath`(中文(简体) ) | `specification/types/*-definition.json` (单位:千美元)`*_definition.requirement`(中文(简体) ) | 要求/禁止/可选语义每种类型 | `E_REQUIRED_COMPONENT`, (中文(简体) ), `E_PROHIBITED_COMPONENT`, (中文(简体) ), `E_MISSING_NAME`, (中文(简体) ), `E_MISSING_VERSION` |
| 特征限制和正常化 | `specification/types/*-definition.json` (单位:千美元)`permitted_characters`, (中文(简体) ), `normalization_rules`, (中文(简体) ), `case_sensitive`(中文(简体) ) | 在验证和建造运河之前适用案例和正常化规则 | `E_PERMITTED_CHARACTERS`, (中文(简体) ), `E_INVALID_CHARACTER` |
| 按类型列出合格名单 | `specification/types/*-definition.json` (单位:千美元)`qualifiers_definition`(中文(简体) ) | 拒绝未知的修饰键, 但全局/ spec-compat 策略键除外 | `E_UNKNOWN_QUALIFIER` |
| 定性值 | 严格政策 | 除非明确允许,否则多值限定语被否决(`checksum`(中文(简体) ) | `E_MULTIVALUE_QUALIFIER`, (中文(简体) ), `E_INVALID_QUALIFIER_VALUE`, (中文(简体) ), `E_CHECKSUM_MISSING_ALGORITHM`, (中文(简体) ), `E_CHECKSUM_INVALID_DIGEST_FOR_ALGORITHM` |
| 所需限定词 | `specification/types/*-definition.json` (单位:千美元)`qualifiers_definition.requirement`(中文(简体) ) | 缺少必要的修饰符在解析和构建流程中被拒绝 | `E_REQUIRED_QUALIFIER` |
| 类型特定语义规则 | 类型规格和执行政策 | CPAN 大写作者命名空间和无 `::` 分布式名称; Swift 主机/所有者命名空间形状 | `E_CPAN_NAMESPACE`, (中文(简体) ), `E_CPAN_NAME`, (中文(简体) ), `E_SWIFT_NAMESPACE` |
| 类型安全 | 从定义中生成的类型登记册 | 包含不匹配检测的每类类型已锁定的解析 | `E_TYPE_MISMATCH` |

### 规范化 opcode 模型

规范化规则 : `specification/types/*-definition.json` 编译为 opcode 数组 `generated/type-rules.js`。 。 。 . `index.js` 应用这些 opcode 顺序通过 `applyNormalizationRules(...)` 并拒绝未知的密码 `E_UNKNOWN_NORMALIZATION_OP`。 。 。 .

当前拼接语义 :

-   `to_lowercase`: 小写全部值.
-   `apply_kebab_case`: 崩溃非全美运行到 `-` 和修剪外接线(保留字母大小写).
-   `replace_underscore_with_dash`: 替换全部 `_` 与 `-`。 。 。 .
-   `replace_dot_with_underscore`: 替换全部 `.` 与 `_`。 。 。 .
-   `replace_non_alnum_with_underscore`: 小写后替换每个非 `[a-z0-9]` 字符为 `_`。 。 。 .

Opcode 优先级在生成器中解决(`scripts/generate-type-rules.mjs`因此,发射的阵列在再生过程中具有决定性. 对于相互冲突的规则,在运行时间之前适用优先。 PyPI 名称示例 :

1.  `replace_dot_with_underscore`
2.  `replace_underscore_with_dash`

这保证了对混血儿的宽容 `A_B-C.D~x` - > (中文) `a-b-c-d~x`。 。 。 .

### 已知的正常化限制

-   `alpm.version` 包括一项正常化规则,即: `vercmp(8)` 语义.
-   此库目前保存 `alpm` 支持而不应用版本正常化逻辑.
-   解析和验证仍在运行 `alpm`,但无额外 `vercmp`\-基于重写适用于版本值.

## 测试命令

```bash
pnpm test
pnpm test:base
pnpm test:typed
pnpm test:typed:all
pnpm test:mutation
pnpm test:fuzz
```

### 决定模糊控制

```bash
PURL_FUZZ_SEED=1337
PURL_FUZZ_CASES=300
PURL_FUZZ_HOPS=10
PURL_FUZZ_MUTATION_CASES=200
PURL_TYPED_FUZZ_SEED=4242
PURL_TYPED_FUZZ_CASES=240
PURL_TYPED_FUZZ_HOPS=8
pnpm test:fuzz
```

覆盖范围包括:

-   基础固定兼容性测试
-   类型和建筑工覆盖所有登记类型
-   对抗性严格政策测试
-   根据类型定义生成的由变异驱动的负面测试
-   具有可再生种子的确定性模糊和突变模糊

## 支助政策

-   运行时间支持: 节点 `>=20`组合键 `>=1.0.0`,德诺 `>=1.40.0`
-   CI 测试矩阵( 节点) : `20.x`, (中文(简体) ), `22.x`, (中文(简体) ), `24.x`, (中文(简体) ), `25.x`
-   CI 运行时间烟雾覆盖率: Bun和Deno
-   构建和发布路径:节点 `24.x` npm 信任的出版 + 来源

## 许可证

MIT许可证。 见 [自由主义](https://npmcn.com/package/%40cdxgen/cdx-purl/LICENSE) 详细情况.

## 常见问题

### @cdxgen/cdx-purl 是什么？

纯 JavaScript 软件包- url 解析器和构建器

### 如何安装 @cdxgen/cdx-purl？

在项目目录运行 npm install @cdxgen/cdx-purl，或使用 pnpm add / yarn add / bun add。

### @cdxgen/cdx-purl 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/cdxgen\_\_cdx-purl 是否存在。

### @cdxgen/cdx-purl 支持 ESM 还是 CommonJS？

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

### @cdxgen/cdx-purl 需要什么版本的 Node\.js？

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

### @cdxgen/cdx-purl 可以商用吗？

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

### @cdxgen/cdx-purl 的下载量有多少？

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

### @cdxgen/cdx-purl 还在维护吗？

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

