@tracepass/dpp-identifiers 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product.js","sourceRoot":"","sources":["../src/product.ts"],"names":[],"mappings":"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"}
package/dist/uri.d.ts ADDED
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Identifier URI construction and parsing for the EN 18219 resolver path.
3
+ *
4
+ * identifierToUri — build a resolver URL from any ProductIdentifier.
5
+ * gs1 → Digital Link path `/01/<gtin14>/21/<encoded-serial>`
6
+ * iso15459 → `/<agency>/<encoded-primaryId>[/<encoded-serial>]`
7
+ * iec61406 / did / doi → null (they carry their own canonical URL)
8
+ *
9
+ * identifierOwnUrl — the identifier's own URL form, when it has one.
10
+ * iec61406 → the Identification Link uri
11
+ * doi → `https://doi.org/<doi>`
12
+ * did → null (resolution is method-specific; the DID itself is not a URL)
13
+ * gs1/iso15459 → null (no URL intrinsic to the identifier; use identifierToUri)
14
+ *
15
+ * parseResolverPath — inverse of identifierToUri, for gs1 and iso15459 only.
16
+ * Leading digits in the first path segment → GS1 AI path (AI 01 + AI 21).
17
+ * A 1–3 char uppercase `[A-Z][A-Z0-9]{0,2}` first segment → ISO/IEC 15459 agency.
18
+ * Otherwise → null (e.g. "/about/team", "/api/v1", lowercase-agency paths).
19
+ *
20
+ * ⚠️ Consumers MUST match their own reserved app routes (/p, /api, /docs, …)
21
+ * BEFORE delegating to parseResolverPath. A 1–3 char uppercase route (e.g. /P)
22
+ * is indistinguishable from a 1-char ISO/IEC 15459 agency code — the function
23
+ * cannot tell them apart and will return a spurious iso15459 result. Pre-empt
24
+ * all known app routes first, then call parseResolverPath for the remainder.
25
+ *
26
+ * identifierKey — a canonical string for deduplication / map keys.
27
+ * gs1 → `gs1:<gtin14>:<serial>`
28
+ * iso15459 → `iso15459:<agency>:<primaryId>:<serial|>` (empty string if no serial)
29
+ * iec61406 → `iec61406:<uri>`
30
+ * did → `did:<did>`
31
+ * doi → `doi:<lowercased-bare>`
32
+ *
33
+ * Note on open question: does the iso15459 path form match the ISO/IEC 18975
34
+ * resolver path that EN 18219 scheme 1 references? ISO/IEC 18975 is paywalled
35
+ * and unread. Until that is resolved, the path here is a TracePass resolver
36
+ * route, not a claim of conformance with 18975. The identifier's own `raw`/`uri`
37
+ * field is its authoritative form.
38
+ */
39
+ import type { ProductIdentifier } from "@tracepass/dpp-types";
40
+ /**
41
+ * Build a resolver URL for a `ProductIdentifier`.
42
+ *
43
+ * @param id - the (validated, normalised) identifier
44
+ * @param resolverBase - the resolver's bare domain, e.g. `"id.example.com"`
45
+ * @returns the full resolver URL, or `null` for schemes that carry their own URL
46
+ */
47
+ export declare function identifierToUri(id: ProductIdentifier, resolverBase: string): string | null;
48
+ /**
49
+ * Return the identifier's own canonical URL, when it has one.
50
+ * `null` when the identifier type does not define its own URL form.
51
+ */
52
+ export declare function identifierOwnUrl(id: ProductIdentifier): string | null;
53
+ /**
54
+ * Parse a resolver path back into a `ProductIdentifier`.
55
+ *
56
+ * Handles the two schemes emitted by `identifierToUri`:
57
+ * - `/01/<gtin14>/21/<encoded-serial>` → `{scheme: "gs1", …}`
58
+ * - `/<AGENCY>/<encoded-primaryId>[/<encoded-serial>]` → `{scheme: "iso15459", …}`
59
+ *
60
+ * Returns `null` for any path that doesn't match, including:
61
+ * - "/about/team" — first segment "about" is 5 chars, exceeds the 3-char limit
62
+ * - "/api/v1/…" — first segment "api" is lowercase
63
+ * - "/mh/ABC" — first segment "mh" is lowercase (ISO/IEC 15459 agency codes
64
+ * are always uppercase per EN 18219; `identifierToUri` always
65
+ * emits uppercase)
66
+ *
67
+ * ⚠️ The agency-code shape check (1–3 chars, `[A-Z][A-Z0-9]{0,2}`) cannot
68
+ * distinguish a short app route from a valid agency code. For example, "/P/x"
69
+ * is indistinguishable from a passport with agency "P" and primaryId "x" — it
70
+ * will parse. Consumers MUST match their own reserved routes (/P, /API, /DOCS, …)
71
+ * BEFORE delegating to `parseResolverPath`.
72
+ *
73
+ * The first path segment determines the scheme: a digit-only segment is a GS1
74
+ * Application Identifier (we only emit `01`); a 1–3 char uppercase segment is
75
+ * an ISO/IEC 15459 issuing agency code.
76
+ */
77
+ export declare function parseResolverPath(path: string): ProductIdentifier | null;
78
+ /**
79
+ * A canonical string key for deduplication and map-key use.
80
+ *
81
+ * The key is stable and unique within its scheme domain. DOI keys are
82
+ * lower-cased (DOI identifiers are case-insensitive per the DOI Handbook).
83
+ */
84
+ export declare function identifierKey(id: ProductIdentifier): string;
85
+ //# sourceMappingURL=uri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../src/uri.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA8B1F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAwBrE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAmDxE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,CAuB3D"}
package/dist/uri.js ADDED
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Identifier URI construction and parsing for the EN 18219 resolver path.
3
+ *
4
+ * identifierToUri — build a resolver URL from any ProductIdentifier.
5
+ * gs1 → Digital Link path `/01/<gtin14>/21/<encoded-serial>`
6
+ * iso15459 → `/<agency>/<encoded-primaryId>[/<encoded-serial>]`
7
+ * iec61406 / did / doi → null (they carry their own canonical URL)
8
+ *
9
+ * identifierOwnUrl — the identifier's own URL form, when it has one.
10
+ * iec61406 → the Identification Link uri
11
+ * doi → `https://doi.org/<doi>`
12
+ * did → null (resolution is method-specific; the DID itself is not a URL)
13
+ * gs1/iso15459 → null (no URL intrinsic to the identifier; use identifierToUri)
14
+ *
15
+ * parseResolverPath — inverse of identifierToUri, for gs1 and iso15459 only.
16
+ * Leading digits in the first path segment → GS1 AI path (AI 01 + AI 21).
17
+ * A 1–3 char uppercase `[A-Z][A-Z0-9]{0,2}` first segment → ISO/IEC 15459 agency.
18
+ * Otherwise → null (e.g. "/about/team", "/api/v1", lowercase-agency paths).
19
+ *
20
+ * ⚠️ Consumers MUST match their own reserved app routes (/p, /api, /docs, …)
21
+ * BEFORE delegating to parseResolverPath. A 1–3 char uppercase route (e.g. /P)
22
+ * is indistinguishable from a 1-char ISO/IEC 15459 agency code — the function
23
+ * cannot tell them apart and will return a spurious iso15459 result. Pre-empt
24
+ * all known app routes first, then call parseResolverPath for the remainder.
25
+ *
26
+ * identifierKey — a canonical string for deduplication / map keys.
27
+ * gs1 → `gs1:<gtin14>:<serial>`
28
+ * iso15459 → `iso15459:<agency>:<primaryId>:<serial|>` (empty string if no serial)
29
+ * iec61406 → `iec61406:<uri>`
30
+ * did → `did:<did>`
31
+ * doi → `doi:<lowercased-bare>`
32
+ *
33
+ * Note on open question: does the iso15459 path form match the ISO/IEC 18975
34
+ * resolver path that EN 18219 scheme 1 references? ISO/IEC 18975 is paywalled
35
+ * and unread. Until that is resolved, the path here is a TracePass resolver
36
+ * route, not a claim of conformance with 18975. The identifier's own `raw`/`uri`
37
+ * field is its authoritative form.
38
+ */
39
+ /**
40
+ * Build a resolver URL for a `ProductIdentifier`.
41
+ *
42
+ * @param id - the (validated, normalised) identifier
43
+ * @param resolverBase - the resolver's bare domain, e.g. `"id.example.com"`
44
+ * @returns the full resolver URL, or `null` for schemes that carry their own URL
45
+ */
46
+ export function identifierToUri(id, resolverBase) {
47
+ const base = resolverBase.replace(/\/+$/, "");
48
+ switch (id.scheme) {
49
+ case "gs1":
50
+ return (`https://${base}/01/${id.gtin}/21/${encodeURIComponent(id.serialNumber)}`);
51
+ case "iso15459": {
52
+ const parts = [
53
+ encodeURIComponent(id.issuingAgencyCode),
54
+ encodeURIComponent(id.primaryId),
55
+ ];
56
+ if (id.serial)
57
+ parts.push(encodeURIComponent(id.serial));
58
+ return `https://${base}/${parts.join("/")}`;
59
+ }
60
+ case "iec61406":
61
+ case "did":
62
+ case "doi":
63
+ // These schemes carry their own canonical URL; use identifierOwnUrl.
64
+ return null;
65
+ default: {
66
+ const _exhaustive = id;
67
+ void _exhaustive;
68
+ return null;
69
+ }
70
+ }
71
+ }
72
+ /**
73
+ * Return the identifier's own canonical URL, when it has one.
74
+ * `null` when the identifier type does not define its own URL form.
75
+ */
76
+ export function identifierOwnUrl(id) {
77
+ switch (id.scheme) {
78
+ case "iec61406":
79
+ return id.uri;
80
+ case "doi":
81
+ // DOI is always stored as bare form; resolve via the global DOI resolver.
82
+ return `https://doi.org/${id.doi}`;
83
+ case "did":
84
+ // DID resolution is method-specific; the DID itself is not a URL.
85
+ return null;
86
+ case "gs1":
87
+ case "iso15459":
88
+ // These have no intrinsic URL; they need a resolver. Use identifierToUri.
89
+ return null;
90
+ default: {
91
+ const _exhaustive = id;
92
+ void _exhaustive;
93
+ return null;
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * Parse a resolver path back into a `ProductIdentifier`.
99
+ *
100
+ * Handles the two schemes emitted by `identifierToUri`:
101
+ * - `/01/<gtin14>/21/<encoded-serial>` → `{scheme: "gs1", …}`
102
+ * - `/<AGENCY>/<encoded-primaryId>[/<encoded-serial>]` → `{scheme: "iso15459", …}`
103
+ *
104
+ * Returns `null` for any path that doesn't match, including:
105
+ * - "/about/team" — first segment "about" is 5 chars, exceeds the 3-char limit
106
+ * - "/api/v1/…" — first segment "api" is lowercase
107
+ * - "/mh/ABC" — first segment "mh" is lowercase (ISO/IEC 15459 agency codes
108
+ * are always uppercase per EN 18219; `identifierToUri` always
109
+ * emits uppercase)
110
+ *
111
+ * ⚠️ The agency-code shape check (1–3 chars, `[A-Z][A-Z0-9]{0,2}`) cannot
112
+ * distinguish a short app route from a valid agency code. For example, "/P/x"
113
+ * is indistinguishable from a passport with agency "P" and primaryId "x" — it
114
+ * will parse. Consumers MUST match their own reserved routes (/P, /API, /DOCS, …)
115
+ * BEFORE delegating to `parseResolverPath`.
116
+ *
117
+ * The first path segment determines the scheme: a digit-only segment is a GS1
118
+ * Application Identifier (we only emit `01`); a 1–3 char uppercase segment is
119
+ * an ISO/IEC 15459 issuing agency code.
120
+ */
121
+ export function parseResolverPath(path) {
122
+ // Normalise: strip leading slash, strip query/fragment
123
+ const clean = path.replace(/^\//, "").split("?")[0].split("#")[0];
124
+ if (!clean)
125
+ return null;
126
+ const segments = clean.split("/");
127
+ if (segments.length < 2)
128
+ return null;
129
+ const first = segments[0];
130
+ if (!first)
131
+ return null;
132
+ // GS1 AI path: leading all-digit segment
133
+ if (/^\d+$/.test(first)) {
134
+ // Only handle the /01/<gtin>/21/<serial> form we emit.
135
+ if (first !== "01" || segments.length < 4 || segments[2] !== "21")
136
+ return null;
137
+ const gtin = segments[1];
138
+ let serial;
139
+ try {
140
+ serial = decodeURIComponent(segments[3]);
141
+ }
142
+ catch {
143
+ // Malformed percent-sequence (e.g. bare %) → treat as not found, not 500.
144
+ return null;
145
+ }
146
+ return { scheme: "gs1", gtin, serialNumber: serial };
147
+ }
148
+ // ISO/IEC 15459 agency path: exactly 1–3 chars, uppercase [A-Z][A-Z0-9]{0,2}.
149
+ // identifierToUri always emits uppercase agency codes; lowercase paths are
150
+ // rejected (the caller may uppercase and retry if needed).
151
+ if (/^[A-Z][A-Z0-9]{0,2}$/.test(first)) {
152
+ let issuingAgencyCode;
153
+ let primaryId;
154
+ let serial;
155
+ try {
156
+ issuingAgencyCode = decodeURIComponent(first).toUpperCase();
157
+ primaryId = decodeURIComponent(segments[1]);
158
+ serial = segments[2] ? decodeURIComponent(segments[2]) : undefined;
159
+ }
160
+ catch {
161
+ return null;
162
+ }
163
+ const raw = [issuingAgencyCode, primaryId, serial].filter(Boolean).join("/");
164
+ return {
165
+ scheme: "iso15459",
166
+ issuingAgencyCode,
167
+ primaryId,
168
+ serial,
169
+ raw,
170
+ };
171
+ }
172
+ return null;
173
+ }
174
+ /**
175
+ * A canonical string key for deduplication and map-key use.
176
+ *
177
+ * The key is stable and unique within its scheme domain. DOI keys are
178
+ * lower-cased (DOI identifiers are case-insensitive per the DOI Handbook).
179
+ */
180
+ export function identifierKey(id) {
181
+ switch (id.scheme) {
182
+ case "gs1":
183
+ return `gs1:${id.gtin}:${id.serialNumber}`;
184
+ case "iso15459":
185
+ return `iso15459:${id.issuingAgencyCode}:${id.primaryId}:${id.serial ?? ""}`;
186
+ case "iec61406":
187
+ return `iec61406:${id.uri}`;
188
+ case "did":
189
+ return `did:${id.did}`;
190
+ case "doi":
191
+ return `doi:${id.doi.toLowerCase()}`;
192
+ default: {
193
+ const _exhaustive = id;
194
+ void _exhaustive;
195
+ return `unknown:${JSON.stringify(id)}`;
196
+ }
197
+ }
198
+ }
199
+ //# sourceMappingURL=uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../src/uri.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@tracepass/dpp-identifiers",
3
+ "version": "0.9.0",
4
+ "description": "Validate and parse EU Digital Product Passport identifiers (EN 18219) — GS1 Digital Link, ISO/IEC 15459, IEC 61406, DID, DOI. Pure functions, no network, no third-party runtime dependencies.",
5
+ "keywords": [
6
+ "digital-product-passport",
7
+ "dpp",
8
+ "en18219",
9
+ "espr",
10
+ "gs1",
11
+ "gtin",
12
+ "iso15459",
13
+ "iec61406",
14
+ "did",
15
+ "doi",
16
+ "identifier",
17
+ "eu-regulation",
18
+ "circular-economy"
19
+ ],
20
+ "license": "Apache-2.0",
21
+ "author": "TracePass LTD (https://tracepass.eu)",
22
+ "homepage": "https://github.com/malinoto/tracepass-open/tree/main/packages/dpp-identifiers#readme",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/malinoto/tracepass-open.git",
26
+ "directory": "packages/dpp-identifiers"
27
+ },
28
+ "bugs": "https://github.com/malinoto/tracepass-open/issues",
29
+ "type": "module",
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js"
36
+ }
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "README.md",
41
+ "LICENSE"
42
+ ],
43
+ "sideEffects": false,
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "provenance": true
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.build.json",
50
+ "clean": "rm -rf dist"
51
+ },
52
+ "dependencies": {
53
+ "@tracepass/dpp-types": "^0.9.0",
54
+ "@tracepass/gs1-utils": "^0.9.0"
55
+ },
56
+ "devDependencies": {
57
+ "typescript": "^5.6.3"
58
+ },
59
+ "engines": {
60
+ "node": ">=18"
61
+ }
62
+ }