@flaks/onerecord 0.1.2 → 0.3.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.
- package/CHANGELOG.md +324 -5
- package/MIGRATING.md +191 -5
- package/README.md +94 -34
- package/dist/booking-flow/index.d.ts +1 -1
- package/dist/booking-flow/index.d.ts.map +1 -1
- package/dist/booking-flow/index.js +1 -1
- package/dist/booking-flow/index.js.map +1 -1
- package/dist/booking-flow/transitions.d.ts +21 -0
- package/dist/booking-flow/transitions.d.ts.map +1 -1
- package/dist/booking-flow/transitions.js +57 -5
- package/dist/booking-flow/transitions.js.map +1 -1
- package/dist/classes/account-number/schema.d.ts +2 -7
- package/dist/classes/account-number/schema.d.ts.map +1 -1
- package/dist/classes/account-number/schema.js +7 -4
- package/dist/classes/account-number/schema.js.map +1 -1
- package/dist/classes/co2-emissions/codec.d.ts +4 -0
- package/dist/classes/co2-emissions/codec.d.ts.map +1 -0
- package/dist/classes/co2-emissions/codec.js +11 -0
- package/dist/classes/co2-emissions/codec.js.map +1 -0
- package/dist/classes/co2-emissions/deserialize.d.ts +5 -0
- package/dist/classes/co2-emissions/deserialize.d.ts.map +1 -0
- package/dist/classes/co2-emissions/deserialize.js +64 -0
- package/dist/classes/co2-emissions/deserialize.js.map +1 -0
- package/dist/classes/co2-emissions/index.d.ts +6 -0
- package/dist/classes/co2-emissions/index.d.ts.map +1 -0
- package/dist/classes/co2-emissions/index.js +5 -0
- package/dist/classes/co2-emissions/index.js.map +1 -0
- package/dist/classes/co2-emissions/schema.d.ts +18 -0
- package/dist/classes/co2-emissions/schema.d.ts.map +1 -0
- package/dist/classes/co2-emissions/schema.js +12 -0
- package/dist/classes/co2-emissions/schema.js.map +1 -0
- package/dist/classes/co2-emissions/serialize.d.ts +6 -0
- package/dist/classes/co2-emissions/serialize.d.ts.map +1 -0
- package/dist/classes/co2-emissions/serialize.js +28 -0
- package/dist/classes/co2-emissions/serialize.js.map +1 -0
- package/dist/classes/company/codec.d.ts +4 -0
- package/dist/classes/company/codec.d.ts.map +1 -0
- package/dist/classes/company/codec.js +11 -0
- package/dist/classes/company/codec.js.map +1 -0
- package/dist/classes/company/deserialize.d.ts +5 -0
- package/dist/classes/company/deserialize.d.ts.map +1 -0
- package/dist/classes/company/deserialize.js +64 -0
- package/dist/classes/company/deserialize.js.map +1 -0
- package/dist/classes/company/index.d.ts +6 -0
- package/dist/classes/company/index.d.ts.map +1 -0
- package/dist/classes/company/index.js +5 -0
- package/dist/classes/company/index.js.map +1 -0
- package/dist/classes/company/schema.d.ts +23 -0
- package/dist/classes/company/schema.d.ts.map +1 -0
- package/dist/classes/company/schema.js +23 -0
- package/dist/classes/company/schema.js.map +1 -0
- package/dist/classes/company/serialize.d.ts +6 -0
- package/dist/classes/company/serialize.d.ts.map +1 -0
- package/dist/classes/company/serialize.js +28 -0
- package/dist/classes/company/serialize.js.map +1 -0
- package/dist/classes/customs-information/codec.d.ts +4 -0
- package/dist/classes/customs-information/codec.d.ts.map +1 -0
- package/dist/classes/customs-information/codec.js +11 -0
- package/dist/classes/customs-information/codec.js.map +1 -0
- package/dist/classes/customs-information/deserialize.d.ts +5 -0
- package/dist/classes/customs-information/deserialize.d.ts.map +1 -0
- package/dist/classes/customs-information/deserialize.js +64 -0
- package/dist/classes/customs-information/deserialize.js.map +1 -0
- package/dist/classes/customs-information/index.d.ts +6 -0
- package/dist/classes/customs-information/index.d.ts.map +1 -0
- package/dist/classes/customs-information/index.js +5 -0
- package/dist/classes/customs-information/index.js.map +1 -0
- package/dist/classes/customs-information/schema.d.ts +18 -0
- package/dist/classes/customs-information/schema.d.ts.map +1 -0
- package/dist/classes/customs-information/schema.js +17 -0
- package/dist/classes/customs-information/schema.js.map +1 -0
- package/dist/classes/customs-information/serialize.d.ts +6 -0
- package/dist/classes/customs-information/serialize.d.ts.map +1 -0
- package/dist/classes/customs-information/serialize.js +28 -0
- package/dist/classes/customs-information/serialize.js.map +1 -0
- package/dist/classes/insurance/codec.d.ts +4 -0
- package/dist/classes/insurance/codec.d.ts.map +1 -0
- package/dist/classes/insurance/codec.js +11 -0
- package/dist/classes/insurance/codec.js.map +1 -0
- package/dist/classes/insurance/deserialize.d.ts +5 -0
- package/dist/classes/insurance/deserialize.d.ts.map +1 -0
- package/dist/classes/insurance/deserialize.js +64 -0
- package/dist/classes/insurance/deserialize.js.map +1 -0
- package/dist/classes/insurance/index.d.ts +6 -0
- package/dist/classes/insurance/index.d.ts.map +1 -0
- package/dist/classes/insurance/index.js +5 -0
- package/dist/classes/insurance/index.js.map +1 -0
- package/dist/classes/insurance/schema.d.ts +17 -0
- package/dist/classes/insurance/schema.d.ts.map +1 -0
- package/dist/classes/insurance/schema.js +11 -0
- package/dist/classes/insurance/schema.js.map +1 -0
- package/dist/classes/insurance/serialize.d.ts +6 -0
- package/dist/classes/insurance/serialize.d.ts.map +1 -0
- package/dist/classes/insurance/serialize.js +28 -0
- package/dist/classes/insurance/serialize.js.map +1 -0
- package/dist/classes/line-item-package/codec.d.ts +4 -0
- package/dist/classes/line-item-package/codec.d.ts.map +1 -0
- package/dist/classes/line-item-package/codec.js +11 -0
- package/dist/classes/line-item-package/codec.js.map +1 -0
- package/dist/classes/line-item-package/deserialize.d.ts +5 -0
- package/dist/classes/line-item-package/deserialize.d.ts.map +1 -0
- package/dist/classes/line-item-package/deserialize.js +64 -0
- package/dist/classes/line-item-package/deserialize.js.map +1 -0
- package/dist/classes/line-item-package/index.d.ts +6 -0
- package/dist/classes/line-item-package/index.d.ts.map +1 -0
- package/dist/classes/line-item-package/index.js +5 -0
- package/dist/classes/line-item-package/index.js.map +1 -0
- package/dist/classes/line-item-package/schema.d.ts +22 -0
- package/dist/classes/line-item-package/schema.d.ts.map +1 -0
- package/dist/classes/line-item-package/schema.js +12 -0
- package/dist/classes/line-item-package/schema.js.map +1 -0
- package/dist/classes/line-item-package/serialize.d.ts +6 -0
- package/dist/classes/line-item-package/serialize.d.ts.map +1 -0
- package/dist/classes/line-item-package/serialize.js +28 -0
- package/dist/classes/line-item-package/serialize.js.map +1 -0
- package/dist/classes/other-charge/codec.d.ts +4 -0
- package/dist/classes/other-charge/codec.d.ts.map +1 -0
- package/dist/classes/other-charge/codec.js +11 -0
- package/dist/classes/other-charge/codec.js.map +1 -0
- package/dist/classes/other-charge/deserialize.d.ts +5 -0
- package/dist/classes/other-charge/deserialize.d.ts.map +1 -0
- package/dist/classes/other-charge/deserialize.js +64 -0
- package/dist/classes/other-charge/deserialize.js.map +1 -0
- package/dist/classes/other-charge/index.d.ts +6 -0
- package/dist/classes/other-charge/index.d.ts.map +1 -0
- package/dist/classes/other-charge/index.js +5 -0
- package/dist/classes/other-charge/index.js.map +1 -0
- package/dist/classes/other-charge/schema.d.ts +27 -0
- package/dist/classes/other-charge/schema.d.ts.map +1 -0
- package/dist/classes/other-charge/schema.js +14 -0
- package/dist/classes/other-charge/schema.js.map +1 -0
- package/dist/classes/other-charge/serialize.d.ts +6 -0
- package/dist/classes/other-charge/serialize.d.ts.map +1 -0
- package/dist/classes/other-charge/serialize.js +28 -0
- package/dist/classes/other-charge/serialize.js.map +1 -0
- package/dist/classes/party/schema.d.ts +9 -1
- package/dist/classes/party/schema.d.ts.map +1 -1
- package/dist/classes/party/schema.js +5 -2
- package/dist/classes/party/schema.js.map +1 -1
- package/dist/classes/piece/schema.d.ts +11 -0
- package/dist/classes/piece/schema.d.ts.map +1 -1
- package/dist/classes/piece/schema.js +10 -0
- package/dist/classes/piece/schema.js.map +1 -1
- package/dist/classes/regulated-entity/codec.d.ts +4 -0
- package/dist/classes/regulated-entity/codec.d.ts.map +1 -0
- package/dist/classes/regulated-entity/codec.js +11 -0
- package/dist/classes/regulated-entity/codec.js.map +1 -0
- package/dist/classes/regulated-entity/deserialize.d.ts +5 -0
- package/dist/classes/regulated-entity/deserialize.d.ts.map +1 -0
- package/dist/classes/regulated-entity/deserialize.js +64 -0
- package/dist/classes/regulated-entity/deserialize.js.map +1 -0
- package/dist/classes/regulated-entity/index.d.ts +6 -0
- package/dist/classes/regulated-entity/index.d.ts.map +1 -0
- package/dist/classes/regulated-entity/index.js +5 -0
- package/dist/classes/regulated-entity/index.js.map +1 -0
- package/dist/classes/regulated-entity/schema.d.ts +19 -0
- package/dist/classes/regulated-entity/schema.d.ts.map +1 -0
- package/dist/classes/regulated-entity/schema.js +12 -0
- package/dist/classes/regulated-entity/schema.js.map +1 -0
- package/dist/classes/regulated-entity/serialize.d.ts +6 -0
- package/dist/classes/regulated-entity/serialize.d.ts.map +1 -0
- package/dist/classes/regulated-entity/serialize.js +28 -0
- package/dist/classes/regulated-entity/serialize.js.map +1 -0
- package/dist/classes/security-declaration/codec.d.ts +4 -0
- package/dist/classes/security-declaration/codec.d.ts.map +1 -0
- package/dist/classes/security-declaration/codec.js +11 -0
- package/dist/classes/security-declaration/codec.js.map +1 -0
- package/dist/classes/security-declaration/deserialize.d.ts +5 -0
- package/dist/classes/security-declaration/deserialize.d.ts.map +1 -0
- package/dist/classes/security-declaration/deserialize.js +64 -0
- package/dist/classes/security-declaration/deserialize.js.map +1 -0
- package/dist/classes/security-declaration/index.d.ts +6 -0
- package/dist/classes/security-declaration/index.d.ts.map +1 -0
- package/dist/classes/security-declaration/index.js +5 -0
- package/dist/classes/security-declaration/index.js.map +1 -0
- package/dist/classes/security-declaration/schema.d.ts +44 -0
- package/dist/classes/security-declaration/schema.d.ts.map +1 -0
- package/dist/classes/security-declaration/schema.js +21 -0
- package/dist/classes/security-declaration/schema.js.map +1 -0
- package/dist/classes/security-declaration/serialize.d.ts +6 -0
- package/dist/classes/security-declaration/serialize.d.ts.map +1 -0
- package/dist/classes/security-declaration/serialize.js +28 -0
- package/dist/classes/security-declaration/serialize.js.map +1 -0
- package/dist/classes/shared/value.d.ts +44 -0
- package/dist/classes/shared/value.d.ts.map +1 -0
- package/dist/classes/shared/value.js +39 -0
- package/dist/classes/shared/value.js.map +1 -0
- package/dist/classes/shipment/schema.d.ts +31 -8
- package/dist/classes/shipment/schema.d.ts.map +1 -1
- package/dist/classes/shipment/schema.js +15 -5
- package/dist/classes/shipment/schema.js.map +1 -1
- package/dist/classes/transport-movement/schema.d.ts +22 -0
- package/dist/classes/transport-movement/schema.d.ts.map +1 -1
- package/dist/classes/transport-movement/schema.js +7 -0
- package/dist/classes/transport-movement/schema.js.map +1 -1
- package/dist/classes/uld/codec.d.ts +4 -0
- package/dist/classes/uld/codec.d.ts.map +1 -0
- package/dist/classes/uld/codec.js +11 -0
- package/dist/classes/uld/codec.js.map +1 -0
- package/dist/classes/uld/deserialize.d.ts +5 -0
- package/dist/classes/uld/deserialize.d.ts.map +1 -0
- package/dist/classes/uld/deserialize.js +64 -0
- package/dist/classes/uld/deserialize.js.map +1 -0
- package/dist/classes/uld/index.d.ts +6 -0
- package/dist/classes/uld/index.d.ts.map +1 -0
- package/dist/classes/uld/index.js +5 -0
- package/dist/classes/uld/index.js.map +1 -0
- package/dist/classes/uld/schema.d.ts +31 -0
- package/dist/classes/uld/schema.d.ts.map +1 -0
- package/dist/classes/uld/schema.js +29 -0
- package/dist/classes/uld/schema.js.map +1 -0
- package/dist/classes/uld/serialize.d.ts +6 -0
- package/dist/classes/uld/serialize.d.ts.map +1 -0
- package/dist/classes/uld/serialize.js +28 -0
- package/dist/classes/uld/serialize.js.map +1 -0
- package/dist/classes/waybill/schema.d.ts +45 -5
- package/dist/classes/waybill/schema.d.ts.map +1 -1
- package/dist/classes/waybill/schema.js +28 -7
- package/dist/classes/waybill/schema.js.map +1 -1
- package/dist/classes/waybill-line-item/codec.d.ts +4 -0
- package/dist/classes/waybill-line-item/codec.d.ts.map +1 -0
- package/dist/classes/waybill-line-item/codec.js +11 -0
- package/dist/classes/waybill-line-item/codec.js.map +1 -0
- package/dist/classes/waybill-line-item/deserialize.d.ts +5 -0
- package/dist/classes/waybill-line-item/deserialize.d.ts.map +1 -0
- package/dist/classes/waybill-line-item/deserialize.js +64 -0
- package/dist/classes/waybill-line-item/deserialize.js.map +1 -0
- package/dist/classes/waybill-line-item/index.d.ts +6 -0
- package/dist/classes/waybill-line-item/index.d.ts.map +1 -0
- package/dist/classes/waybill-line-item/index.js +5 -0
- package/dist/classes/waybill-line-item/index.js.map +1 -0
- package/dist/classes/waybill-line-item/schema.d.ts +44 -0
- package/dist/classes/waybill-line-item/schema.d.ts.map +1 -0
- package/dist/classes/waybill-line-item/schema.js +22 -0
- package/dist/classes/waybill-line-item/schema.js.map +1 -0
- package/dist/classes/waybill-line-item/serialize.d.ts +6 -0
- package/dist/classes/waybill-line-item/serialize.d.ts.map +1 -0
- package/dist/classes/waybill-line-item/serialize.js +28 -0
- package/dist/classes/waybill-line-item/serialize.js.map +1 -0
- package/dist/codecs.d.ts +10 -1
- package/dist/codecs.d.ts.map +1 -1
- package/dist/codecs.js +10 -1
- package/dist/codecs.js.map +1 -1
- package/dist/codes/enums.d.ts +35 -0
- package/dist/codes/enums.d.ts.map +1 -1
- package/dist/codes/enums.js +4 -0
- package/dist/codes/enums.js.map +1 -1
- package/dist/codes/fsu-event-codes.d.ts +6 -6
- package/dist/codes/fsu-event-codes.d.ts.map +1 -1
- package/dist/codes/fsu-event-codes.js +11 -9
- package/dist/codes/fsu-event-codes.js.map +1 -1
- package/dist/codes/index.d.ts +1 -1
- package/dist/codes/index.d.ts.map +1 -1
- package/dist/codes/index.js +1 -1
- package/dist/codes/index.js.map +1 -1
- package/dist/dispatch/context-order.d.ts +28 -0
- package/dist/dispatch/context-order.d.ts.map +1 -0
- package/dist/dispatch/context-order.js +21 -0
- package/dist/dispatch/context-order.js.map +1 -0
- package/dist/dispatch/domain-constraints.d.ts +49 -0
- package/dist/dispatch/domain-constraints.d.ts.map +1 -0
- package/dist/dispatch/domain-constraints.js +59 -0
- package/dist/dispatch/domain-constraints.js.map +1 -0
- package/dist/dispatch/field-types.d.ts +29 -0
- package/dist/dispatch/field-types.d.ts.map +1 -0
- package/dist/dispatch/field-types.js +135 -0
- package/dist/dispatch/field-types.js.map +1 -0
- package/dist/dispatch/graph-walk.d.ts +23 -0
- package/dist/dispatch/graph-walk.d.ts.map +1 -0
- package/dist/dispatch/graph-walk.js +207 -0
- package/dist/dispatch/graph-walk.js.map +1 -0
- package/dist/dispatch/index.d.ts +30 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/index.js +36 -0
- package/dist/dispatch/index.js.map +1 -0
- package/dist/dispatch/iri-canonical.d.ts +28 -0
- package/dist/dispatch/iri-canonical.d.ts.map +1 -0
- package/dist/dispatch/iri-canonical.js +55 -0
- package/dist/dispatch/iri-canonical.js.map +1 -0
- package/dist/error/format.d.ts.map +1 -1
- package/dist/error/format.js +8 -0
- package/dist/error/format.js.map +1 -1
- package/dist/facade.d.ts +53 -2
- package/dist/facade.d.ts.map +1 -1
- package/dist/facade.js +8 -0
- package/dist/facade.js.map +1 -1
- package/dist/factory-classes.d.ts +27 -6
- package/dist/factory-classes.d.ts.map +1 -1
- package/dist/factory-classes.js +27 -6
- package/dist/factory-classes.js.map +1 -1
- package/dist/factory.d.ts +12 -0
- package/dist/factory.d.ts.map +1 -1
- package/dist/factory.js +10 -1
- package/dist/factory.js.map +1 -1
- package/dist/index.d.ts +32 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -3
- package/dist/index.js.map +1 -1
- package/dist/iri/dereference.d.ts +42 -0
- package/dist/iri/dereference.d.ts.map +1 -0
- package/dist/iri/dereference.js +75 -0
- package/dist/iri/dereference.js.map +1 -0
- package/dist/iri/zod-safe-iri.d.ts +18 -2
- package/dist/iri/zod-safe-iri.d.ts.map +1 -1
- package/dist/iri/zod-safe-iri.js +14 -2
- package/dist/iri/zod-safe-iri.js.map +1 -1
- package/dist/result.d.ts +27 -1
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +9 -0
- package/dist/result.js.map +1 -1
- package/dist/safety/blank-node.d.ts +20 -0
- package/dist/safety/blank-node.d.ts.map +1 -0
- package/dist/safety/blank-node.js +59 -0
- package/dist/safety/blank-node.js.map +1 -0
- package/dist/safety/pre-validate.d.ts.map +1 -1
- package/dist/safety/pre-validate.js +12 -72
- package/dist/safety/pre-validate.js.map +1 -1
- package/dist/safety/walk-graph.d.ts +30 -0
- package/dist/safety/walk-graph.d.ts.map +1 -0
- package/dist/safety/walk-graph.js +100 -0
- package/dist/safety/walk-graph.js.map +1 -0
- package/dist/types/index.d.ts +10 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/version.d.ts +9 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +18 -6
- package/dist/version.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain-semantic constraints that the Zod schemas mark as optional but spec
|
|
3
|
+
* §5.x requires. Used by `dispatchGraphWalk` to emit
|
|
4
|
+
* `domain_constraint_violation` for missing-but-required fields.
|
|
5
|
+
*
|
|
6
|
+
* Closes deviation #6 PARTIALLY (v0.2 — deferral F):
|
|
7
|
+
* - graph-cardinality (this file) — EMPTY in v0.3.0: Path A removed the stale v0.2 constraints (Waybill.shipmentInformation / Shipment.containedPieces); see the explanatory note below
|
|
8
|
+
* - AWB number consistency between Waybill ↔ embedded Shipments — v0.3
|
|
9
|
+
* - total-pieces / total-weight sums between Shipment ↔ Pieces — v0.3
|
|
10
|
+
* - reference resolvability for cross-graph IRIs — v0.3
|
|
11
|
+
*
|
|
12
|
+
* v0.3 (Path A): The v0.2 constraints on `Waybill.shipmentInformation` and
|
|
13
|
+
* `Shipment.containedPieces` have been REMOVED. Path A replaced
|
|
14
|
+
* `shipmentInformation` with `shipment` and `containedPieces` with `pieces`
|
|
15
|
+
* in the schema; the old field names have no 3.2.0 spec basis and are no
|
|
16
|
+
* longer part of the data model surface. The spec-correct cross-node check
|
|
17
|
+
* (Waybill↔Shipment inverse-property consistency via `Waybill.shipment` ↔
|
|
18
|
+
* `Shipment.waybill`) is deferred to v0.3's final-review task — the
|
|
19
|
+
* constraint framework would need bidirectional-reference resolution which
|
|
20
|
+
* is multi-node and out of this batch's scope.
|
|
21
|
+
*
|
|
22
|
+
* Opt-in via the dispatch path; default per-class deserializers stay
|
|
23
|
+
* schema-permissive.
|
|
24
|
+
*/
|
|
25
|
+
export interface DomainConstraint {
|
|
26
|
+
/** Field that must be present on the root LO. */
|
|
27
|
+
field: string;
|
|
28
|
+
/** Cardinality requirement (`required` = present + non-null). */
|
|
29
|
+
cardinality: 'required';
|
|
30
|
+
/** Spec section reference for the constraint. */
|
|
31
|
+
specRef: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const DOMAIN_CONSTRAINTS: Readonly<Record<string, DomainConstraint[]>>;
|
|
34
|
+
export interface DomainConstraintViolation {
|
|
35
|
+
className: string;
|
|
36
|
+
field: string;
|
|
37
|
+
expected: 'required';
|
|
38
|
+
specRef: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Validate root-level cardinality constraints for the given root class.
|
|
42
|
+
* Returns the FIRST missing-required-field violation, or undefined if all
|
|
43
|
+
* required fields are present.
|
|
44
|
+
*
|
|
45
|
+
* Only checks root-level constraints — nested LO-in-LO cardinality is
|
|
46
|
+
* deferred to v0.3 (alongside the other deviation #6 sub-items).
|
|
47
|
+
*/
|
|
48
|
+
export declare function checkDomainConstraints(rootClass: string, root: Record<string, unknown>): DomainConstraintViolation | undefined;
|
|
49
|
+
//# sourceMappingURL=domain-constraints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-constraints.d.ts","sourceRoot":"","sources":["../../src/dispatch/domain-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,iEAAiE;IACjE,WAAW,EAAE,UAAU,CAAA;IACvB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAqB,CAAA;AAEjG,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,UAAU,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,yBAAyB,GAAG,SAAS,CAuBvC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain-semantic constraints that the Zod schemas mark as optional but spec
|
|
3
|
+
* §5.x requires. Used by `dispatchGraphWalk` to emit
|
|
4
|
+
* `domain_constraint_violation` for missing-but-required fields.
|
|
5
|
+
*
|
|
6
|
+
* Closes deviation #6 PARTIALLY (v0.2 — deferral F):
|
|
7
|
+
* - graph-cardinality (this file) — EMPTY in v0.3.0: Path A removed the stale v0.2 constraints (Waybill.shipmentInformation / Shipment.containedPieces); see the explanatory note below
|
|
8
|
+
* - AWB number consistency between Waybill ↔ embedded Shipments — v0.3
|
|
9
|
+
* - total-pieces / total-weight sums between Shipment ↔ Pieces — v0.3
|
|
10
|
+
* - reference resolvability for cross-graph IRIs — v0.3
|
|
11
|
+
*
|
|
12
|
+
* v0.3 (Path A): The v0.2 constraints on `Waybill.shipmentInformation` and
|
|
13
|
+
* `Shipment.containedPieces` have been REMOVED. Path A replaced
|
|
14
|
+
* `shipmentInformation` with `shipment` and `containedPieces` with `pieces`
|
|
15
|
+
* in the schema; the old field names have no 3.2.0 spec basis and are no
|
|
16
|
+
* longer part of the data model surface. The spec-correct cross-node check
|
|
17
|
+
* (Waybill↔Shipment inverse-property consistency via `Waybill.shipment` ↔
|
|
18
|
+
* `Shipment.waybill`) is deferred to v0.3's final-review task — the
|
|
19
|
+
* constraint framework would need bidirectional-reference resolution which
|
|
20
|
+
* is multi-node and out of this batch's scope.
|
|
21
|
+
*
|
|
22
|
+
* Opt-in via the dispatch path; default per-class deserializers stay
|
|
23
|
+
* schema-permissive.
|
|
24
|
+
*/
|
|
25
|
+
export const DOMAIN_CONSTRAINTS = Object.freeze({});
|
|
26
|
+
/**
|
|
27
|
+
* Validate root-level cardinality constraints for the given root class.
|
|
28
|
+
* Returns the FIRST missing-required-field violation, or undefined if all
|
|
29
|
+
* required fields are present.
|
|
30
|
+
*
|
|
31
|
+
* Only checks root-level constraints — nested LO-in-LO cardinality is
|
|
32
|
+
* deferred to v0.3 (alongside the other deviation #6 sub-items).
|
|
33
|
+
*/
|
|
34
|
+
export function checkDomainConstraints(rootClass, root) {
|
|
35
|
+
const constraints = DOMAIN_CONSTRAINTS[rootClass];
|
|
36
|
+
if (!constraints)
|
|
37
|
+
return undefined;
|
|
38
|
+
for (const c of constraints) {
|
|
39
|
+
const v = root[c.field];
|
|
40
|
+
if (v === undefined || v === null) {
|
|
41
|
+
return {
|
|
42
|
+
className: rootClass,
|
|
43
|
+
field: c.field,
|
|
44
|
+
expected: c.cardinality,
|
|
45
|
+
specRef: c.specRef,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(v) && v.length === 0) {
|
|
49
|
+
return {
|
|
50
|
+
className: rootClass,
|
|
51
|
+
field: c.field,
|
|
52
|
+
expected: c.cardinality,
|
|
53
|
+
specRef: c.specRef,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=domain-constraints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-constraints.js","sourceRoot":"","sources":["../../src/dispatch/domain-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAWH,MAAM,CAAC,MAAM,kBAAkB,GAAiD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AASjG;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,IAA6B;IAE7B,MAAM,WAAW,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAA;IACjD,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAA;IAClC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACvB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAClC,OAAO;gBACL,SAAS,EAAE,SAAS;gBACpB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,QAAQ,EAAE,CAAC,CAAC,WAAW;gBACvB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAA;QACH,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO;gBACL,SAAS,EAAE,SAAS;gBACpB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,QAAQ,EAAE,CAAC,CAAC,WAAW;gBACvB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static map: '<Class>.<field>' -> expected `@type` of an embedded
|
|
3
|
+
* object or IRI-referenced node. Used by `dispatchGraphWalk` to emit
|
|
4
|
+
* `wrong_type_for_endpoint` when an embedded node's `@type` does not
|
|
5
|
+
* match the field's contract.
|
|
6
|
+
*
|
|
7
|
+
* Coverage: every cross-referencing field across the registered class set.
|
|
8
|
+
* Scalar fields and external-endpoint URLs
|
|
9
|
+
* (`Subscription.notificationEndpoint`, `ServerInformation.serverEndpoint`)
|
|
10
|
+
* are intentionally omitted — those don't resolve to a OneRecord type.
|
|
11
|
+
*
|
|
12
|
+
* Polymorphic fields are marked with `'*'`. The graph-walker treats
|
|
13
|
+
* `'*'` as "any logistics-object type accepted".
|
|
14
|
+
*
|
|
15
|
+
* Maintenance: when adding a new class or field that holds a
|
|
16
|
+
* cross-reference, also add the expected-type mapping here. The
|
|
17
|
+
* graph-walker only checks mapped fields, so omission is silent —
|
|
18
|
+
* a missing entry means "not validated".
|
|
19
|
+
*/
|
|
20
|
+
export declare const FIELD_TYPES: Readonly<Record<string, string>>;
|
|
21
|
+
/**
|
|
22
|
+
* Look up the expected `@type` for a given (className, fieldName).
|
|
23
|
+
* Returns `undefined` for fields not in the map (= not validated by
|
|
24
|
+
* the graph-walker — either scalar or out-of-scope external URL).
|
|
25
|
+
* Returns `'*'` for polymorphic fields where any logistics-object
|
|
26
|
+
* `@type` is valid.
|
|
27
|
+
*/
|
|
28
|
+
export declare function expectedTypeFor(className: string, fieldName: string): string | undefined;
|
|
29
|
+
//# sourceMappingURL=field-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-types.d.ts","sourceRoot":"","sources":["../../src/dispatch/field-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA6HvD,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExF"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static map: '<Class>.<field>' -> expected `@type` of an embedded
|
|
3
|
+
* object or IRI-referenced node. Used by `dispatchGraphWalk` to emit
|
|
4
|
+
* `wrong_type_for_endpoint` when an embedded node's `@type` does not
|
|
5
|
+
* match the field's contract.
|
|
6
|
+
*
|
|
7
|
+
* Coverage: every cross-referencing field across the registered class set.
|
|
8
|
+
* Scalar fields and external-endpoint URLs
|
|
9
|
+
* (`Subscription.notificationEndpoint`, `ServerInformation.serverEndpoint`)
|
|
10
|
+
* are intentionally omitted — those don't resolve to a OneRecord type.
|
|
11
|
+
*
|
|
12
|
+
* Polymorphic fields are marked with `'*'`. The graph-walker treats
|
|
13
|
+
* `'*'` as "any logistics-object type accepted".
|
|
14
|
+
*
|
|
15
|
+
* Maintenance: when adding a new class or field that holds a
|
|
16
|
+
* cross-reference, also add the expected-type mapping here. The
|
|
17
|
+
* graph-walker only checks mapped fields, so omission is silent —
|
|
18
|
+
* a missing entry means "not validated".
|
|
19
|
+
*/
|
|
20
|
+
export const FIELD_TYPES = Object.freeze({
|
|
21
|
+
// Access-delegation
|
|
22
|
+
'AccessDelegationRequest.accessDelegation': 'AccessDelegation',
|
|
23
|
+
'AccessDelegation.delegatedTo': 'Party',
|
|
24
|
+
'AccessDelegation.delegatedFrom': 'Party',
|
|
25
|
+
// Account number
|
|
26
|
+
// (AccountNumber.issuedBy removed — :issuedBy is range :Person / domain :SecurityDeclaration,
|
|
27
|
+
// not on :AccountNumber; do not repoint)
|
|
28
|
+
// Booking ecosystem
|
|
29
|
+
'Booking.forBookingRequest': 'BookingRequest',
|
|
30
|
+
'Booking.forBookingOption': 'BookingOption',
|
|
31
|
+
'BookingOption.forBookingRequest': 'BookingRequest',
|
|
32
|
+
'BookingOption.preferences': 'BookingPreferences',
|
|
33
|
+
'BookingOptionRequest.forBookingOption': 'BookingOption',
|
|
34
|
+
'BookingRequest.requestor': 'Party',
|
|
35
|
+
'BookingRequest.preferences': 'BookingPreferences',
|
|
36
|
+
'BookingSegment.transportMovement': 'TransportMovement',
|
|
37
|
+
'BookingSegment.loadingLocation': 'Location',
|
|
38
|
+
'BookingSegment.unloadingLocation': 'Location',
|
|
39
|
+
'BookingShipment.forShipment': 'Shipment',
|
|
40
|
+
// Change ecosystem
|
|
41
|
+
'Change.hasOperation': 'Operation', // embedded array, not IRI ref
|
|
42
|
+
'ChangeRequest.forLogisticsObject': '*', // polymorphic
|
|
43
|
+
'ChangeRequest.hasChange': 'Change',
|
|
44
|
+
// CO2Emissions
|
|
45
|
+
'CO2Emissions.calculationFor': '*', // polymorphic — TransportMovement or Shipment etc.
|
|
46
|
+
'TransportMovement.co2Emissions': 'CO2Emissions',
|
|
47
|
+
// Company (concrete :Organization subtype — only concrete org type shipped)
|
|
48
|
+
'Company.basedAtLocation': 'Location',
|
|
49
|
+
// Organization-range properties pin to 'Company': :Company rdfs:subClassOf :Organization and
|
|
50
|
+
// Company is the only concrete :Organization subtype this library ships post-Organization-
|
|
51
|
+
// retirement, so 'Company' is the correct (not over-strict) wrong_type_for_endpoint contract.
|
|
52
|
+
// Company.contactPersons → 'Person': ontology range is abstract :Actor, :Person rdfs:subClassOf
|
|
53
|
+
// :Actor, no NonHumanActor shipped, so 'Person' is the correct concrete contract.
|
|
54
|
+
'Company.contactPersons': 'Person',
|
|
55
|
+
'Company.parentOrganization': 'Company',
|
|
56
|
+
'Company.subOrganization': 'Company',
|
|
57
|
+
// CustomsInformation
|
|
58
|
+
'CustomsInformation.issuedForPiece': 'Piece',
|
|
59
|
+
'CustomsInformation.issuedForShipment': 'Shipment',
|
|
60
|
+
// Handling
|
|
61
|
+
'HandlingService.provider': 'Party',
|
|
62
|
+
'HandlingService.forShipment': 'Shipment',
|
|
63
|
+
// Insurance
|
|
64
|
+
'Insurance.coveringOrganization': 'Company',
|
|
65
|
+
'Insurance.insuredShipments': 'Shipment',
|
|
66
|
+
// LineItemPackage / ULD
|
|
67
|
+
'LineItemPackage.pieceReferences': 'Piece',
|
|
68
|
+
'WaybillLineItem.lineItemPackages': 'LineItemPackage',
|
|
69
|
+
'WaybillLineItem.uldReferences': 'ULD',
|
|
70
|
+
// Location ↔ Address
|
|
71
|
+
'Location.address': 'Address',
|
|
72
|
+
// Logistics event
|
|
73
|
+
'LogisticsEvent.eventLocation': 'Location',
|
|
74
|
+
'LogisticsEvent.relatedTransportMovement': 'TransportMovement',
|
|
75
|
+
// Notification
|
|
76
|
+
'Notification.relatedLogisticsObject': '*', // polymorphic
|
|
77
|
+
// Party (Organization retired; partyDetails is Person or Company)
|
|
78
|
+
'Party.partyDetails': '*', // polymorphic — Person or Company
|
|
79
|
+
'Party.accountNumbers': 'AccountNumber',
|
|
80
|
+
// Piece
|
|
81
|
+
'Piece.ofShipment': 'Shipment',
|
|
82
|
+
'Piece.containedPieces': 'Piece',
|
|
83
|
+
'Piece.securityDeclarations': 'SecurityDeclaration',
|
|
84
|
+
// Piece.packagingType omitted — :PackagingType is a codes class (enum), not a logistics object
|
|
85
|
+
// RegulatedEntity
|
|
86
|
+
'RegulatedEntity.owningOrganization': 'Company',
|
|
87
|
+
// SecurityDeclaration
|
|
88
|
+
'SecurityDeclaration.issuedForPiece': 'Piece',
|
|
89
|
+
'SecurityDeclaration.issuedBy': 'Person',
|
|
90
|
+
'SecurityDeclaration.regulatedEntityIssuer': 'RegulatedEntity',
|
|
91
|
+
'SecurityDeclaration.regulatedEntityAcceptor': 'RegulatedEntity',
|
|
92
|
+
'SecurityDeclaration.receivedFrom': 'RegulatedEntity',
|
|
93
|
+
'SecurityDeclaration.otherRegulatedEntities': 'RegulatedEntity',
|
|
94
|
+
// Shipment
|
|
95
|
+
'Shipment.pieces': 'Piece',
|
|
96
|
+
'Shipment.waybill': 'Waybill',
|
|
97
|
+
'Shipment.involvedParties': 'Party',
|
|
98
|
+
'Shipment.customsInformation': 'CustomsInformation',
|
|
99
|
+
'Shipment.insurance': 'Insurance',
|
|
100
|
+
'Shipment.securityDeclarations': 'SecurityDeclaration',
|
|
101
|
+
// Subscription
|
|
102
|
+
'SubscriptionRequest.subscription': 'Subscription',
|
|
103
|
+
'Subscription.topic': '*', // polymorphic — any logistics object class IRI
|
|
104
|
+
'Subscription.subscriber': 'Party',
|
|
105
|
+
// Transport movement
|
|
106
|
+
'TransportMovement.departureLocation': 'Location',
|
|
107
|
+
'TransportMovement.arrivalLocation': 'Location',
|
|
108
|
+
'TransportMovement.movementTimes': 'MovementTime',
|
|
109
|
+
// Verification
|
|
110
|
+
'VerificationRequest.verification': 'Verification',
|
|
111
|
+
'Verification.verifiedObject': '*', // polymorphic
|
|
112
|
+
// Waybill
|
|
113
|
+
'Waybill.shipment': 'Shipment',
|
|
114
|
+
'Waybill.involvedParties': 'Party',
|
|
115
|
+
'Waybill.waybillLineItems': 'WaybillLineItem',
|
|
116
|
+
'Waybill.otherCharges': 'OtherCharge',
|
|
117
|
+
'Waybill.carrierDeclarationPlace': 'Location',
|
|
118
|
+
'Waybill.departureLocation': 'Location',
|
|
119
|
+
'Waybill.arrivalLocation': 'Location',
|
|
120
|
+
'Waybill.houseWaybills': 'Waybill',
|
|
121
|
+
'Waybill.masterWaybill': 'Waybill',
|
|
122
|
+
// Waybill.billingDetails omitted — :BillingDetails not modelled in v0.3.0 (deviation #16)
|
|
123
|
+
'Waybill.referredBookingOption': 'BookingOption',
|
|
124
|
+
});
|
|
125
|
+
/**
|
|
126
|
+
* Look up the expected `@type` for a given (className, fieldName).
|
|
127
|
+
* Returns `undefined` for fields not in the map (= not validated by
|
|
128
|
+
* the graph-walker — either scalar or out-of-scope external URL).
|
|
129
|
+
* Returns `'*'` for polymorphic fields where any logistics-object
|
|
130
|
+
* `@type` is valid.
|
|
131
|
+
*/
|
|
132
|
+
export function expectedTypeFor(className, fieldName) {
|
|
133
|
+
return FIELD_TYPES[`${className}.${fieldName}`];
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=field-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-types.js","sourceRoot":"","sources":["../../src/dispatch/field-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ParseResult } from '../result.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cross-node graph integrity analysis. Runs as a single walk via
|
|
4
|
+
* `walkGraph`'s visitor; emits at most one of:
|
|
5
|
+
* - `duplicate_id_in_graph` — two distinct nodes share an `@id`.
|
|
6
|
+
* - `missing_id` — a node embedded in a cross-reference position has no `@id`.
|
|
7
|
+
* - `wrong_type_for_endpoint` — a node's `@type` does not match the
|
|
8
|
+
* declared expected type for the field that references it.
|
|
9
|
+
* - `missing_type` — a non-leaf node lacks `@type`.
|
|
10
|
+
* - `iri_not_canonical` — an IRI string is not in canonical form
|
|
11
|
+
* (lowercase scheme/host, no default port; RFC 3987 + spec §3.2).
|
|
12
|
+
*
|
|
13
|
+
* Returns `ok: true` if the graph is structurally sound (per spec §3.2 + §7.1).
|
|
14
|
+
*
|
|
15
|
+
* Does NOT replace per-class Zod schema validation — that runs after this
|
|
16
|
+
* pass succeeds, in `dispatch.deserialize.<Class>`.
|
|
17
|
+
*
|
|
18
|
+
* v0.2: containing-class tracking via path-keyed map of object @types,
|
|
19
|
+
* so `wrong_type_for_endpoint` and `missing_id` checks fire for all
|
|
20
|
+
* embedded references, not just direct children of the root.
|
|
21
|
+
*/
|
|
22
|
+
export declare function dispatchGraphWalk(input: unknown, rootClass: string): ParseResult<true>;
|
|
23
|
+
//# sourceMappingURL=graph-walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-walk.d.ts","sourceRoot":"","sources":["../../src/dispatch/graph-walk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,cAAc,CAAA;AAO3D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAoItF"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { walkGraph } from '../safety/walk-graph.js';
|
|
2
|
+
import { checkContextOrder } from './context-order.js';
|
|
3
|
+
import { checkDomainConstraints } from './domain-constraints.js';
|
|
4
|
+
import { expectedTypeFor } from './field-types.js';
|
|
5
|
+
import { checkIriCanonical, looksLikeIri } from './iri-canonical.js';
|
|
6
|
+
/**
|
|
7
|
+
* Cross-node graph integrity analysis. Runs as a single walk via
|
|
8
|
+
* `walkGraph`'s visitor; emits at most one of:
|
|
9
|
+
* - `duplicate_id_in_graph` — two distinct nodes share an `@id`.
|
|
10
|
+
* - `missing_id` — a node embedded in a cross-reference position has no `@id`.
|
|
11
|
+
* - `wrong_type_for_endpoint` — a node's `@type` does not match the
|
|
12
|
+
* declared expected type for the field that references it.
|
|
13
|
+
* - `missing_type` — a non-leaf node lacks `@type`.
|
|
14
|
+
* - `iri_not_canonical` — an IRI string is not in canonical form
|
|
15
|
+
* (lowercase scheme/host, no default port; RFC 3987 + spec §3.2).
|
|
16
|
+
*
|
|
17
|
+
* Returns `ok: true` if the graph is structurally sound (per spec §3.2 + §7.1).
|
|
18
|
+
*
|
|
19
|
+
* Does NOT replace per-class Zod schema validation — that runs after this
|
|
20
|
+
* pass succeeds, in `dispatch.deserialize.<Class>`.
|
|
21
|
+
*
|
|
22
|
+
* v0.2: containing-class tracking via path-keyed map of object @types,
|
|
23
|
+
* so `wrong_type_for_endpoint` and `missing_id` checks fire for all
|
|
24
|
+
* embedded references, not just direct children of the root.
|
|
25
|
+
*/
|
|
26
|
+
export function dispatchGraphWalk(input, rootClass) {
|
|
27
|
+
// context_order_violation (deviation #10 closure, deferral E): if the
|
|
28
|
+
// root @context is an array, verify the LAST element is allowed.
|
|
29
|
+
// Per JSON-LD 1.1 §3.7 later items override earlier ones for term
|
|
30
|
+
// definitions; the last item is the effective cargo-term context.
|
|
31
|
+
// String-form @context is delegated to assertContextAllowed (already
|
|
32
|
+
// runs in the per-class deserializer).
|
|
33
|
+
if (typeof input === 'object' && input !== null && '@context' in input) {
|
|
34
|
+
const ctx = input['@context'];
|
|
35
|
+
const orderR = checkContextOrder(ctx);
|
|
36
|
+
if (!orderR.ok && orderR.lastUnallowed !== undefined) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
error: {
|
|
40
|
+
kind: 'context_order_violation',
|
|
41
|
+
got: ctx,
|
|
42
|
+
lastUnallowed: orderR.lastUnallowed,
|
|
43
|
+
path: '$["@context"]',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// domain_constraint_violation (deviation #6 partial closure, deferral F):
|
|
49
|
+
// root-level cardinality constraints from spec §5.x. v0.3 (Path A) removed
|
|
50
|
+
// the stale v0.2 constraints on Waybill.shipmentInformation /
|
|
51
|
+
// Shipment.containedPieces (Path A replaced those field names with shipment
|
|
52
|
+
// / pieces). Future expansion: AWB consistency, total-pieces/weight sums,
|
|
53
|
+
// and reference resolvability.
|
|
54
|
+
if (typeof input === 'object' && input !== null && !Array.isArray(input)) {
|
|
55
|
+
const violation = checkDomainConstraints(rootClass, input);
|
|
56
|
+
if (violation) {
|
|
57
|
+
return {
|
|
58
|
+
ok: false,
|
|
59
|
+
error: {
|
|
60
|
+
kind: 'domain_constraint_violation',
|
|
61
|
+
className: violation.className,
|
|
62
|
+
field: violation.field,
|
|
63
|
+
expected: violation.expected,
|
|
64
|
+
specRef: violation.specRef,
|
|
65
|
+
path: `$.${violation.field}`,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const seen = new Map(); // @id -> first path seen
|
|
71
|
+
// Path-keyed @type lookup: maps each object node's path to its declared
|
|
72
|
+
// (or root-defaulted) @type. Used to resolve the containing class when
|
|
73
|
+
// checking wrong_type_for_endpoint / missing_id at any depth.
|
|
74
|
+
const pathToType = new Map();
|
|
75
|
+
pathToType.set('$', rootClass);
|
|
76
|
+
let firstError;
|
|
77
|
+
const walkR = walkGraph(input, {}, (node, path, _depth) => {
|
|
78
|
+
if (firstError)
|
|
79
|
+
return; // short-circuit on first error
|
|
80
|
+
// iri_not_canonical: check every IRI-shaped string value in the
|
|
81
|
+
// graph (deviation #9 closure, deferral D). Runs before the
|
|
82
|
+
// object-only checks below because string values are visited
|
|
83
|
+
// separately by walkGraph.
|
|
84
|
+
if (typeof node === 'string' && looksLikeIri(node)) {
|
|
85
|
+
const r = checkIriCanonical(node);
|
|
86
|
+
if (!r.canonical && r.reason) {
|
|
87
|
+
firstError = {
|
|
88
|
+
kind: 'iri_not_canonical',
|
|
89
|
+
iri: node,
|
|
90
|
+
reason: r.reason,
|
|
91
|
+
path,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (typeof node !== 'object' || node === null || Array.isArray(node))
|
|
97
|
+
return;
|
|
98
|
+
const obj = node;
|
|
99
|
+
const id = typeof obj['@id'] === 'string' ? obj['@id'] : undefined;
|
|
100
|
+
const type = typeof obj['@type'] === 'string' ? obj['@type'] : undefined;
|
|
101
|
+
// Record this object's @type by path so children can find their
|
|
102
|
+
// containing class. Falls back to rootClass for the root path.
|
|
103
|
+
if (type)
|
|
104
|
+
pathToType.set(path, type);
|
|
105
|
+
// missing_type: every non-leaf node must declare @type
|
|
106
|
+
if (!type && hasObjectChildren(obj)) {
|
|
107
|
+
firstError = { kind: 'missing_type', path };
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const parentField = pathToParentField(path);
|
|
111
|
+
const containingClass = parentField ? containingClassFor(path, pathToType) : undefined;
|
|
112
|
+
// missing_id: nodes embedded in cross-reference positions must have @id.
|
|
113
|
+
// Cross-reference positions are fields in FIELD_TYPES for the containing class.
|
|
114
|
+
if (parentField && containingClass && !id && requiresId(parentField, containingClass)) {
|
|
115
|
+
firstError = {
|
|
116
|
+
kind: 'missing_id',
|
|
117
|
+
objectType: type ?? 'unknown',
|
|
118
|
+
path,
|
|
119
|
+
};
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// duplicate_id_in_graph
|
|
123
|
+
if (id) {
|
|
124
|
+
if (seen.has(id)) {
|
|
125
|
+
firstError = { kind: 'duplicate_id_in_graph', iri: id, path };
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
seen.set(id, path);
|
|
129
|
+
}
|
|
130
|
+
// wrong_type_for_endpoint: embedded @type must match the field's
|
|
131
|
+
// expected class. Now checked at any depth — containing class
|
|
132
|
+
// resolved via the path-keyed @type map.
|
|
133
|
+
if (type && parentField && containingClass) {
|
|
134
|
+
const expected = expectedTypeFor(containingClass, parentField);
|
|
135
|
+
if (expected && expected !== '*' && expected !== type) {
|
|
136
|
+
firstError = {
|
|
137
|
+
kind: 'wrong_type_for_endpoint',
|
|
138
|
+
expected,
|
|
139
|
+
got: type,
|
|
140
|
+
path,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
if (!walkR.ok)
|
|
146
|
+
return walkR; // safety-limit error
|
|
147
|
+
if (firstError)
|
|
148
|
+
return { ok: false, error: firstError };
|
|
149
|
+
return { ok: true, value: true };
|
|
150
|
+
}
|
|
151
|
+
function hasObjectChildren(obj) {
|
|
152
|
+
for (const v of Object.values(obj)) {
|
|
153
|
+
if (typeof v === 'object' && v !== null)
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Path format: `$`, `$.<field>`, `$.<field>[<n>]`, `$.<field>.<sub>`,
|
|
160
|
+
* `$.<field>[<n>].<sub>`. Returns the immediate parent field name.
|
|
161
|
+
* Returns `undefined` for the root path `$`.
|
|
162
|
+
*/
|
|
163
|
+
function pathToParentField(path) {
|
|
164
|
+
if (path === '$')
|
|
165
|
+
return undefined;
|
|
166
|
+
const last = path.split('.').pop();
|
|
167
|
+
if (!last)
|
|
168
|
+
return undefined;
|
|
169
|
+
return last.replace(/\[\d+\]$/, ''); // strip array index suffix
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Resolve the containing class for the node at `path` by looking up the
|
|
173
|
+
* @type recorded at the parent object's path. Skips array-index segments
|
|
174
|
+
* (those don't carry their own @type).
|
|
175
|
+
*
|
|
176
|
+
* Examples (rootClass = 'Waybill'):
|
|
177
|
+
* - `$.shipment` → parent path `$` → 'Waybill'
|
|
178
|
+
* - `$.shipment.involvedParties` → parent path `$.shipment`
|
|
179
|
+
* → whatever @type was declared on that node (typically 'Shipment')
|
|
180
|
+
* - `$.pieces[0]` → strip `[0]` then `.pieces` → '$' → 'Waybill' (via Shipment)
|
|
181
|
+
* (the array container itself isn't an object node so we step past it)
|
|
182
|
+
* - `$.pieces[0].dimensions` → parent path `$.pieces[0]`
|
|
183
|
+
* → @type at that path (typically 'Piece')
|
|
184
|
+
*/
|
|
185
|
+
function containingClassFor(path, pathToType) {
|
|
186
|
+
if (path === '$')
|
|
187
|
+
return undefined;
|
|
188
|
+
// Strip the trailing `.field` or `[N]` segment to get the parent path.
|
|
189
|
+
const stripped = path.replace(/\[\d+\]$/, '');
|
|
190
|
+
const lastDot = stripped.lastIndexOf('.');
|
|
191
|
+
if (lastDot < 0)
|
|
192
|
+
return undefined;
|
|
193
|
+
let parentPath = stripped.slice(0, lastDot);
|
|
194
|
+
if (parentPath === '')
|
|
195
|
+
parentPath = '$';
|
|
196
|
+
return pathToType.get(parentPath);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* A field requires `@id` on referenced nodes if it's in `FIELD_TYPES`
|
|
200
|
+
* for the given containing class (= the field points at another
|
|
201
|
+
* logistics-object node). Scalar fields and unmapped fields don't
|
|
202
|
+
* require `@id`.
|
|
203
|
+
*/
|
|
204
|
+
function requiresId(parentField, containingClass) {
|
|
205
|
+
return expectedTypeFor(containingClass, parentField) !== undefined;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=graph-walk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-walk.js","sourceRoot":"","sources":["../../src/dispatch/graph-walk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type ClassName } from '../factory-classes.js';
|
|
2
|
+
import type { ParseResult } from '../result.js';
|
|
3
|
+
/**
|
|
4
|
+
* Build the per-class deserialize map by wrapping each module's
|
|
5
|
+
* `deserialize<ClassName>` function with the graph-walk pre-pass.
|
|
6
|
+
*
|
|
7
|
+
* Failure of the graph-walk pre-pass returns the underlying ParseError
|
|
8
|
+
* untouched; per-class Zod validation only runs if the pre-pass passes.
|
|
9
|
+
*/
|
|
10
|
+
type DispatchDeserializeMap = {
|
|
11
|
+
readonly [C in ClassName]: (raw: unknown) => ParseResult<unknown>;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Opt-in dispatch facade per spec §13. Use:
|
|
15
|
+
* import { dispatch } from '@flaks/onerecord'
|
|
16
|
+
* const r = dispatch.deserialize.Waybill(input)
|
|
17
|
+
*
|
|
18
|
+
* Each per-class deserializer runs the graph-walk pre-pass before
|
|
19
|
+
* delegating to the per-class Zod schema. The default per-class
|
|
20
|
+
* deserializers (`WaybillCodec.deserialize`, `onerecord.deserialize.Waybill`)
|
|
21
|
+
* are unchanged — graph-walk is opt-in.
|
|
22
|
+
*
|
|
23
|
+
* For state-bound graph-walk (per-call limits, IRI strategy etc.), use
|
|
24
|
+
* `createMapper({ graphWalk: true })` instead.
|
|
25
|
+
*/
|
|
26
|
+
export declare const dispatch: Readonly<{
|
|
27
|
+
deserialize: Readonly<DispatchDeserializeMap>;
|
|
28
|
+
}>;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dispatch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C;;;;;;GAMG;AACH,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,WAAW,CAAC,OAAO,CAAC;CAClE,CAAA;AAuBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ;;EAEnB,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CLASSES } from '../factory-classes.js';
|
|
2
|
+
import { dispatchGraphWalk } from './graph-walk.js';
|
|
3
|
+
function buildDispatchDeserialize() {
|
|
4
|
+
const out = {};
|
|
5
|
+
for (const className of Object.keys(CLASSES)) {
|
|
6
|
+
const mod = CLASSES[className];
|
|
7
|
+
const fn = mod[`deserialize${className}`];
|
|
8
|
+
if (typeof fn !== 'function') {
|
|
9
|
+
throw new Error(`dispatch: deserialize${className} not found on module — check src/factory-classes.ts and src/classes/${className.toLowerCase()}/index.ts`);
|
|
10
|
+
}
|
|
11
|
+
out[className] = (raw) => {
|
|
12
|
+
const walkR = dispatchGraphWalk(raw, className);
|
|
13
|
+
if (!walkR.ok)
|
|
14
|
+
return walkR;
|
|
15
|
+
return fn(raw);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Opt-in dispatch facade per spec §13. Use:
|
|
22
|
+
* import { dispatch } from '@flaks/onerecord'
|
|
23
|
+
* const r = dispatch.deserialize.Waybill(input)
|
|
24
|
+
*
|
|
25
|
+
* Each per-class deserializer runs the graph-walk pre-pass before
|
|
26
|
+
* delegating to the per-class Zod schema. The default per-class
|
|
27
|
+
* deserializers (`WaybillCodec.deserialize`, `onerecord.deserialize.Waybill`)
|
|
28
|
+
* are unchanged — graph-walk is opt-in.
|
|
29
|
+
*
|
|
30
|
+
* For state-bound graph-walk (per-call limits, IRI strategy etc.), use
|
|
31
|
+
* `createMapper({ graphWalk: true })` instead.
|
|
32
|
+
*/
|
|
33
|
+
export const dispatch = Object.freeze({
|
|
34
|
+
deserialize: Object.freeze(buildDispatchDeserialize()),
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dispatch/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,uBAAuB,CAAA;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAanD,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,EAA+D,CAAA;IAC3E,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAgB,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAA4B,CAAA;QACzD,MAAM,EAAE,GAAG,GAAG,CAAC,cAAc,SAAS,EAAE,CAE3B,CAAA;QACb,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,wBAAwB,SAAS,uEAAuE,SAAS,CAAC,WAAW,EAAE,WAAW,CAC3I,CAAA;QACH,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,GAAY,EAAwB,EAAE;YACtD,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YAC/C,IAAI,CAAC,KAAK,CAAC,EAAE;gBAAE,OAAO,KAAK,CAAA;YAC3B,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;QAChB,CAAC,CAAA;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,wBAAwB,EAAE,CAAC;CACvD,CAAC,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per RFC 3987 + spec §3.2 the canonical IRI form requires:
|
|
3
|
+
* - scheme in lowercase (`https` not `HTTPS`)
|
|
4
|
+
* - host in lowercase (`example.com` not `EXAMPLE.COM`)
|
|
5
|
+
* - no default port (omit `:443` for https, `:80` for http)
|
|
6
|
+
*
|
|
7
|
+
* Percent-encoding case (uppercase hex) is intentionally NOT checked
|
|
8
|
+
* here — modern URL parsers already normalize it, and the false-positive
|
|
9
|
+
* surface in v0.2 is too high.
|
|
10
|
+
*
|
|
11
|
+
* Used by `dispatchGraphWalk` to emit `iri_not_canonical` for non-canonical
|
|
12
|
+
* IRIs anywhere in the graph. Default deserializers (v0.1.x compat) do
|
|
13
|
+
* NOT run this check; it's only fired through the opt-in dispatch path.
|
|
14
|
+
*/
|
|
15
|
+
/** True if `s` looks like an IRI (has a `scheme:` prefix). */
|
|
16
|
+
export declare function looksLikeIri(s: string): boolean;
|
|
17
|
+
export type IriCanonicalReason = 'scheme_not_lowercase' | 'host_not_lowercase' | 'default_port';
|
|
18
|
+
export interface IriCanonicalResult {
|
|
19
|
+
canonical: boolean;
|
|
20
|
+
reason?: IriCanonicalReason;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check whether `s` is in canonical form per RFC 3987 + spec §3.2.
|
|
24
|
+
* Non-IRI strings (no scheme prefix) return `{ canonical: true }` —
|
|
25
|
+
* other validators (Zod schemas, safeIri) handle the malformed case.
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkIriCanonical(s: string): IriCanonicalResult;
|
|
28
|
+
//# sourceMappingURL=iri-canonical.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iri-canonical.d.ts","sourceRoot":"","sources":["../../src/dispatch/iri-canonical.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAE/C;AAED,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,GAAG,oBAAoB,GAAG,cAAc,CAAA;AAE/F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,kBAAkB,CA+B/D"}
|