@tracepass/dpp-epcis 0.1.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,38 @@
1
+ /**
2
+ * Lightweight structural validation of TracePass-emitted EPCIS
3
+ * documents.
4
+ *
5
+ * This is NOT a full EPCIS 2.0 JSON Schema validator — the official
6
+ * schema is large and a full `ajv`-based validation belongs in the
7
+ * conformance self-test script (`scripts/epcis-conformance-check.ts`),
8
+ * run against a live endpoint, not on every request. What this module
9
+ * does is a fast, dependency-free sanity check the document builder
10
+ * and tests can call to catch the structural mistakes that would make
11
+ * a document obviously non-conformant:
12
+ * - missing the EPCIS envelope keys
13
+ * - an event without the mandatory `type` / `eventTime` /
14
+ * `eventTimeZoneOffset`
15
+ * - an event with neither `epcList` nor `outputEPCList` (an event
16
+ * about no object is meaningless)
17
+ *
18
+ * It is deliberately permissive about everything else — the goal is
19
+ * "would a strict consumer immediately reject this", not "is every
20
+ * optional field perfect".
21
+ *
22
+ * Pure. Unit-tested in tests/epcis/validate.test.ts.
23
+ */
24
+ /** A single problem found in a document. `path` locates it. */
25
+ export interface EpcisValidationIssue {
26
+ path: string;
27
+ message: string;
28
+ }
29
+ export interface EpcisValidationResult {
30
+ valid: boolean;
31
+ issues: EpcisValidationIssue[];
32
+ }
33
+ /**
34
+ * Validate a full EPCISDocument structure. Returns `{ valid, issues }`
35
+ * — `valid` is true only when `issues` is empty.
36
+ */
37
+ export declare function validateEpcisDocument(doc: unknown): EpcisValidationResult;
38
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,+DAA+D;AAC/D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AA4KD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CA2CzE"}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Lightweight structural validation of TracePass-emitted EPCIS
3
+ * documents.
4
+ *
5
+ * This is NOT a full EPCIS 2.0 JSON Schema validator — the official
6
+ * schema is large and a full `ajv`-based validation belongs in the
7
+ * conformance self-test script (`scripts/epcis-conformance-check.ts`),
8
+ * run against a live endpoint, not on every request. What this module
9
+ * does is a fast, dependency-free sanity check the document builder
10
+ * and tests can call to catch the structural mistakes that would make
11
+ * a document obviously non-conformant:
12
+ * - missing the EPCIS envelope keys
13
+ * - an event without the mandatory `type` / `eventTime` /
14
+ * `eventTimeZoneOffset`
15
+ * - an event with neither `epcList` nor `outputEPCList` (an event
16
+ * about no object is meaningless)
17
+ *
18
+ * It is deliberately permissive about everything else — the goal is
19
+ * "would a strict consumer immediately reject this", not "is every
20
+ * optional field perfect".
21
+ *
22
+ * Pure. Unit-tested in tests/epcis/validate.test.ts.
23
+ */
24
+ /** EPCIS event types EPCIS 2.0 defines. */
25
+ const KNOWN_EVENT_TYPES = new Set([
26
+ "ObjectEvent",
27
+ "AggregationEvent",
28
+ "TransformationEvent",
29
+ "TransactionEvent",
30
+ "AssociationEvent",
31
+ ]);
32
+ /** ISO-8601-ish instant: date + time + offset. Loose by design. */
33
+ const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/;
34
+ /** Timezone offset: `Z`-free `+HH:MM` / `-HH:MM`, or `+00:00`. */
35
+ const TZ_OFFSET = /^[+-]\d{2}:\d{2}$/;
36
+ /**
37
+ * Standard GS1 CBV 2.0 bizStep short-form values that OpenEPCIS accepts
38
+ * without a URI. The EPCIS 2.0 spec allows two shapes:
39
+ * 1. A short token from this enum (`"shipping"`, `"receiving"`, …)
40
+ * 2. A fully-qualified URI (any `https://…` or `urn:…`)
41
+ *
42
+ * OpenEPCIS rejects anything that's neither — found 2026-05-23 when
43
+ * test events with arbitrary tokens like `prod_smoke_test` got routed
44
+ * to the `epcis-event-validated-failure` Kafka topic and silently
45
+ * dropped (no error surfaced back to the client).
46
+ *
47
+ * Source: GS1 CBV 2.0 Table 7-2 (bizStep). Updated when CBV ratifies
48
+ * new bizSteps — rare; the list has been stable since CBV 2.0 (2022).
49
+ */
50
+ const CBV_BIZSTEP_TOKENS = new Set([
51
+ "accepting", "arriving", "assembling", "collecting", "commissioning",
52
+ "consigning", "creating_class_instance", "cycle_counting",
53
+ "decommissioning", "departing", "destroying", "disassembling",
54
+ "dispensing", "encoding", "entering_exiting", "holding", "inspecting",
55
+ "installing", "killing", "loading", "other", "packing", "picking",
56
+ "receiving", "removing", "repackaging", "repairing", "replacing",
57
+ "reserving", "retail_selling", "sampling", "sensor_reporting",
58
+ "shipping", "staging_outbound", "stock_taking", "stocking", "storing",
59
+ "transporting", "unloading", "unpacking", "void_shipping",
60
+ ]);
61
+ /**
62
+ * Standard GS1 CBV 2.0 disposition short-form values. Same accept-OR-URI
63
+ * rule as bizStep above.
64
+ *
65
+ * Source: GS1 CBV 2.0 Table 7-3 (disposition).
66
+ */
67
+ const CBV_DISPOSITION_TOKENS = new Set([
68
+ "active", "available", "completeness_inferred", "completeness_verified",
69
+ "conformant", "container_closed", "container_open", "damaged", "destroyed",
70
+ "dispensed", "disposed", "encoded", "expired", "in_progress", "in_transit",
71
+ "inactive", "mismatch_instance", "mismatch_class", "mismatch_quantity",
72
+ "needs_replacement", "no_pedigree_match", "non_conformant", "non_sellable_other",
73
+ "partially_dispensed", "recalled", "reserved", "retail_sold", "returned",
74
+ "sellable_accessible", "sellable_not_accessible", "stolen", "unavailable",
75
+ "unknown",
76
+ ]);
77
+ /**
78
+ * True when `value` is a recognised CBV short-form OR looks like a URI.
79
+ * Permissive on URIs — the spec allows any URI (and OpenEPCIS does too).
80
+ *
81
+ * Used by both bizStep + disposition; pass the corresponding token set.
82
+ */
83
+ function isCbvValueOrUri(value, tokens) {
84
+ if (typeof value !== "string" || value.length === 0)
85
+ return false;
86
+ if (tokens.has(value))
87
+ return true;
88
+ // URI check — accept anything that looks like `scheme:path`.
89
+ // Matches `https://ref.gs1.org/cbv/BizStep-shipping`,
90
+ // `urn:epcglobal:cbv:bizstep:shipping`, `tracepass:cbv/bizstep/smelting`.
91
+ return /^[a-z][a-z0-9+.\-]*:\S+$/i.test(value);
92
+ }
93
+ function isObject(v) {
94
+ return typeof v === "object" && v !== null && !Array.isArray(v);
95
+ }
96
+ /**
97
+ * Validate one EPCIS event object. Pushes issues onto `issues` with
98
+ * paths rooted at `basePath`.
99
+ */
100
+ function validateEvent(event, basePath, issues) {
101
+ if (!isObject(event)) {
102
+ issues.push({ path: basePath, message: "event is not an object" });
103
+ return;
104
+ }
105
+ const type = event.type;
106
+ if (typeof type !== "string" || !KNOWN_EVENT_TYPES.has(type)) {
107
+ issues.push({
108
+ path: `${basePath}.type`,
109
+ message: `missing or unknown event type: ${String(type)}`,
110
+ });
111
+ }
112
+ if (typeof event.eventTime !== "string" || !ISO_INSTANT.test(event.eventTime)) {
113
+ issues.push({
114
+ path: `${basePath}.eventTime`,
115
+ message: "missing or non-ISO-8601 eventTime",
116
+ });
117
+ }
118
+ if (typeof event.eventTimeZoneOffset !== "string" ||
119
+ !TZ_OFFSET.test(event.eventTimeZoneOffset)) {
120
+ issues.push({
121
+ path: `${basePath}.eventTimeZoneOffset`,
122
+ message: "missing or malformed eventTimeZoneOffset",
123
+ });
124
+ }
125
+ // An event must be about at least one object. The object-bearing
126
+ // key depends on the event type:
127
+ // - ObjectEvent / TransactionEvent → `epcList`
128
+ // - TransformationEvent → `inputEPCList` / `outputEPCList`
129
+ // - AggregationEvent → `childEPCs` (+ a `parentID`)
130
+ // Omitting `childEPCs` here would reject every valid AggregationEvent.
131
+ const nonEmptyArray = (v) => Array.isArray(v) && v.length > 0;
132
+ const hasObjects = nonEmptyArray(event.epcList) ||
133
+ nonEmptyArray(event.outputEPCList) ||
134
+ nonEmptyArray(event.inputEPCList) ||
135
+ nonEmptyArray(event.childEPCs) ||
136
+ typeof event.parentID === "string";
137
+ if (!hasObjects) {
138
+ issues.push({
139
+ path: basePath,
140
+ message: "event references no objects (no epcList / outputEPCList / inputEPCList / childEPCs / parentID)",
141
+ });
142
+ }
143
+ // CBV vocabulary check on bizStep + disposition. Both are OPTIONAL
144
+ // EPCIS fields — only validate when present. When present, they
145
+ // must be either a known CBV short-form token (`shipping`) or a
146
+ // valid URI (`https://ref.gs1.org/cbv/BizStep-shipping`,
147
+ // `tracepass:cbv/bizstep/smelting`). OpenEPCIS rejects anything
148
+ // else silently into its `epcis-event-validated-failure` Kafka
149
+ // topic — see the comment on CBV_BIZSTEP_TOKENS above for why this
150
+ // is dropped here in the platform instead of waiting for OpenEPCIS
151
+ // to find out.
152
+ if (event.bizStep !== undefined &&
153
+ !isCbvValueOrUri(event.bizStep, CBV_BIZSTEP_TOKENS)) {
154
+ issues.push({
155
+ path: `${basePath}.bizStep`,
156
+ message: `bizStep "${String(event.bizStep)}" is not a CBV short-form token ` +
157
+ `(e.g. "shipping", "receiving") or a URI ` +
158
+ `(e.g. "https://ref.gs1.org/cbv/BizStep-shipping"). ` +
159
+ "OpenEPCIS will reject it.",
160
+ });
161
+ }
162
+ if (event.disposition !== undefined &&
163
+ !isCbvValueOrUri(event.disposition, CBV_DISPOSITION_TOKENS)) {
164
+ issues.push({
165
+ path: `${basePath}.disposition`,
166
+ message: `disposition "${String(event.disposition)}" is not a CBV short-form ` +
167
+ `token (e.g. "in_transit", "active") or a URI. ` +
168
+ "OpenEPCIS will reject it.",
169
+ });
170
+ }
171
+ }
172
+ /**
173
+ * Validate a full EPCISDocument structure. Returns `{ valid, issues }`
174
+ * — `valid` is true only when `issues` is empty.
175
+ */
176
+ export function validateEpcisDocument(doc) {
177
+ const issues = [];
178
+ if (!isObject(doc)) {
179
+ return { valid: false, issues: [{ path: "$", message: "document is not an object" }] };
180
+ }
181
+ if (doc["@context"] === undefined) {
182
+ issues.push({ path: "$.@context", message: "missing @context" });
183
+ }
184
+ if (doc.type !== "EPCISDocument") {
185
+ issues.push({
186
+ path: "$.type",
187
+ message: `type must be "EPCISDocument", got: ${String(doc.type)}`,
188
+ });
189
+ }
190
+ if (doc.schemaVersion !== "2.0") {
191
+ issues.push({
192
+ path: "$.schemaVersion",
193
+ message: `schemaVersion must be "2.0", got: ${String(doc.schemaVersion)}`,
194
+ });
195
+ }
196
+ const body = doc.epcisBody;
197
+ if (!isObject(body)) {
198
+ issues.push({ path: "$.epcisBody", message: "missing or malformed epcisBody" });
199
+ }
200
+ else {
201
+ const eventList = body.eventList;
202
+ if (!Array.isArray(eventList)) {
203
+ issues.push({
204
+ path: "$.epcisBody.eventList",
205
+ message: "eventList must be an array",
206
+ });
207
+ }
208
+ else {
209
+ eventList.forEach((ev, i) => {
210
+ validateEvent(ev, `$.epcisBody.eventList[${i}]`, issues);
211
+ });
212
+ }
213
+ }
214
+ return { valid: issues.length === 0, issues };
215
+ }
216
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@tracepass/dpp-epcis",
3
+ "version": "0.1.0",
4
+ "description": "Map Digital Product Passport data to GS1 EPCIS 2.0 events, with a CBV 2.0 vocabulary extended for steel production steps. Pure functions, no third-party runtime dependencies.",
5
+ "keywords": ["epcis", "epcis-2.0", "gs1", "cbv", "traceability", "digital-product-passport", "dpp", "supply-chain"],
6
+ "license": "Apache-2.0",
7
+ "author": "TracePass LTD (https://tracepass.eu)",
8
+ "homepage": "https://github.com/malinoto/tracepass-open/tree/main/packages/dpp-epcis#readme",
9
+ "repository": { "type": "git", "url": "git+https://github.com/malinoto/tracepass-open.git", "directory": "packages/dpp-epcis" },
10
+ "bugs": "https://github.com/malinoto/tracepass-open/issues",
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } },
15
+ "files": ["dist", "README.md", "LICENSE"],
16
+ "sideEffects": false,
17
+ "publishConfig": { "access": "public" },
18
+ "scripts": { "build": "tsc -p tsconfig.build.json", "clean": "rm -rf dist" },
19
+ "dependencies": { "@tracepass/dpp-types": "^0.1.0", "@tracepass/gs1-utils": "^0.1.0" },
20
+ "devDependencies": { "typescript": "^5.6.3" },
21
+ "engines": { "node": ">=18" }
22
+ }