@burdenoff/microfe-movethewheels 2026.1010.2 → 2026.1011.2

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.
Files changed (38) hide show
  1. package/dist/MoveTheWheelsRoot.js +12 -1
  2. package/dist/MoveTheWheelsRoutes.js +57 -49
  3. package/dist/generated/shipment-status-authority-operations.d.ts +4473 -0
  4. package/dist/generated/tracking-quality-operations.d.ts +4302 -0
  5. package/dist/hooks/useEpod.js +85 -77
  6. package/dist/hooks/useShipmentStatusAuthority.js +127 -0
  7. package/dist/hooks/useTracking.js +15 -14
  8. package/dist/hooks/useTrackingEventQuality.js +60 -0
  9. package/dist/movethewheels/hooks/useEpod.d.ts +23 -0
  10. package/dist/movethewheels/hooks/useShipmentStatusAuthority.d.ts +23 -0
  11. package/dist/movethewheels/hooks/useTrackingEventQuality.d.ts +18 -0
  12. package/dist/movethewheels/pages/ShipmentStatusAuthorityPage.d.ts +1 -0
  13. package/dist/movethewheels/pages/TrackingEventQualityPage.d.ts +1 -0
  14. package/dist/movethewheels/utils/shipmentStatusDraft.d.ts +45 -0
  15. package/dist/node_modules/lucide-react/dist/esm/icons/radio-tower.js +36 -0
  16. package/dist/pages/DeliveryCapturePage.js +181 -116
  17. package/dist/pages/ShipmentStatusAuthorityPage.js +563 -0
  18. package/dist/pages/TrackingEventQualityPage.js +224 -0
  19. package/dist/src/generated/shipment-status-authority-operations.js +86 -0
  20. package/dist/src/generated/tracking-quality-operations.js +44 -0
  21. package/dist/utils/shipmentStatusDraft.js +41 -0
  22. package/package.json +16 -7
  23. package/patches/README.md +25 -0
  24. package/patches/braces@3.0.3.patch +87 -0
  25. package/src/generated/shipment-status-authority-operations.ts +5503 -0
  26. package/src/generated/tracking-quality-operations.ts +5323 -0
  27. package/src/movethewheels/MoveTheWheelsRoot.tsx +14 -0
  28. package/src/movethewheels/MoveTheWheelsRoutes.tsx +4 -0
  29. package/src/movethewheels/hooks/useEpod.ts +47 -12
  30. package/src/movethewheels/hooks/useShipmentStatusAuthority.ts +179 -0
  31. package/src/movethewheels/hooks/useTracking.ts +27 -12
  32. package/src/movethewheels/hooks/useTrackingEventQuality.ts +110 -0
  33. package/src/movethewheels/pages/DeliveryCapturePage.tsx +113 -6
  34. package/src/movethewheels/pages/ShipmentStatusAuthorityPage.tsx +639 -0
  35. package/src/movethewheels/pages/TrackingEventQualityPage.tsx +250 -0
  36. package/src/movethewheels/utils/shipmentStatusDraft.ts +118 -0
  37. package/src/operations/shipment-status-authority/status.graphql +80 -0
  38. package/src/operations/tracking-quality/quality.graphql +15 -0
@@ -0,0 +1,224 @@
1
+ import { RadioTower as e } from "../node_modules/lucide-react/dist/esm/icons/radio-tower.js";
2
+ import { useMoveTheWheels as t } from "../providers/MoveTheWheelsProvider.js";
3
+ import { Button as n } from "../components/ui.js";
4
+ import { PageLayout as r } from "../components/PageLayout.js";
5
+ import { useConditionQuery as i } from "../hooks/useContainerCondition.js";
6
+ import { ReuseState as a, reuseCard as o, reuseSelect as s } from "../components/ReuseControls.js";
7
+ import { TrackingQualityDeliveriesDocument as c, TrackingQualityIntegrationsDocument as l, TrackingQualityShipmentDocument as u } from "../src/generated/tracking-quality-operations.js";
8
+ import { trackingOutcomes as d } from "../hooks/useTrackingEventQuality.js";
9
+ import { useState as f } from "react";
10
+ import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
11
+ //#region src/movethewheels/pages/TrackingEventQualityPage.tsx
12
+ var g = 20;
13
+ function _({ offset: e, length: t, busy: r, onChange: i }) {
14
+ return /* @__PURE__ */ h("div", {
15
+ className: "flex flex-wrap items-center gap-3",
16
+ children: [
17
+ /* @__PURE__ */ m(n, {
18
+ variant: "outline",
19
+ disabled: r || e === 0,
20
+ onClick: () => i(Math.max(0, e - g)),
21
+ children: "Previous page"
22
+ }),
23
+ /* @__PURE__ */ m("span", { children: t === void 0 ? "Page unavailable" : `${t} records on this page` }),
24
+ /* @__PURE__ */ m(n, {
25
+ variant: "outline",
26
+ disabled: r || t !== g || e >= 9980,
27
+ onClick: () => i(e + g),
28
+ children: "Next page"
29
+ })
30
+ ]
31
+ });
32
+ }
33
+ function v() {
34
+ let { workspaceId: n, tenantId: i, currentUser: a, apiGatewayUrl: o } = t();
35
+ return /* @__PURE__ */ m(r, {
36
+ title: "Tracking event quality",
37
+ subtitle: "Review delivery results before investigating a shipment.",
38
+ icon: /* @__PURE__ */ m(e, { "aria-hidden": "true" }),
39
+ children: /* @__PURE__ */ m(y, {}, `${n}:${i}:${a?.id}:${o}`)
40
+ });
41
+ }
42
+ function y() {
43
+ let [e, t] = f(0), [r, u] = f(""), [p, v] = f(0), [y, x] = f(0), [S, C] = f(null), w = i(l, { pagination: {
44
+ limit: g,
45
+ offset: e
46
+ } }, y), T = i(c, r ? {
47
+ id: r,
48
+ pagination: {
49
+ limit: g,
50
+ offset: p
51
+ }
52
+ } : null, y), E = w.data?.integrations, D = T.data?.integration?.events;
53
+ return /* @__PURE__ */ h("div", {
54
+ className: "space-y-6",
55
+ children: [
56
+ /* @__PURE__ */ m("p", { children: "Matching event keys and payloads create no additional tracking event. A changed payload with the same key is a conflict. Updates without a key can create new events." }),
57
+ /* @__PURE__ */ m("p", { children: "Each delivery admits at most five updates. An oversized or malformed delivery is rejected before updates are recorded. Delivery history can include older records without item results." }),
58
+ /* @__PURE__ */ h("section", {
59
+ className: o,
60
+ "aria-label": "Integration selection",
61
+ children: [
62
+ /* @__PURE__ */ m(a, {
63
+ loading: w.loading,
64
+ error: w.error
65
+ }),
66
+ E?.length === 0 && /* @__PURE__ */ m("p", { children: "No integrations on this page." }),
67
+ /* @__PURE__ */ h("label", {
68
+ className: "block",
69
+ children: ["Integration", /* @__PURE__ */ h("select", {
70
+ className: s,
71
+ value: r,
72
+ disabled: !E || w.loading,
73
+ onChange: (e) => {
74
+ u(e.target.value), v(0), C(null);
75
+ },
76
+ children: [/* @__PURE__ */ m("option", {
77
+ value: "",
78
+ children: "Choose an integration"
79
+ }), E?.map((e) => /* @__PURE__ */ h("option", {
80
+ value: e.id,
81
+ children: [
82
+ e.name,
83
+ " · ",
84
+ e.provider,
85
+ " · ",
86
+ e.status
87
+ ]
88
+ }, e.id))]
89
+ })]
90
+ }),
91
+ /* @__PURE__ */ m(_, {
92
+ offset: e,
93
+ length: E?.length,
94
+ busy: w.loading,
95
+ onChange: (e) => {
96
+ t(e), u(""), v(0), C(null);
97
+ }
98
+ })
99
+ ]
100
+ }),
101
+ r && /* @__PURE__ */ h("section", {
102
+ className: "space-y-4 rounded-xl border bg-bg-surface p-5",
103
+ "aria-label": "Tracking delivery history",
104
+ children: [
105
+ /* @__PURE__ */ h("div", {
106
+ className: "flex flex-wrap items-center justify-between gap-3",
107
+ children: [/* @__PURE__ */ m("h2", {
108
+ className: "text-lg font-semibold",
109
+ children: "Delivery history"
110
+ }), /* @__PURE__ */ m(n, {
111
+ variant: "outline",
112
+ disabled: T.loading,
113
+ onClick: () => x((e) => e + 1),
114
+ children: "Refresh results"
115
+ })]
116
+ }),
117
+ /* @__PURE__ */ m(a, {
118
+ loading: T.loading,
119
+ error: T.error
120
+ }),
121
+ T.data?.integration === null && /* @__PURE__ */ m("p", {
122
+ role: "status",
123
+ children: "Integration unavailable in this workspace."
124
+ }),
125
+ D?.length === 0 && /* @__PURE__ */ m("p", { children: "No deliveries on this page." }),
126
+ D?.map((e) => {
127
+ let t = d(e.outcomes);
128
+ return /* @__PURE__ */ h("article", {
129
+ className: "space-y-3 rounded-lg border p-4",
130
+ children: [/* @__PURE__ */ h("h3", {
131
+ className: "font-semibold",
132
+ children: [
133
+ e.status,
134
+ " · ",
135
+ new Date(e.receivedAt).toLocaleString()
136
+ ]
137
+ }), t === null ? /* @__PURE__ */ m("p", { children: "Per-update results unavailable for this delivery." }) : t.length === 0 ? /* @__PURE__ */ m("p", { children: "No normalized updates were attempted. This is not a count of raw sender items." }) : /* @__PURE__ */ m("ol", {
138
+ className: "space-y-3",
139
+ children: t.map((e) => /* @__PURE__ */ h("li", {
140
+ className: "break-words rounded-md bg-bg-surface p-3",
141
+ children: [
142
+ /* @__PURE__ */ h("p", { children: [
143
+ "Update ",
144
+ e.index + 1,
145
+ ": ",
146
+ /* @__PURE__ */ m("strong", { children: e.status })
147
+ ] }),
148
+ /* @__PURE__ */ h("p", { children: ["Event key: ", e.externalEventId ?? "Missing — not deduplicated"] }),
149
+ /* @__PURE__ */ h("p", { children: ["Shipment reference: ", e.shipmentReference || "Not recorded"] }),
150
+ e.errorCode && /* @__PURE__ */ h("p", { children: ["Reason: ", e.errorCode.replaceAll("_", " ").toLowerCase()] }),
151
+ (e.status === "ACCEPTED" || e.status === "DUPLICATE") && /* @__PURE__ */ h("p", { children: [
152
+ "Status decision:",
153
+ " ",
154
+ e.projection?.status === "APPLIED" ? "Applied to the recorded shipment status" : e.projection?.status === "HELD" ? `Held — ${e.projection.heldReason?.replaceAll("_", " ").toLowerCase()}` : "No status decision recorded in this legacy result"
155
+ ] }),
156
+ e.status === "CONFLICT" && /* @__PURE__ */ m("p", { children: "The earlier receipt stays unchanged; this update adds no event." }),
157
+ e.shipmentId && /* @__PURE__ */ m(n, {
158
+ variant: "outline",
159
+ onClick: () => C(e.shipmentId),
160
+ children: "View shipment"
161
+ })
162
+ ]
163
+ }, e.index))
164
+ })]
165
+ }, e.id);
166
+ }),
167
+ /* @__PURE__ */ m(_, {
168
+ offset: p,
169
+ length: D?.length,
170
+ busy: T.loading,
171
+ onChange: v
172
+ })
173
+ ]
174
+ }),
175
+ S && /* @__PURE__ */ m(b, {
176
+ id: S,
177
+ onClose: () => C(null)
178
+ }, S),
179
+ /* @__PURE__ */ m("p", {
180
+ className: "text-sm text-text-secondary",
181
+ children: "These results describe recorded ingestion, not physical shipment truth. The chosen-source clock policy and manual corrections control recorded shipment status. Provider corrections and replay need separate reviewed policies."
182
+ })
183
+ ]
184
+ });
185
+ }
186
+ function b({ id: e, onClose: t }) {
187
+ let r = i(u, { id: e });
188
+ return /* @__PURE__ */ h("section", {
189
+ className: o,
190
+ "aria-label": "Shipment tracking summary",
191
+ children: [
192
+ /* @__PURE__ */ m("h2", {
193
+ className: "text-lg font-semibold",
194
+ children: "Shipment tracking summary"
195
+ }),
196
+ /* @__PURE__ */ m(n, {
197
+ variant: "outline",
198
+ onClick: t,
199
+ children: "Close shipment summary"
200
+ }),
201
+ /* @__PURE__ */ m(a, {
202
+ loading: r.loading,
203
+ error: r.error
204
+ }),
205
+ r.data?.shipment === null && /* @__PURE__ */ m("p", { children: "Shipment unavailable in this workspace." }),
206
+ r.data?.shipment && /* @__PURE__ */ h(p, { children: [
207
+ /* @__PURE__ */ h("p", { children: [
208
+ r.data.shipment.shipmentNumber,
209
+ " · ",
210
+ r.data.shipment.status
211
+ ] }),
212
+ /* @__PURE__ */ h("p", { children: ["Tracking number: ", r.data.shipment.trackingNumber ?? "Not recorded"] }),
213
+ /* @__PURE__ */ h("p", { children: [r.data.shipment.trackingEvents.length, " tracking events on the first page (up to 20)."] }),
214
+ /* @__PURE__ */ m("ul", { children: r.data.shipment.trackingEvents.map((e) => /* @__PURE__ */ h("li", { children: [
215
+ e.eventType,
216
+ " · ",
217
+ new Date(e.timestamp).toLocaleString()
218
+ ] }, e.id)) })
219
+ ] })
220
+ ]
221
+ });
222
+ }
223
+ //#endregion
224
+ export { v as default };
@@ -0,0 +1,86 @@
1
+ import { gql as e } from "@apollo/client";
2
+ //#region src/generated/shipment-status-authority-operations.ts
3
+ var t = e`
4
+ fragment ShipmentStatusAuthorityFields on MtwShipment {
5
+ id
6
+ shipmentNumber
7
+ status
8
+ statusRevision
9
+ statusAuthority
10
+ statusAuthorityEpoch
11
+ designatedIntegrationId
12
+ statusBasisEventId
13
+ statusBasisSourceTime
14
+ maxSourceAgeSeconds
15
+ maxFutureSkewSeconds
16
+ }
17
+ `, n = e`
18
+ query StatusAuthorityShipments($filter: ShipmentFilterInput, $pagination: PaginationInput!) {
19
+ shipments(filter: $filter, pagination: $pagination) {
20
+ ...ShipmentStatusAuthorityFields
21
+ }
22
+ }
23
+ ${t}`, r = e`
24
+ query StatusAuthorityDetail($id: ID!, $pagination: PaginationInput!, $evidencePagination: PaginationInput!) {
25
+ shipment(id: $id) {
26
+ ...ShipmentStatusAuthorityFields
27
+ trackingEvents(pagination: $evidencePagination) {
28
+ id
29
+ eventType
30
+ sourceIntegrationId
31
+ sourceTimestampProvenance
32
+ providerEventTime
33
+ serverReceivedAt
34
+ timestamp
35
+ }
36
+ }
37
+ shipmentStatusDecisions(shipmentId: $id, pagination: $pagination) {
38
+ id
39
+ origin
40
+ outcome
41
+ heldReason
42
+ observedRevision
43
+ resultRevision
44
+ priorStatus
45
+ resultStatus
46
+ trackingEventId
47
+ proofId
48
+ reason
49
+ recordedAt
50
+ configuredIntegrationId
51
+ configuredMaxSourceAgeSeconds
52
+ configuredMaxFutureSkewSeconds
53
+ }
54
+ }
55
+ ${t}`, i = e`
56
+ query StatusAuthoritySources($pagination: PaginationInput!) {
57
+ integrations(pagination: $pagination) {
58
+ id
59
+ name
60
+ provider
61
+ status
62
+ }
63
+ }
64
+ `, a = e`
65
+ mutation StatusAuthorityConfigure($id: ID!, $input: ConfigureShipmentStatusSourceInput!) {
66
+ configureShipmentStatusSource(id: $id, input: $input) {
67
+ ...ShipmentStatusAuthorityFields
68
+ }
69
+ }
70
+ ${t}`, o = e`
71
+ mutation StatusAuthorityManual($id: ID!, $input: UpdateShipmentInput!) {
72
+ updateShipment(id: $id, input: $input) {
73
+ ...ShipmentStatusAuthorityFields
74
+ }
75
+ }
76
+ ${t}`, s = e`
77
+ query StatusAuthorityOwnedDelivery($deliveryJobId: ID!) {
78
+ myEpodShipmentStatus(deliveryJobId: $deliveryJobId) {
79
+ id
80
+ status
81
+ statusRevision
82
+ }
83
+ }
84
+ `;
85
+ //#endregion
86
+ export { a as StatusAuthorityConfigureDocument, r as StatusAuthorityDetailDocument, o as StatusAuthorityManualDocument, s as StatusAuthorityOwnedDeliveryDocument, n as StatusAuthorityShipmentsDocument, i as StatusAuthoritySourcesDocument };
@@ -0,0 +1,44 @@
1
+ import { gql as e } from "@apollo/client";
2
+ //#region src/generated/tracking-quality-operations.ts
3
+ var t = e`
4
+ query TrackingQualityIntegrations($pagination: PaginationInput!) {
5
+ integrations(pagination: $pagination) {
6
+ id
7
+ name
8
+ provider
9
+ status
10
+ }
11
+ }
12
+ `, n = e`
13
+ query TrackingQualityDeliveries($id: ID!, $pagination: PaginationInput!) {
14
+ integration(id: $id) {
15
+ id
16
+ name
17
+ provider
18
+ status
19
+ events(pagination: $pagination) {
20
+ id
21
+ status
22
+ receivedAt
23
+ processedAt
24
+ outcomes
25
+ }
26
+ }
27
+ }
28
+ `, r = e`
29
+ query TrackingQualityShipment($id: ID!) {
30
+ shipment(id: $id) {
31
+ id
32
+ shipmentNumber
33
+ status
34
+ trackingNumber
35
+ trackingEvents(pagination: {limit: 20, offset: 0}) {
36
+ id
37
+ eventType
38
+ timestamp
39
+ }
40
+ }
41
+ }
42
+ `;
43
+ //#endregion
44
+ export { n as TrackingQualityDeliveriesDocument, t as TrackingQualityIntegrationsDocument, r as TrackingQualityShipmentDocument };
@@ -0,0 +1,41 @@
1
+ //#region src/movethewheels/utils/shipmentStatusDraft.ts
2
+ function e(e) {
3
+ let t = e.trim();
4
+ if (!t || t.length > 1e3) throw Error("Enter a reason of 1–1000 characters.");
5
+ return t;
6
+ }
7
+ function t(e, t, n, r) {
8
+ if (!/^\d+$/.test(e.trim())) throw Error(`${r} must be an explicit whole number of seconds.`);
9
+ let i = Number(e.trim());
10
+ if (!Number.isSafeInteger(i) || i < t || i > n) throw Error(`${r} must be between ${t} and ${n} seconds.`);
11
+ return i;
12
+ }
13
+ function n(n, r) {
14
+ if (!n.integrationId || !n.basisTrackingEventId) throw Error("Choose one integration and one recorded basis event.");
15
+ return {
16
+ expectedStatusRevision: r,
17
+ integrationId: n.integrationId,
18
+ basisTrackingEventId: n.basisTrackingEventId,
19
+ maxSourceAgeSeconds: t(n.maxSourceAgeSeconds, 1, 2592e3, "Maximum source age"),
20
+ maxFutureSkewSeconds: t(n.maxFutureSkewSeconds, 0, 86400, "Allowed future skew"),
21
+ reason: e(n.reason)
22
+ };
23
+ }
24
+ function r(e, t) {
25
+ let n = {
26
+ PICKED_UP: "PICKED_UP",
27
+ IN_TRANSIT: "IN_TRANSIT",
28
+ ARRIVED: "IN_TRANSIT",
29
+ DEPARTED: "IN_TRANSIT",
30
+ OUT_FOR_DELIVERY: "IN_TRANSIT",
31
+ DELIVERED: "DELIVERED",
32
+ FAILED: "FAILED",
33
+ RETURNED: "RETURNED"
34
+ }, r = t.basis, i = r?.providerEventTime ? Date.parse(r.providerEventTime) : NaN;
35
+ return !!e && !!r && Number.isFinite(i) && e.id === t.id && e.statusRevision === t.input.expectedStatusRevision + 1 && e.statusAuthority === "INTEGRATION_EVENT_TIME" && e.statusAuthorityEpoch === t.epoch + 1 && e.designatedIntegrationId === t.input.integrationId && e.statusBasisEventId === r.id && r.id === t.input.basisTrackingEventId && typeof e.statusBasisSourceTime == "string" && Date.parse(e.statusBasisSourceTime) === i && e.maxSourceAgeSeconds === t.input.maxSourceAgeSeconds && e.maxFutureSkewSeconds === t.input.maxFutureSkewSeconds && typeof n[r.eventType] == "string" && e.status === n[r.eventType];
36
+ }
37
+ function i(e, t) {
38
+ return !!e && e.id === t.id && e.statusRevision === t.revision + 1 && e.status === t.status && e.statusAuthority === "MANUAL_HOLD" && e.statusAuthorityEpoch === t.epoch + 1 && e.designatedIntegrationId === null && e.statusBasisEventId === null && e.statusBasisSourceTime === null && e.maxSourceAgeSeconds === null && e.maxFutureSkewSeconds === null;
39
+ }
40
+ //#endregion
41
+ export { i as manualStatusAcknowledged, n as shipmentSourceInput, r as sourceStatusAcknowledged, e as statusDecisionReason };
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-movethewheels",
3
- "version": "2026.1010.2",
3
+ "version": "2026.1011.2",
4
4
  "description": "Burdenoff MoveTheWheels Microfrontend - Logistics & Supply Chain Management Platform",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "src",
8
8
  "dist",
9
- "package.json"
9
+ "package.json",
10
+ "patches"
10
11
  ],
11
12
  "imports": {
12
13
  "#src/*": "./src/*",
@@ -34,7 +35,7 @@
34
35
  "format": "prettier --write \"src/**/*.{ts,tsx}\"",
35
36
  "type:check": "bash scripts/build-limits.sh tsc --noEmit",
36
37
  "validate:schema-drift": "graphql-schema-drift",
37
- "sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run build && bun run build-storybook'",
38
+ "sanity": "bash scripts/build-limits.sh --gate bash -c 'bun run codegen && bun run validate:schema-drift && bun run lint:sanity && bun run format && bun run type:check && bun run verify:live-logistics-contract && bun run verify:empty-reuse-retry && bun run verify:empty-reuse-recovery && bun run verify:trip-utilization-input && bun run verify:trip-draft-context && bun run verify:stock-binding-input && bun run verify:stock-observation-input && bun run verify:pending-pick-input && bun run verify:freight-input && bun run verify:freight-recovery && bun run verify:procedure-input && bun run verify:consolidation && bun run verify:multimodal-single-attempt && bun run verify:tracking-quality-outcomes && bun run verify:shipment-status-authority && bun run verify:braces-depth && bun run build && bun run build-storybook'",
38
39
  "storybook": "storybook dev -p 6006",
39
40
  "build-storybook": "storybook build",
40
41
  "test:storybook": "test-storybook",
@@ -42,7 +43,7 @@
42
43
  "schema:pull:introspect": "bash scripts/schema-pull.sh --mode introspect",
43
44
  "schema:check": "bash scripts/schema-pull.sh --check",
44
45
  "verify:stock-binding-input": "bun scripts/verify-stock-binding-input.mjs",
45
- "codegen": "graphql-codegen --project wspace && graphql-codegen --project container-foundation && graphql-codegen --project container-condition && graphql-codegen --project free-time && graphql-codegen --project empty-reuse && graphql-codegen --project trip-utilization && graphql-codegen --project stock-binding && graphql-codegen --project stock-observation && graphql-codegen --project pending-pick && graphql-codegen --project freight-cost && graphql-codegen --project logistics-procedure && graphql-codegen --project consolidation",
46
+ "codegen": "graphql-codegen --project wspace && graphql-codegen --project container-foundation && graphql-codegen --project container-condition && graphql-codegen --project free-time && graphql-codegen --project empty-reuse && graphql-codegen --project trip-utilization && graphql-codegen --project stock-binding && graphql-codegen --project stock-observation && graphql-codegen --project pending-pick && graphql-codegen --project freight-cost && graphql-codegen --project logistics-procedure && graphql-codegen --project consolidation && graphql-codegen --project tracking-quality && graphql-codegen --project shipment-status-authority",
46
47
  "codegen:all": "bun run schema:pull && bun run codegen",
47
48
  "switch:status": "bun scripts/deps-mode.ts status",
48
49
  "switch:remote": "bun scripts/deps-mode.ts remote",
@@ -59,7 +60,10 @@
59
60
  "verify:freight-input": "bun scripts/verify-freight-input.mjs",
60
61
  "verify:freight-recovery": "bun scripts/verify-freight-recovery-hook.mjs",
61
62
  "verify:procedure-input": "bun scripts/verify-procedure-input.mjs && bun scripts/verify-procedure-recovery-hook.mjs",
62
- "verify:consolidation": "bun scripts/verify-consolidation-input.mjs && bun scripts/verify-consolidation-recovery-hook.mjs && bun scripts/verify-consolidation-mounted-hook.mjs"
63
+ "verify:consolidation": "bun scripts/verify-consolidation-input.mjs && bun scripts/verify-consolidation-recovery-hook.mjs && bun scripts/verify-consolidation-mounted-hook.mjs",
64
+ "verify:tracking-quality-outcomes": "bun test scripts/verify-tracking-quality-outcomes.test.ts",
65
+ "verify:braces-depth": "bun test scripts/braces-depth-patch.test.ts",
66
+ "verify:shipment-status-authority": "bun scripts/verify-shipment-status-command.mjs"
63
67
  },
64
68
  "dependencies": {
65
69
  "@apollo/client": "^4.0.11",
@@ -114,7 +118,8 @@
114
118
  "typescript": "^5.9.0",
115
119
  "typescript-eslint": "^8.54.0",
116
120
  "vite": "8.0.16",
117
- "vite-plugin-dts": "3.9.1"
121
+ "vite-plugin-dts": "3.9.1",
122
+ "braces": "3.0.3"
118
123
  },
119
124
  "peerDependencies": {
120
125
  "@apollo/client": "^4.0.11",
@@ -140,6 +145,10 @@
140
145
  "yaml": ">=2.8.3",
141
146
  "picomatch": ">=2.3.2",
142
147
  "immutable": ">=3.8.3",
143
- "minimatch": ">=3.1.3"
148
+ "minimatch": ">=3.1.3",
149
+ "@graphql-tools/utils": "12.0.3"
150
+ },
151
+ "patchedDependencies": {
152
+ "braces@3.0.3": "patches/braces@3.0.3.patch"
144
153
  }
145
154
  }
@@ -0,0 +1,25 @@
1
+ # Reviewed build dependency mitigation
2
+
3
+ BOFF-9129 tracks the MoveTheWheels build dependency fixes. The canonical frozen
4
+ Bun installation applies `braces@3.0.3.patch` using `patchedDependencies`.
5
+
6
+ The upstream advisory [GHSA-vfj7-8cjw-p6xm](https://github.com/advisories/GHSA-vfj7-8cjw-p6xm)
7
+ currently lists no fixed release. This local patch adds iterative validation before
8
+ recursive parse cleanup, compile, stringify and expand processing: nesting is bounded
9
+ to 128 and AST visits to 65,536, with malformed child and parent cycles rejected.
10
+ It preserves the tested ordinary escaped, quoted, range and nested glob patterns.
11
+
12
+ The version remains 3.0.3. Version-based dependency audits still report this HIGH
13
+ advisory; that result must remain visible with the pinned patch and regression evidence.
14
+ This is a reviewed nesting mitigation, not an upstream fixed-version or clean-audit claim.
15
+ It does not establish general limits on Cartesian expansion or every resource-exhaustion
16
+ pattern. npm installations do not apply Bun patches and must not claim this mitigation.
17
+
18
+ `bun run verify:braces-depth` exercises deeply nested balanced/unbalanced brace and
19
+ parenthesis strings, direct deep/cyclic/oversized ASTs and ordinary pattern semantics.
20
+ Normal `bun run sanity` includes those checks. The exact patch is shared with the
21
+ workspace public gateway (BOFF-9127); independent review covers its installed source.
22
+
23
+ The separate `@graphql-tools/utils` override uses published version 12.0.1 to remove
24
+ GHSA-7mx3-vvmw-hjmv from the actual Bun audit. Other inherited moderate findings remain
25
+ tracked under BOFF-8590. Keep all limitations attached to release evidence.
@@ -0,0 +1,87 @@
1
+ diff --git a/lib/compile.js b/lib/compile.js
2
+ --- a/lib/compile.js
3
+ +++ b/lib/compile.js
4
+ @@ -1,0 +2,2 @@
5
+ +
6
+ +const validateAst = require('./validate-ast');
7
+ @@ -6,0 +9 @@
8
+ + validateAst(ast);
9
+ diff --git a/lib/expand.js b/lib/expand.js
10
+ --- a/lib/expand.js
11
+ +++ b/lib/expand.js
12
+ @@ -1,0 +2,2 @@
13
+ +
14
+ +const validateAst = require('./validate-ast');
15
+ @@ -33,0 +36 @@
16
+ + validateAst(ast);
17
+ diff --git a/lib/parse.js b/lib/parse.js
18
+ --- a/lib/parse.js
19
+ +++ b/lib/parse.js
20
+ @@ -1,0 +2,2 @@
21
+ +
22
+ +const validateAst = require('./validate-ast');
23
+ @@ -146,0 +149 @@
24
+ + if (stack.length >= 128) throw new RangeError('Braces nesting limit exceeded');
25
+ @@ -212,0 +216 @@
26
+ + if (stack.length >= 128) throw new RangeError('Braces nesting limit exceeded');
27
+ @@ -327,0 +332 @@
28
+ + validateAst(ast);
29
+ diff --git a/lib/stringify.js b/lib/stringify.js
30
+ --- a/lib/stringify.js
31
+ +++ b/lib/stringify.js
32
+ @@ -1,0 +2,2 @@
33
+ +
34
+ +const validateAst = require('./validate-ast');
35
+ @@ -5,0 +8 @@
36
+ + validateAst(ast);
37
+ diff --git a/lib/validate-ast.js b/lib/validate-ast.js
38
+ new file mode 100644
39
+ --- /dev/null
40
+ +++ b/lib/validate-ast.js
41
+ @@ -0,0 +1,46 @@
42
+ +'use strict';
43
+ +
44
+ +// Local mitigation for GHSA-vfj7-8cjw-p6xm. Validate iteratively before any
45
+ +// recursive AST processing. Parent/prev links are metadata, not child edges.
46
+ +const MAX_DEPTH = 128;
47
+ +const MAX_NODES = 65536;
48
+ +
49
+ +module.exports = ast => {
50
+ + const pending = [{ node: ast, depth: 0, exit: false }];
51
+ + const active = new WeakSet();
52
+ + let visits = 0;
53
+ + while (pending.length > 0) {
54
+ + const item = pending.pop();
55
+ + const node = item.node;
56
+ + if (item.exit) {
57
+ + active.delete(node);
58
+ + continue;
59
+ + }
60
+ + if (node === null || typeof node !== 'object') throw new TypeError('Invalid braces AST');
61
+ + if (++visits > MAX_NODES) throw new RangeError('Braces AST node limit exceeded');
62
+ + if (item.depth > MAX_DEPTH) throw new RangeError('Braces nesting limit exceeded');
63
+ + if (active.has(node)) throw new RangeError('Cyclic braces AST');
64
+ + // expand() also follows parent links. Reject malformed parent chains before
65
+ + // its loop can hang; normal parser parents lead to the root.
66
+ + let parent = node.parent;
67
+ + const parents = new WeakSet();
68
+ + let parentDepth = 0;
69
+ + while (parent) {
70
+ + if (typeof parent !== 'object' || parents.has(parent) || ++parentDepth > MAX_DEPTH) {
71
+ + throw new RangeError('Invalid braces AST parent chain');
72
+ + }
73
+ + parents.add(parent);
74
+ + parent = parent.parent;
75
+ + }
76
+ + if (node.nodes !== undefined) {
77
+ + if (!Array.isArray(node.nodes)) throw new TypeError('Invalid braces AST children');
78
+ + if (node.nodes.length > MAX_NODES - visits) throw new RangeError('Braces AST node limit exceeded');
79
+ + active.add(node);
80
+ + pending.push({ node, depth: item.depth, exit: true });
81
+ + for (let index = node.nodes.length - 1; index >= 0; index--) {
82
+ + pending.push({ node: node.nodes[index], depth: item.depth + 1, exit: false });
83
+ + }
84
+ + if (pending.length > 2 * MAX_NODES) throw new RangeError('Braces AST node limit exceeded');
85
+ + }
86
+ + }
87
+ +};