@cdxgen/cdx-purl

中文文档
0.0.6发布于 2026/09/30MITES Module零依赖构建来源已验证近 30 天下载 5万

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

中文使用文档
文档目录18 节
  1. 安装
  2. 快开始
  3. API 密码
  4. 验证行为(按设计限制)
  5. 保留字符必须是%- 编码
  6. 未知的修饰键被拒绝
  7. 只接受明确允许的多值限定符
  8. 校验和值通过算法验证
  9. 要求的和被禁的类别字段得到执行
  10. 虚空模块路径没有命名空间被接受
  11. 构建器和对象流中的子路径验证
  12. 支持的 purl 类型
  13. 规范化 opcode 模型
  14. 已知的正常化限制
  15. 测试命令
  16. 决定模糊控制
  17. 支助政策
  18. 许可证

cdx- purl (英语)

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

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

AI-DECLARATION: auto

安装

pnpm add @cdxgen/cdx-purl
npm install @cdxgen/cdx-purl
bun add @cdxgen/cdx-purl
deno add npm:@cdxgen/cdx-purl

快开始

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

const parsed = parse("pkg:npm/%40angular/[email protected]");
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 又解码了.

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

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

parse("pkg:npm/[email protected]+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+Servercdx-purl 拒绝这些 投入;其逃出的形式产生准确的上游期望 (单位:千美元)test/reserved-character-errors.test.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,
});

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

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,或选定算法错误长度的文摘.

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

// success: valid lengths for each algorithm
parse(
  "pkg:generic/[email protected]?checksum=" +
    "sha1:da39a3ee5e6b4b0d3255bfef95601890afd80709," +
    "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
);

// throws E_CHECKSUM_MISSING_ALGORITHM
parse(
  "pkg:generic/[email protected]?checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709",
);

// throws E_CHECKSUM_INVALID_DIGEST_FOR_ALGORITHM (wrong length)
parse("pkg:generic/[email protected]?checksum=sha256:abc123");

// throws E_CHECKSUM_INVALID_DIGEST_FOR_ALGORITHM (non-hex)
parse(
  "pkg:generic/[email protected]?checksum=" +
    "sha1:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",
);

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

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 标签)时它们会被接受. 不类似主机的去名仍需要命名空间 .

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

parse("pkg:golang/[email protected]"); // 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。 。 。 .

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/[email protected]#//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-基于重写适用于版本值.

测试命令

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

决定模糊控制

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许可证。 见 自由主义 详细情况.

版本与发布记录

@cdxgen/cdx-purl 共发布 5 个版本,首次发布于 2026/04/26;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.0.6latest2026/09/301 个月前
0.0.52026/08/053 个月前
0.0.42026/07/313 个月前
0.0.32026/04/266 个月前
0.0.12026/04/266 个月前

关于 @cdxgen/cdx-purl 的常见问题

@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 和提交记录判断。