@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,58 @@
1
+ /**
2
+ * EPCIS 2.0 JSON-LD @context for TracePass-emitted EPCIS documents.
3
+ *
4
+ * An EPCIS 2.0 document is JSON-LD — the same linked-data family as the
5
+ * schema.org JSON-LD the public passport viewer already emits. The
6
+ * @context tells a consumer which vocabularies the document's terms
7
+ * come from.
8
+ *
9
+ * Four vocabularies compose here:
10
+ * 1. The GS1-published EPCIS 2.0 context — the canonical source of
11
+ * `EPCISDocument`, `ObjectEvent`, `eventTime`, `bizStep`, etc.
12
+ * GS1 hosts this at a stable URL; consumers dereference it.
13
+ * 2. The GS1 CBV terms — Core Business Vocabulary (bizSteps,
14
+ * dispositions). Carried inside the EPCIS context for 2.0.
15
+ * 3. `cbv:` alias — so CBV-standard bizStep/disposition values that
16
+ * DO exist in the standard vocabulary are written with the
17
+ * official `cbv:` prefix.
18
+ * 4. `tracepass:` alias — for the terms that are genuinely ours:
19
+ * the custom bizStep URIs we coin for production steps absent
20
+ * from CBV (smelting, rolling, …), and any TracePass-specific
21
+ * annotation we attach to an event.
22
+ *
23
+ * Design call (per the 2026-05-22 EPCIS review, decision [Q2]):
24
+ * production steps that CBV's fixed bizStep list doesn't cover get
25
+ * TracePass-owned vocabulary URIs under `https://tracepass.eu/cbv/`.
26
+ * This is the GS1-sanctioned industry-extension pattern — a valid
27
+ * EPCIS document MAY use bizStep values outside the standard CBV as
28
+ * long as they are URIs. The `tracepass:` alias keeps those URIs
29
+ * compact in the serialized JSON.
30
+ */
31
+ /**
32
+ * The GS1-hosted EPCIS 2.0 JSON-LD context URL. Stable, published by
33
+ * GS1. Consumers dereference it to resolve EPCIS + CBV core terms.
34
+ */
35
+ export const EPCIS_CONTEXT_URL = "https://ref.gs1.org/standards/epcis/2.0.0/epcis-context.jsonld";
36
+ /**
37
+ * Base URI for the TracePass-owned vocabulary. The CBV bizStep
38
+ * extension URIs (`.../cbv/bizstep/smelting`) and any other
39
+ * TracePass-namespaced EPCIS term hang off this. Published as a
40
+ * resolvable JSON-LD vocabulary document — see `cbv.ts` for the
41
+ * term list and `docs`/the vocabulary route for the published doc.
42
+ */
43
+ export const TRACEPASS_VOC_BASE = "https://tracepass.eu/voc/";
44
+ /**
45
+ * The `@context` value placed on every EPCIS document TracePass
46
+ * emits. Array form: the GS1 EPCIS 2.0 context URL first (so its
47
+ * term definitions take precedence), then a local object defining
48
+ * the `tracepass:` alias.
49
+ *
50
+ * The `cbv:` prefix is already defined inside the GS1 EPCIS context,
51
+ * so it is NOT redeclared here — redeclaring it would risk shadowing
52
+ * the official definition.
53
+ */
54
+ export const EPCIS_JSONLD_CONTEXT = [
55
+ EPCIS_CONTEXT_URL,
56
+ { tracepass: TRACEPASS_VOC_BASE },
57
+ ];
58
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC5B,gEAAgE,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAmD;IAClF,iBAAiB;IACjB,EAAE,SAAS,EAAE,kBAAkB,EAAE;CACzB,CAAC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Pure builders for individual EPCIS 2.0 events.
3
+ *
4
+ * Each function takes a TracePass domain object and returns a plain
5
+ * JSON-LD-shaped EPCIS event object. No IO, no template lookups, no
6
+ * @context (the document builder in `document.ts` adds the single
7
+ * shared @context once for the whole document).
8
+ *
9
+ * Three event sources, per the [Q1] decision (all three in Layer A,
10
+ * `supplyChainEvents` first):
11
+ * - `supplyChainEvents` (steel template field 77) → TransformationEvent
12
+ * — a production step consumes inputs and yields the product.
13
+ * - `ServiceEvent` → ObjectEvent — repair/inspection observed
14
+ * on the product after it exists.
15
+ * - `OwnershipTransfer` → ObjectEvent — a custody/ownership change.
16
+ *
17
+ * EPCIS time fields: every event needs `eventTime` (an instant) and
18
+ * `eventTimeZoneOffset` (the offset that instant was recorded in).
19
+ * TracePass stores timestamps as UTC `Date`s with no original offset
20
+ * retained, so we emit `eventTime` in UTC and `eventTimeZoneOffset`
21
+ * as `+00:00`. This is honest — it says "recorded in UTC" — rather
22
+ * than inventing a local offset we never captured.
23
+ *
24
+ * Unit-tested in tests/epcis/event-builders.test.ts.
25
+ */
26
+ import type { ServiceEvent, OwnershipTransfer } from "@tracepass/dpp-types";
27
+ /**
28
+ * One entry of the steel template's `supplyChainEvents` array (field
29
+ * 77). The template's `aiHints.expectedFormat` documents the shape:
30
+ * `{eventType, timestamp, location, country, operator, epcisEventId}`.
31
+ * Every field is optional in practice — supplier-provided data is
32
+ * uneven — so the builder must tolerate partial entries.
33
+ */
34
+ export interface SupplyChainEventInput {
35
+ eventType?: string;
36
+ timestamp?: string;
37
+ location?: string;
38
+ country?: string;
39
+ operator?: string;
40
+ /** A pre-existing EPCIS event id, if the source system already had
41
+ * one. When present we reuse it instead of minting our own. */
42
+ epcisEventId?: string;
43
+ /** GLN of the operating site, when the source provided one. */
44
+ gln?: string;
45
+ }
46
+ /**
47
+ * Convert an ISO-ish timestamp string (or Date) to an EPCIS
48
+ * `eventTime` string. Returns null when the value can't be parsed —
49
+ * the caller drops the event rather than emit an invalid time.
50
+ */
51
+ export declare function toEventTime(value: string | Date | undefined | null): string | null;
52
+ /**
53
+ * Build a TransformationEvent from one `supplyChainEvents` entry.
54
+ *
55
+ * A production step is a transformation: inputs (ore, billet, scrap)
56
+ * become the output product. We rarely hold the input EPCs from
57
+ * supplier data, so `inputEPCList` is usually empty and the event
58
+ * carries only the `outputEPCList` (the product) — still a valid
59
+ * TransformationEvent under EPCIS 2.0.
60
+ *
61
+ * Returns null when the entry has no usable timestamp (an EPCIS event
62
+ * without `eventTime` is invalid).
63
+ */
64
+ export declare function buildTransformationEvent(entry: SupplyChainEventInput, productEpc: string, passportId: string, index: number): Record<string, unknown> | null;
65
+ /**
66
+ * Build an ObjectEvent from a `ServiceEvent` (repair / warranty /
67
+ * maintenance / inspection / replacement / recall).
68
+ *
69
+ * The event is `action: "OBSERVE"` — a service event observes an
70
+ * existing object, it doesn't create or destroy it. Uses `performedAt`
71
+ * for the time; falls back to `createdAt` when the service wasn't
72
+ * marked performed (a scheduled-but-not-done service still has a
73
+ * record time). Returns null when neither timestamp is usable.
74
+ */
75
+ export declare function buildServiceObjectEvent(service: Pick<ServiceEvent, "_id" | "type" | "title" | "performedBy" | "performedAt" | "createdAt" | "warrantyRef">, productEpc: string, passportId: string): Record<string, unknown> | null;
76
+ /**
77
+ * Build an ObjectEvent from an `OwnershipTransfer`. A custody change
78
+ * is an `action: "OBSERVE"` ObjectEvent — the object persists, only
79
+ * its holder changes. We only export *accepted* transfers (a pending
80
+ * or rejected transfer is not a real custody change) — the caller is
81
+ * expected to filter, but the builder also guards.
82
+ *
83
+ * Returns null when the transfer isn't accepted or has no usable time.
84
+ */
85
+ export declare function buildOwnershipObjectEvent(transfer: Pick<OwnershipTransfer, "_id" | "reason" | "transferredAt" | "createdAt" | "status" | "fromName" | "toName">, productEpc: string, passportId: string): Record<string, unknown> | null;
86
+ /**
87
+ * Build the commissioning ObjectEvent — the "this passport went live"
88
+ * event, emitted from `passport.publishedAt`. Every published passport
89
+ * gets exactly one; it anchors the event timeline even when the
90
+ * passport has no supply-chain or service events at all.
91
+ *
92
+ * Returns null when there is no publish timestamp (an unpublished
93
+ * passport shouldn't be EPCIS-exported in the first place).
94
+ */
95
+ export declare function buildCommissioningEvent(publishedAt: Date | string | undefined | null, productEpc: string, passportId: string, manufacturerGln?: string | null): Record<string, unknown> | null;
96
+ /**
97
+ * One supply-chain event a supplier reports through the portal — the
98
+ * plain shape collected from the supplier-facing form (mirrors the
99
+ * Zod `supplierSupplyChainEventSchema`).
100
+ */
101
+ export interface SupplierReportedEvent {
102
+ eventType: string;
103
+ timestamp: string;
104
+ location?: string;
105
+ country?: string;
106
+ gln?: string;
107
+ }
108
+ /**
109
+ * Build an EPCIS ObjectEvent from a supplier-reported supply-chain
110
+ * event. A supplier describing "shipping" / "receiving" / a
111
+ * production step is reporting an observation about the component
112
+ * they supply — an `action: "OBSERVE"` ObjectEvent.
113
+ *
114
+ * `bizStep` is mapped through `mapEventTypeToBizStep`, so both
115
+ * standard CBV steps (shipping, receiving) and production steps
116
+ * (smelting, …) resolve correctly — the same mapping the inline
117
+ * supply-chain events use.
118
+ *
119
+ * `index` makes the minted `eventID` deterministic per (passport,
120
+ * supplier-submission-index), so re-capturing the same submission
121
+ * dedupes rather than piling up duplicates.
122
+ *
123
+ * Returns null when the report has no usable timestamp.
124
+ */
125
+ export declare function buildSupplierObjectEvent(report: SupplierReportedEvent, productEpc: string, passportId: string, index: number): Record<string, unknown> | null;
126
+ //# sourceMappingURL=event-builders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-builders.d.ts","sourceRoot":"","sources":["../src/event-builders.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAY5E;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;oEACgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,qBAAqB,EAC5B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA+BhC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CACX,YAAY,EACZ,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,aAAa,CACvF,EACD,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAuBhC;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,IAAI,CACZ,iBAAiB,EACjB,KAAK,GAAG,QAAQ,GAAG,eAAe,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CACpF,EACD,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA2BhC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,EAC7C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAkBhC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,qBAAqB,EAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA4BhC"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Pure builders for individual EPCIS 2.0 events.
3
+ *
4
+ * Each function takes a TracePass domain object and returns a plain
5
+ * JSON-LD-shaped EPCIS event object. No IO, no template lookups, no
6
+ * @context (the document builder in `document.ts` adds the single
7
+ * shared @context once for the whole document).
8
+ *
9
+ * Three event sources, per the [Q1] decision (all three in Layer A,
10
+ * `supplyChainEvents` first):
11
+ * - `supplyChainEvents` (steel template field 77) → TransformationEvent
12
+ * — a production step consumes inputs and yields the product.
13
+ * - `ServiceEvent` → ObjectEvent — repair/inspection observed
14
+ * on the product after it exists.
15
+ * - `OwnershipTransfer` → ObjectEvent — a custody/ownership change.
16
+ *
17
+ * EPCIS time fields: every event needs `eventTime` (an instant) and
18
+ * `eventTimeZoneOffset` (the offset that instant was recorded in).
19
+ * TracePass stores timestamps as UTC `Date`s with no original offset
20
+ * retained, so we emit `eventTime` in UTC and `eventTimeZoneOffset`
21
+ * as `+00:00`. This is honest — it says "recorded in UTC" — rather
22
+ * than inventing a local offset we never captured.
23
+ *
24
+ * Unit-tested in tests/epcis/event-builders.test.ts.
25
+ */
26
+ import { mapEventTypeToBizStep, mapServiceEventType, mapOwnershipReasonDisposition, CBV_BIZSTEP_URI, } from "./cbv.js";
27
+ import { locationRef, buildEventId } from "./identifiers.js";
28
+ /** EPCIS `eventTimeZoneOffset` for our UTC-stored timestamps. */
29
+ const UTC_OFFSET = "+00:00";
30
+ /**
31
+ * Convert an ISO-ish timestamp string (or Date) to an EPCIS
32
+ * `eventTime` string. Returns null when the value can't be parsed —
33
+ * the caller drops the event rather than emit an invalid time.
34
+ */
35
+ export function toEventTime(value) {
36
+ if (!value)
37
+ return null;
38
+ const d = value instanceof Date ? value : new Date(value);
39
+ if (Number.isNaN(d.getTime()))
40
+ return null;
41
+ return d.toISOString();
42
+ }
43
+ /**
44
+ * Build a TransformationEvent from one `supplyChainEvents` entry.
45
+ *
46
+ * A production step is a transformation: inputs (ore, billet, scrap)
47
+ * become the output product. We rarely hold the input EPCs from
48
+ * supplier data, so `inputEPCList` is usually empty and the event
49
+ * carries only the `outputEPCList` (the product) — still a valid
50
+ * TransformationEvent under EPCIS 2.0.
51
+ *
52
+ * Returns null when the entry has no usable timestamp (an EPCIS event
53
+ * without `eventTime` is invalid).
54
+ */
55
+ export function buildTransformationEvent(entry, productEpc, passportId, index) {
56
+ const eventTime = toEventTime(entry.timestamp);
57
+ if (!eventTime)
58
+ return null;
59
+ const { bizStep } = mapEventTypeToBizStep(entry.eventType ?? "");
60
+ const event = {
61
+ type: "TransformationEvent",
62
+ eventID: entry.epcisEventId || buildEventId(passportId, `sce-${index}`),
63
+ eventTime,
64
+ eventTimeZoneOffset: UTC_OFFSET,
65
+ outputEPCList: [productEpc],
66
+ bizStep,
67
+ };
68
+ const where = locationRef(entry.gln);
69
+ if (where) {
70
+ event.bizLocation = where;
71
+ }
72
+ // Preserve human-readable provenance that has no native EPCIS slot
73
+ // under the tracepass: namespace — a strict consumer ignores it,
74
+ // a TracePass-aware one keeps the operator/country/site label.
75
+ const annotations = {};
76
+ if (entry.eventType)
77
+ annotations["tracepass:processStep"] = entry.eventType;
78
+ if (entry.operator)
79
+ annotations["tracepass:operator"] = entry.operator;
80
+ if (entry.country)
81
+ annotations["tracepass:country"] = entry.country;
82
+ if (entry.location)
83
+ annotations["tracepass:locationName"] = entry.location;
84
+ Object.assign(event, annotations);
85
+ return event;
86
+ }
87
+ /**
88
+ * Build an ObjectEvent from a `ServiceEvent` (repair / warranty /
89
+ * maintenance / inspection / replacement / recall).
90
+ *
91
+ * The event is `action: "OBSERVE"` — a service event observes an
92
+ * existing object, it doesn't create or destroy it. Uses `performedAt`
93
+ * for the time; falls back to `createdAt` when the service wasn't
94
+ * marked performed (a scheduled-but-not-done service still has a
95
+ * record time). Returns null when neither timestamp is usable.
96
+ */
97
+ export function buildServiceObjectEvent(service, productEpc, passportId) {
98
+ const eventTime = toEventTime(service.performedAt ?? service.createdAt);
99
+ if (!eventTime)
100
+ return null;
101
+ const { bizStep, disposition } = mapServiceEventType(service.type);
102
+ const event = {
103
+ type: "ObjectEvent",
104
+ eventID: buildEventId(passportId, `service-${service._id.toString()}`),
105
+ eventTime,
106
+ eventTimeZoneOffset: UTC_OFFSET,
107
+ epcList: [productEpc],
108
+ action: "OBSERVE",
109
+ bizStep,
110
+ disposition,
111
+ "tracepass:serviceType": service.type,
112
+ };
113
+ if (service.title)
114
+ event["tracepass:serviceTitle"] = service.title;
115
+ if (service.performedBy)
116
+ event["tracepass:performedBy"] = service.performedBy;
117
+ if (service.warrantyRef)
118
+ event["tracepass:warrantyRef"] = service.warrantyRef;
119
+ return event;
120
+ }
121
+ /**
122
+ * Build an ObjectEvent from an `OwnershipTransfer`. A custody change
123
+ * is an `action: "OBSERVE"` ObjectEvent — the object persists, only
124
+ * its holder changes. We only export *accepted* transfers (a pending
125
+ * or rejected transfer is not a real custody change) — the caller is
126
+ * expected to filter, but the builder also guards.
127
+ *
128
+ * Returns null when the transfer isn't accepted or has no usable time.
129
+ */
130
+ export function buildOwnershipObjectEvent(transfer, productEpc, passportId) {
131
+ if (transfer.status !== "accepted")
132
+ return null;
133
+ const eventTime = toEventTime(transfer.transferredAt ?? transfer.createdAt);
134
+ if (!eventTime)
135
+ return null;
136
+ const event = {
137
+ type: "ObjectEvent",
138
+ eventID: buildEventId(passportId, `ownership-${transfer._id.toString()}`),
139
+ eventTime,
140
+ eventTimeZoneOffset: UTC_OFFSET,
141
+ epcList: [productEpc],
142
+ action: "OBSERVE",
143
+ bizStep: transfer.reason === "recycling"
144
+ ? CBV_BIZSTEP_URI.decommissioning
145
+ : CBV_BIZSTEP_URI.shipping,
146
+ disposition: mapOwnershipReasonDisposition(transfer.reason),
147
+ "tracepass:ownershipReason": transfer.reason,
148
+ };
149
+ // from/to names are custody parties; no GLN is held for them, so
150
+ // they ride as tracepass: annotations rather than EPCIS sourceList.
151
+ if (transfer.fromName)
152
+ event["tracepass:transferFrom"] = transfer.fromName;
153
+ if (transfer.toName)
154
+ event["tracepass:transferTo"] = transfer.toName;
155
+ return event;
156
+ }
157
+ /**
158
+ * Build the commissioning ObjectEvent — the "this passport went live"
159
+ * event, emitted from `passport.publishedAt`. Every published passport
160
+ * gets exactly one; it anchors the event timeline even when the
161
+ * passport has no supply-chain or service events at all.
162
+ *
163
+ * Returns null when there is no publish timestamp (an unpublished
164
+ * passport shouldn't be EPCIS-exported in the first place).
165
+ */
166
+ export function buildCommissioningEvent(publishedAt, productEpc, passportId, manufacturerGln) {
167
+ const eventTime = toEventTime(publishedAt);
168
+ if (!eventTime)
169
+ return null;
170
+ const event = {
171
+ type: "ObjectEvent",
172
+ eventID: buildEventId(passportId, "commissioning"),
173
+ eventTime,
174
+ eventTimeZoneOffset: UTC_OFFSET,
175
+ epcList: [productEpc],
176
+ action: "ADD",
177
+ bizStep: CBV_BIZSTEP_URI.commissioning,
178
+ };
179
+ const where = locationRef(manufacturerGln);
180
+ if (where)
181
+ event.bizLocation = where;
182
+ return event;
183
+ }
184
+ /**
185
+ * Build an EPCIS ObjectEvent from a supplier-reported supply-chain
186
+ * event. A supplier describing "shipping" / "receiving" / a
187
+ * production step is reporting an observation about the component
188
+ * they supply — an `action: "OBSERVE"` ObjectEvent.
189
+ *
190
+ * `bizStep` is mapped through `mapEventTypeToBizStep`, so both
191
+ * standard CBV steps (shipping, receiving) and production steps
192
+ * (smelting, …) resolve correctly — the same mapping the inline
193
+ * supply-chain events use.
194
+ *
195
+ * `index` makes the minted `eventID` deterministic per (passport,
196
+ * supplier-submission-index), so re-capturing the same submission
197
+ * dedupes rather than piling up duplicates.
198
+ *
199
+ * Returns null when the report has no usable timestamp.
200
+ */
201
+ export function buildSupplierObjectEvent(report, productEpc, passportId, index) {
202
+ const eventTime = toEventTime(report.timestamp);
203
+ if (!eventTime)
204
+ return null;
205
+ const { bizStep } = mapEventTypeToBizStep(report.eventType ?? "");
206
+ const event = {
207
+ type: "ObjectEvent",
208
+ eventID: buildEventId(passportId, `supplier-${index}`),
209
+ eventTime,
210
+ eventTimeZoneOffset: UTC_OFFSET,
211
+ epcList: [productEpc],
212
+ action: "OBSERVE",
213
+ bizStep,
214
+ };
215
+ const where = locationRef(report.gln);
216
+ if (where)
217
+ event.bizLocation = where;
218
+ // Human-readable provenance the supplier gave — no native EPCIS
219
+ // slot, kept under the tracepass: namespace (a strict consumer
220
+ // ignores it, a TracePass-aware one keeps the supplier's labels).
221
+ if (report.eventType)
222
+ event["tracepass:processStep"] = report.eventType;
223
+ if (report.country)
224
+ event["tracepass:country"] = report.country;
225
+ if (report.location)
226
+ event["tracepass:locationName"] = report.location;
227
+ event["tracepass:reportedBySupplier"] = true;
228
+ return event;
229
+ }
230
+ //# sourceMappingURL=event-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-builders.js","sourceRoot":"","sources":["../src/event-builders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * EPC and location identifier construction for EPCIS events.
3
+ *
4
+ * EPCIS events identify objects ("what") and places ("where") with
5
+ * URIs. TracePass already mints GS1 Digital Link URIs for products
6
+ * and validates GLNs for parties — this module turns those into the
7
+ * identifier forms EPCIS events expect.
8
+ *
9
+ * Identifier choices (per EPCIS 2.0, which accepts both URN and
10
+ * Digital Link / constrained-URI forms):
11
+ * - Object identity ("what") — we emit the GS1 Digital Link URI
12
+ * for the product. EPCIS 2.0 explicitly supports Digital Link
13
+ * URIs as EPCs, and it keeps the EPCIS document consistent with
14
+ * the identifier already printed on the passport's QR.
15
+ * - Location identity ("where") — we emit the GS1 SGLN-style
16
+ * Digital Link URI `https://id.gs1.org/414/<gln>` for a party's
17
+ * GLN. `414` is the GS1 Application Identifier for a physical
18
+ * location / party.
19
+ *
20
+ * Pure — no IO. Unit-tested in tests/epcis/identifiers.test.ts.
21
+ */
22
+ /**
23
+ * Build the EPC URI ("what") for a passport. We use the passport's
24
+ * already-minted Digital Link URI verbatim — it is the stable object
25
+ * identifier the rest of the platform (schema.org JSON-LD, tenant
26
+ * export, QR) also uses, so the EPCIS document agrees with them.
27
+ *
28
+ * Returns null when the passport has no Digital Link URI (should not
29
+ * happen for a published passport, but the builder must not throw).
30
+ */
31
+ export declare function passportEpc(digitalLinkUri: string | undefined | null): string | null;
32
+ /**
33
+ * Build a location URI ("where") from a 13-digit GLN. Returns the
34
+ * GS1-canonical `id.gs1.org/414/<gln>` Digital Link form.
35
+ *
36
+ * Returns null when the GLN is absent or fails the mod-10 check —
37
+ * an invalid GLN must not produce a malformed location URI. The
38
+ * caller omits the readPoint/bizLocation rather than emitting a
39
+ * broken one.
40
+ */
41
+ export declare function locationUri(gln: string | undefined | null): string | null;
42
+ /**
43
+ * Build the `id` object EPCIS uses for a readPoint / bizLocation:
44
+ * `{ id: "<uri>" }`. Returns null when the GLN is missing or invalid
45
+ * so the event builder can cleanly omit the key.
46
+ */
47
+ export declare function locationRef(gln: string | undefined | null): {
48
+ id: string;
49
+ } | null;
50
+ /**
51
+ * Build an EPCIS `eventID` URI for one of our exported events. EPCIS
52
+ * 2.0 events carry an optional stable `eventID`; making it stable and
53
+ * deterministic means re-exporting the same passport produces the
54
+ * same event IDs (idempotent consumers can dedupe).
55
+ *
56
+ * Shape: a TracePass URN namespacing the passport id + an event-local
57
+ * discriminator (the source collection + its row id, or a synthetic
58
+ * index for inline supplyChainEvents which have no own id).
59
+ */
60
+ export declare function buildEventId(passportId: string, discriminator: string): string;
61
+ //# sourceMappingURL=identifiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifiers.d.ts","sourceRoot":"","sources":["../src/identifiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAeH;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKpF;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAIzE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAC7B;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAGvB;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,GACpB,MAAM,CAGR"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * EPC and location identifier construction for EPCIS events.
3
+ *
4
+ * EPCIS events identify objects ("what") and places ("where") with
5
+ * URIs. TracePass already mints GS1 Digital Link URIs for products
6
+ * and validates GLNs for parties — this module turns those into the
7
+ * identifier forms EPCIS events expect.
8
+ *
9
+ * Identifier choices (per EPCIS 2.0, which accepts both URN and
10
+ * Digital Link / constrained-URI forms):
11
+ * - Object identity ("what") — we emit the GS1 Digital Link URI
12
+ * for the product. EPCIS 2.0 explicitly supports Digital Link
13
+ * URIs as EPCs, and it keeps the EPCIS document consistent with
14
+ * the identifier already printed on the passport's QR.
15
+ * - Location identity ("where") — we emit the GS1 SGLN-style
16
+ * Digital Link URI `https://id.gs1.org/414/<gln>` for a party's
17
+ * GLN. `414` is the GS1 Application Identifier for a physical
18
+ * location / party.
19
+ *
20
+ * Pure — no IO. Unit-tested in tests/epcis/identifiers.test.ts.
21
+ */
22
+ import { validateGln } from "@tracepass/gs1-utils";
23
+ /**
24
+ * GS1 canonical resolver host. Location URIs are minted against
25
+ * `id.gs1.org` (not our resolver) because a GLN is globally owned by
26
+ * the party, not by TracePass — an EPCIS consumer resolving the
27
+ * location should reach GS1's canonical resolver, not ours.
28
+ */
29
+ const GS1_CANONICAL_HOST = "https://id.gs1.org";
30
+ /** GS1 Application Identifier for a location / party (GLN). */
31
+ const AI_LOCATION = "414";
32
+ /**
33
+ * Build the EPC URI ("what") for a passport. We use the passport's
34
+ * already-minted Digital Link URI verbatim — it is the stable object
35
+ * identifier the rest of the platform (schema.org JSON-LD, tenant
36
+ * export, QR) also uses, so the EPCIS document agrees with them.
37
+ *
38
+ * Returns null when the passport has no Digital Link URI (should not
39
+ * happen for a published passport, but the builder must not throw).
40
+ */
41
+ export function passportEpc(digitalLinkUri) {
42
+ if (typeof digitalLinkUri !== "string" || digitalLinkUri.length === 0) {
43
+ return null;
44
+ }
45
+ return digitalLinkUri;
46
+ }
47
+ /**
48
+ * Build a location URI ("where") from a 13-digit GLN. Returns the
49
+ * GS1-canonical `id.gs1.org/414/<gln>` Digital Link form.
50
+ *
51
+ * Returns null when the GLN is absent or fails the mod-10 check —
52
+ * an invalid GLN must not produce a malformed location URI. The
53
+ * caller omits the readPoint/bizLocation rather than emitting a
54
+ * broken one.
55
+ */
56
+ export function locationUri(gln) {
57
+ if (typeof gln !== "string")
58
+ return null;
59
+ if (!validateGln(gln))
60
+ return null;
61
+ return `${GS1_CANONICAL_HOST}/${AI_LOCATION}/${gln}`;
62
+ }
63
+ /**
64
+ * Build the `id` object EPCIS uses for a readPoint / bizLocation:
65
+ * `{ id: "<uri>" }`. Returns null when the GLN is missing or invalid
66
+ * so the event builder can cleanly omit the key.
67
+ */
68
+ export function locationRef(gln) {
69
+ const uri = locationUri(gln);
70
+ return uri ? { id: uri } : null;
71
+ }
72
+ /**
73
+ * Build an EPCIS `eventID` URI for one of our exported events. EPCIS
74
+ * 2.0 events carry an optional stable `eventID`; making it stable and
75
+ * deterministic means re-exporting the same passport produces the
76
+ * same event IDs (idempotent consumers can dedupe).
77
+ *
78
+ * Shape: a TracePass URN namespacing the passport id + an event-local
79
+ * discriminator (the source collection + its row id, or a synthetic
80
+ * index for inline supplyChainEvents which have no own id).
81
+ */
82
+ export function buildEventId(passportId, discriminator) {
83
+ const safe = discriminator.replace(/[^a-zA-Z0-9._-]/g, "-");
84
+ return `urn:tracepass:epcis:${passportId}:${safe}`;
85
+ }
86
+ //# sourceMappingURL=identifiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../src/identifiers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEhD,+DAA+D;AAC/D,MAAM,WAAW,GAAG,KAAK,CAAC;AAE1B;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,cAAyC;IACnE,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,GAA8B;IACxD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,GAAG,kBAAkB,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC;AACvD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,GAA8B;IAE9B,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,UAAkB,EAClB,aAAqB;IAErB,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,uBAAuB,UAAU,IAAI,IAAI,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Map Digital Product Passport data to GS1 EPCIS 2.0 events.
3
+ *
4
+ * Pure functions over plain objects — no network, no database. Includes a CBV
5
+ * 2.0 (Core Business Vocabulary) mapping, extended with vocabulary URIs for
6
+ * steel production steps that standard CBV does not cover, following the
7
+ * GS1-sanctioned extension pattern.
8
+ */
9
+ export { toEventTime, buildTransformationEvent, buildServiceObjectEvent, buildOwnershipObjectEvent, buildCommissioningEvent, buildSupplierObjectEvent, } from "./event-builders.js";
10
+ export type { SupplyChainEventInput, SupplierReportedEvent, } from "./event-builders.js";
11
+ export { CBV_BIZSTEP_URI, CBV_DISPOSITION_URI, TRACEPASS_BIZSTEP_URI, normalizeStepToken, mapEventTypeToBizStep, mapServiceEventType, mapOwnershipReasonDisposition, } from "./cbv.js";
12
+ export type { BizStepMapping } from "./cbv.js";
13
+ export { validateEpcisDocument } from "./validate.js";
14
+ export type { EpcisValidationIssue, EpcisValidationResult, } from "./validate.js";
15
+ export { passportEpc, locationUri, locationRef, buildEventId } from "./identifiers.js";
16
+ export { EPCIS_CONTEXT_URL, TRACEPASS_VOC_BASE, EPCIS_JSONLD_CONTEXT, } from "./context.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EACV,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Map Digital Product Passport data to GS1 EPCIS 2.0 events.
3
+ *
4
+ * Pure functions over plain objects — no network, no database. Includes a CBV
5
+ * 2.0 (Core Business Vocabulary) mapping, extended with vocabulary URIs for
6
+ * steel production steps that standard CBV does not cover, following the
7
+ * GS1-sanctioned extension pattern.
8
+ */
9
+ export { toEventTime, buildTransformationEvent, buildServiceObjectEvent, buildOwnershipObjectEvent, buildCommissioningEvent, buildSupplierObjectEvent, } from "./event-builders.js";
10
+ export { CBV_BIZSTEP_URI, CBV_DISPOSITION_URI, TRACEPASS_BIZSTEP_URI, normalizeStepToken, mapEventTypeToBizStep, mapServiceEventType, mapOwnershipReasonDisposition, } from "./cbv.js";
11
+ export { validateEpcisDocument } from "./validate.js";
12
+ export { passportEpc, locationUri, locationRef, buildEventId } from "./identifiers.js";
13
+ export { EPCIS_CONTEXT_URL, TRACEPASS_VOC_BASE, EPCIS_JSONLD_CONTEXT, } from "./context.js";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,WAAW,EACX,wBAAwB,EACxB,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,6BAA6B,GAC9B,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAMtD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEvF,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC"}