@tracepass/dpp-identifiers

中文文档
0.19.0发布于 2026/11/03Apache-2.0TypeScriptES Module构建来源已验证

验证和解析欧盟数字产品护照标识符(EN 18219) - GS1数字链接,ISO/IEC 15459, IEC 61406, DID, DOI。纯函数,没有网络,没有第三方运行时依赖。

中文使用文档
文档目录10 节
  1. 验证产品标识符
  2. 支持的方案(EN 18219)
  3. 验证操作员和设备标识符
  4. 构建和解析解析器路径
  5. parseResolverPath 以及消费者的优先购买权
  6. 读取规范标识符
  7. 字符约束(EN 18219条款4.3.2)
  8. 零依赖关系
  9. 超出范围
  10. 许可证
TracePass

@tracepass / dpp-identifiers

根据EN 18219 - GS1, ISO/IEC 15459, IEC 61406, DID, DOI验证和解析欧盟数字产品护照标识符。纯函数,没有网络,没有第三方运行时依赖。

License Dependencies

的一部分 tracepass-open ·由 TracePass


npm install @tracepass/dpp-identifiers

验证EN 18219允许的数字产品护照的任何标识符方案,并且 构建/解析它们映射到的解析器路径。

验证产品标识符

import { validateProductIdentifier } from "@tracepass/dpp-identifiers";
import type { ProductIdentifier } from "@tracepass/dpp-types";

// GS1 Digital Link — normalises GTIN-8/12/13 to 14 digits
const gs1: ProductIdentifier = {
  scheme: "gs1",
  gtin: "5449000000996",   // GTIN-13 — normalised to "05449000000996"
  serialNumber: "SN-001",
};
const r = validateProductIdentifier(gs1);
// r.ok === true; r.value.gtin === "05449000000996"

// ISO/IEC 15459 — required for battery passports (Art. 77(3))
const iso15459: ProductIdentifier = {
  scheme: "iso15459",
  issuingAgencyCode: "MH",   // starts with a letter (GS1 holds the digit range)
  primaryId: "BATT-2026-001",
  raw: "MHBATT-2026-001",
};
validateProductIdentifier(iso15459).ok;  // true

// Battery passports: only gs1 and iso15459 are allowed
validateProductIdentifier(
  { scheme: "did", did: "did:web:example.com", method: "web" },
  { category: "battery" },
).ok;  // false — Battery Regulation Art. 77(3) requires ISO/IEC 15459

支持的方案(EN 18219)

schemeEN 18219笔记
gs1方案1GTIN-8/12/13/14接受;始终归一化为14位数字
iso15459方案1非gs1发行机构。机构代码第一个字符必须是一个字母
iec61406方案2https URL,仅限ascii, RFC 3986有效
did方案3只支持W3C DID核心语法;No method allow-list
doi计划510.<registrant>/<suffix>; 接受 doi: / https://doi.org/ 前缀。 granularity (model | batch | item):第5.6.2(b)条

电池的护照 只接受 gs1 和 iso15459电池法规第77(3)条 要求ISO/IEC 15459,直到授权法案用EN 18219取代它。

LEI不是产品标识符。 EN 18219条款5.1为方案1-5命名 产品;LEI没有出现。将LEI作为 运营商 标识符: { scheme: "iso6523", icd: "0199", value: "<20-char LEI>" }.

验证操作员和设备标识符

import { validateOperatorIdentifier, validateFacilityIdentifier } from "@tracepass/dpp-identifiers";

// ISO 7064 MOD 97-10 check for LEI
validateOperatorIdentifier({ scheme: "iso6523", icd: "0199", value: "5493001KJTIIGC8Y1R12" }).ok;  // true

// GLN (icd 0088) validated with GS1 mod-10
validateOperatorIdentifier({ scheme: "iso6523", icd: "0088", value: "5412345000013" }).ok;  // true

// Facility — the same four schemes as operators (EN 18219 clauses 6.2–6.5)
validateFacilityIdentifier({ scheme: "gln", gln: "5412345000013", extension: "DOCK-1" }).ok;  // true
validateFacilityIdentifier({ scheme: "did", did: "did:web:plant.example.com" }).ok;  // true

构建和解析解析器路径

import { identifierToUri, identifierOwnUrl, parseResolverPath, diQueryCandidateKeys, identifierKey } from "@tracepass/dpp-identifiers";

const gs1 = { scheme: "gs1", gtin: "05449000000996", serialNumber: "SN-001" } as const;

// Build a resolver URL
identifierToUri(gs1, "id.example.com");
// "https://id.example.com/01/05449000000996/21/SN-001"

// Parse back
parseResolverPath("/01/05449000000996/21/SN-001");
// { scheme: "gs1", gtin: "05449000000996", serialNumber: "SN-001" }

// ISO/IEC 15459 → the ISO/IEC 18975 query form (EN 18219 Table B.12)
identifierToUri(
  { scheme: "iso15459", issuingAgencyCode: "QC", primaryId: "ELMI12345", serial: "654321", raw: "QC/ELMI12345/654321" },
  "id.example.com",
);
// "https://id.example.com/?.25P=QCELMI12345&.S=654321"

// A resolver splits .25P back into candidate keys (the agency code is 1–3 characters)
diQueryCandidateKeys("QCELMI12345", "654321");
// ["iso15459:Q:CELMI12345:654321", "iso15459:QC:ELMI12345:654321", "iso15459:QCE:LMI12345:654321"]

// A DOI carries its own URL; no resolver needed
identifierOwnUrl({ scheme: "doi", doi: "10.1234/my-passport", granularity: "model" });
// "https://doi.org/10.1234/my-passport"

// Canonical key for deduplication
identifierKey(gs1);  // "gs1:05449000000996:SN-001"

identifierToUri 返回 null 用于 iec61406, did 和 doi -这些都是自己的 规范URL(使用) identifierOwnUrl 相反)。

parseResolverPath 以及消费者的优先购买权

parseResolverPath 也读得更老 /<AGENCY>/<primaryId>[/<serial>] 路径,也就是URL 已经以那种形式打印出来的一直在解析。 identifierToUri 不再排放二氧化碳。它 执行ISO/IEC 15459机构代码形状:第一个路径段 必须是1-3个大写字母匹配吗 [A-Z][A-Z0-9]{0,2}。这会拒绝常见的应用路由:

路径结果
/about/teamnull -“about”是5个字符
/mh/ABCnull -“mh”是小写的; identifierToUri 总是大写
/MH/BAT-001{scheme: "iso15459", …} ✓
/01/0544…/21/SN{scheme: "gs1", …} ✓

短的大写路由仍然是不明确的。 /P/x 解析为 {issuingAgencyCode: "P", primaryId: "x"} 因为 "P" 是一个有效的1字符机构代码。消费者必须匹配他们的 自己的短应用路线(/P, /Q, /DOCS),然后再委托给 parseResolverPath.

读取规范标识符

在EN 18219之前编写的代码只设置 passport.gs1,以及新的代码集 passport.identifier,使用 resolveProductIdentifier 读现存的:

import { resolveProductIdentifier } from "@tracepass/dpp-identifiers";

const id = resolveProductIdentifier(passport);
// → passport.identifier, or lifted Gs1Identifier from passport.gs1, or undefined
if (!id) throw new Error("No product identifier");

identifier 两个字段都设置时优先。

字符约束(EN 18219条款4.3.2)

所有标识符字段必须使用ISO/IEC 646字符-可打印ASCII (0x20-0x7E)。 非ascii输入被拒绝,并出现错误命名违规字段。

零依赖关系

这个包是基于普通对象的纯TypeScript。它只导入两个兄弟包 (@tracepass/dpp-types 类型和 @tracepass/gs1-utils GTIN/GLN算法), 这两种方法都不添加第三方运行时依赖项。

超出范围

  • EN 18219方案 (RAIN RFID和2D条码)编码相同的ISO/IEC 15459 有限容量载波上的标识符。这是一个数据运营商的问题,而不是一个独立的问题 标识符类型。
  • DID方法允许列表。 第5.4.2条只要求DID核心。是:网络,是:以太和 Did:ebsi是一个推荐(5.4.3)。任何DID核心语法都可以接受。
  • 作为操作符标识符的DID 还需要一个可验证的证书 授权公司登记册(第6.4.2(b)条)。验证器只检查语法。

许可证

apache - 2.0.

版本与发布记录

@tracepass/dpp-identifiers 共发布 18 个版本,首次发布于 2026/09/28;过去 12 个月发布了 18 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.19.0latest2026/11/03今天
0.18.42026/10/303 天前
0.18.32026/10/303 天前
0.18.22026/10/304 天前
0.18.12026/10/304 天前
0.18.02026/10/295 天前

关于 @tracepass/dpp-identifiers 的常见问题

@tracepass/dpp-identifiers 是什么?

验证和解析欧盟数字产品护照标识符(EN 18219) - GS1数字链接,ISO/IEC 15459, IEC 61406, DID, DOI。纯函数,没有网络,没有第三方运行时依赖。

如何安装 @tracepass/dpp-identifiers?

在项目目录运行 npm install @tracepass/dpp-identifiers,或使用 pnpm add / yarn add / bun add。

@tracepass/dpp-identifiers 支持 TypeScript 吗?

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

@tracepass/dpp-identifiers 支持 ESM 还是 CommonJS?

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

@tracepass/dpp-identifiers 需要什么版本的 Node.js?

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

@tracepass/dpp-identifiers 可以商用吗?

@tracepass/dpp-identifiers 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@tracepass/dpp-identifiers 还在维护吗?

最新版本 0.19.0 发布于 2026/11/03(今天);至今共发布 18 个版本,其中过去 12 个月发布了 18 个;首次发布于 2026/09/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。