@burdenoff/microfe-movethewheels 2026.1016.2 → 2026.1016.4

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 (113) hide show
  1. package/README.md +10 -0
  2. package/dist/MoveTheWheelsRoot.js +5 -0
  3. package/dist/MoveTheWheelsRoutes.js +25 -21
  4. package/dist/components/ContainerEvidencePicker.js +55 -55
  5. package/dist/components/FleetAlertsPanel.js +2 -2
  6. package/dist/components/freight-cost/FreightCommercialEditor.js +217 -0
  7. package/dist/components/freight-cost/FreightCommercialFactEditor.js +217 -0
  8. package/dist/components/freight-cost/FreightCommercialHistory.js +115 -0
  9. package/dist/components/freight-cost/FreightDraftForm.js +106 -91
  10. package/dist/components/freight-cost/FreightHistory.js +42 -40
  11. package/dist/components/freight-invoice/InvoiceForm.js +366 -0
  12. package/dist/components/freight-invoice/InvoiceResults.js +240 -0
  13. package/dist/generated/consolidation-operations.d.ts +195 -265
  14. package/dist/generated/container-condition-operations.d.ts +124 -187
  15. package/dist/generated/container-operations.d.ts +59 -85
  16. package/dist/generated/empty-reuse-operations.d.ts +165 -271
  17. package/dist/generated/free-time-operations.d.ts +120 -184
  18. package/dist/generated/freight-cost-operations.d.ts +955 -165
  19. package/dist/generated/freight-invoice-operations.d.ts +1447 -0
  20. package/dist/generated/logistics-procedure-operations.d.ts +100 -156
  21. package/dist/generated/pending-pick-operations.d.ts +769 -1025
  22. package/dist/generated/shipment-status-authority-operations.d.ts +82 -103
  23. package/dist/generated/stock-binding-operations.d.ts +188 -260
  24. package/dist/generated/stock-observation-operations.d.ts +103 -138
  25. package/dist/generated/tracking-quality-operations.d.ts +27 -41
  26. package/dist/generated/trip-utilization-operations.d.ts +137 -185
  27. package/dist/generated/wspace-operations.d.ts +628 -2272
  28. package/dist/generated/wspace-types.d.ts +4 -23
  29. package/dist/hooks/useFreightRecoveryAction.js +20 -20
  30. package/dist/hooks/useInvoiceComparisonRecovery.js +118 -0
  31. package/dist/movethewheels/components/ContainerEvidencePicker.d.ts +2 -1
  32. package/dist/movethewheels/components/freight-cost/FreightCommercialEditor.d.ts +8 -0
  33. package/dist/movethewheels/components/freight-cost/FreightCommercialFactEditor.d.ts +8 -0
  34. package/dist/movethewheels/components/freight-cost/FreightCommercialHistory.d.ts +4 -0
  35. package/dist/movethewheels/components/freight-cost/FreightDraftForm.d.ts +4 -2
  36. package/dist/movethewheels/components/freight-cost/FreightHistory.d.ts +2 -2
  37. package/dist/movethewheels/components/freight-invoice/InvoiceForm.d.ts +19 -0
  38. package/dist/movethewheels/components/freight-invoice/InvoiceResults.d.ts +9 -0
  39. package/dist/movethewheels/hooks/useFleet.d.ts +1 -1
  40. package/dist/movethewheels/hooks/useFleetIntelligence.d.ts +1 -1
  41. package/dist/movethewheels/hooks/useInvoiceComparisonRecovery.d.ts +22 -0
  42. package/dist/movethewheels/hooks/useProcedureSelection.d.ts +1 -3
  43. package/dist/movethewheels/pages/FreightInvoicePage.d.ts +10 -0
  44. package/dist/movethewheels/utils/driverLicenseExpiry.d.ts +6 -0
  45. package/dist/movethewheels/utils/freightCommercial.d.ts +44 -0
  46. package/dist/movethewheels/utils/invoiceComparison.d.ts +32 -0
  47. package/dist/pages/DriverDetailsPage.js +306 -282
  48. package/dist/pages/FreightEstimatePage.js +97 -92
  49. package/dist/pages/FreightInvoicePage.js +346 -0
  50. package/dist/src/generated/consolidation-operations.js +3961 -503
  51. package/dist/src/generated/container-condition-operations.js +2968 -206
  52. package/dist/src/generated/container-operations.js +997 -99
  53. package/dist/src/generated/empty-reuse-operations.js +4811 -747
  54. package/dist/src/generated/free-time-operations.js +2824 -233
  55. package/dist/src/generated/freight-cost-operations.js +4852 -323
  56. package/dist/src/generated/freight-invoice-operations.js +4894 -0
  57. package/dist/src/generated/logistics-procedure-operations.js +2707 -360
  58. package/dist/src/generated/pending-pick-operations.js +8244 -1196
  59. package/dist/src/generated/shipment-status-authority-operations.js +1157 -84
  60. package/dist/src/generated/stock-binding-operations.js +2779 -173
  61. package/dist/src/generated/stock-observation-operations.js +1274 -91
  62. package/dist/src/generated/tracking-quality-operations.js +407 -42
  63. package/dist/src/generated/trip-utilization-operations.js +1765 -138
  64. package/dist/src/generated/wspace-operations.js +428 -706
  65. package/dist/utils/driverLicenseExpiry.js +14 -0
  66. package/dist/utils/freightAcknowledgement.js +6 -5
  67. package/dist/utils/freightCommercial.js +194 -0
  68. package/dist/utils/freightRecovery.js +22 -22
  69. package/dist/utils/invoiceComparison.js +272 -0
  70. package/package.json +30 -29
  71. package/src/generated/consolidation-operations.ts +60 -559
  72. package/src/generated/container-condition-operations.ts +63 -265
  73. package/src/generated/container-operations.ts +37 -132
  74. package/src/generated/empty-reuse-operations.ts +83 -824
  75. package/src/generated/free-time-operations.ts +55 -284
  76. package/src/generated/freight-cost-operations.ts +373 -349
  77. package/src/generated/freight-invoice-operations.ts +830 -0
  78. package/src/generated/logistics-procedure-operations.ts +60 -414
  79. package/src/generated/pending-pick-operations.ts +48 -1239
  80. package/src/generated/shipment-status-authority-operations.ts +33 -113
  81. package/src/generated/stock-binding-operations.ts +29 -198
  82. package/src/generated/stock-observation-operations.ts +24 -111
  83. package/src/generated/tracking-quality-operations.ts +19 -57
  84. package/src/generated/trip-utilization-operations.ts +32 -166
  85. package/src/generated/wspace-operations.ts +284 -2906
  86. package/src/generated/wspace-types.ts +2 -8
  87. package/src/movethewheels/MoveTheWheelsRoot.tsx +6 -0
  88. package/src/movethewheels/MoveTheWheelsRoutes.tsx +2 -0
  89. package/src/movethewheels/components/ContainerEvidencePicker.tsx +12 -4
  90. package/src/movethewheels/components/FleetAlertsPanel.tsx +4 -2
  91. package/src/movethewheels/components/freight-cost/FreightCommercialEditor.tsx +236 -0
  92. package/src/movethewheels/components/freight-cost/FreightCommercialFactEditor.tsx +258 -0
  93. package/src/movethewheels/components/freight-cost/FreightCommercialHistory.tsx +90 -0
  94. package/src/movethewheels/components/freight-cost/FreightDraftForm.tsx +33 -4
  95. package/src/movethewheels/components/freight-cost/FreightHistory.tsx +4 -2
  96. package/src/movethewheels/components/freight-invoice/InvoiceForm.tsx +412 -0
  97. package/src/movethewheels/components/freight-invoice/InvoiceResults.tsx +162 -0
  98. package/src/movethewheels/hooks/useFleet.ts +1 -1
  99. package/src/movethewheels/hooks/useFleetIntelligence.ts +5 -1
  100. package/src/movethewheels/hooks/useFreightRecoveryAction.ts +2 -1
  101. package/src/movethewheels/hooks/useInvoiceComparisonRecovery.ts +227 -0
  102. package/src/movethewheels/pages/DriverDetailsPage.tsx +35 -9
  103. package/src/movethewheels/pages/FreightEstimatePage.tsx +15 -7
  104. package/src/movethewheels/pages/FreightInvoicePage.tsx +477 -0
  105. package/src/movethewheels/utils/driverLicenseExpiry.ts +25 -0
  106. package/src/movethewheels/utils/freightAcknowledgement.ts +3 -1
  107. package/src/movethewheels/utils/freightCommercial.ts +388 -0
  108. package/src/movethewheels/utils/freightRecovery.ts +6 -2
  109. package/src/movethewheels/utils/invoiceComparison.ts +520 -0
  110. package/src/operations/freight-cost/commercial.graphql +483 -0
  111. package/src/operations/freight-invoice/comparison.graphql +40 -0
  112. package/src/operations/wspace/freight-invoice-evidence.graphql +6 -0
  113. package/patches/braces@3.0.3.patch +0 -87
@@ -0,0 +1,483 @@
1
+ fragment CommercialProvenance on MtwFreightCommercialProvenance {
2
+ sourceReference
3
+ sourceRevision
4
+ observedAt
5
+ evidenceLinks {
6
+ fileId
7
+ versionId
8
+ }
9
+ }
10
+ mutation SaveFreightCommercialCosts($input: SaveMtwFreightEstimateInput!) {
11
+ saveMtwFreightEstimate(input: $input) {
12
+ id
13
+ shipmentId
14
+ estimateReference
15
+ version
16
+ previousVersionId
17
+ shipmentCapture {
18
+ shipmentNumber
19
+ primaryMode
20
+ capturedUpdatedAt
21
+ }
22
+ facts {
23
+ kind
24
+ title
25
+ commercialScope
26
+ sourceReference
27
+ sourceRevision
28
+ pricingAt
29
+ quotedAt
30
+ validFrom
31
+ validUntil
32
+ reportingCurrency {
33
+ code
34
+ minorUnitDigits
35
+ }
36
+ rounding
37
+ lines {
38
+ id
39
+ category
40
+ description
41
+ payerReference
42
+ payerLabel
43
+ disposition
44
+ inclusionParentLineId
45
+ currency {
46
+ code
47
+ minorUnitDigits
48
+ }
49
+ amountBasis
50
+ quantity
51
+ unit
52
+ unitRateMajor
53
+ amountMinor
54
+ zeroReason
55
+ sourceReference
56
+ sourceRevision
57
+ }
58
+ requirements {
59
+ category
60
+ status
61
+ reason
62
+ sourceReference
63
+ sourceRevision
64
+ }
65
+ fx {
66
+ fromCurrency {
67
+ code
68
+ minorUnitDigits
69
+ }
70
+ toCurrency {
71
+ code
72
+ minorUnitDigits
73
+ }
74
+ rate
75
+ observedAt
76
+ effectiveFrom
77
+ effectiveUntil
78
+ sourceReference
79
+ sourceRevision
80
+ }
81
+ }
82
+ totals {
83
+ completeRelativeToDeclarations
84
+ reportingTotalMinor
85
+ subtotals {
86
+ currency {
87
+ code
88
+ minorUnitDigits
89
+ }
90
+ payerReference
91
+ payerLabel
92
+ knownAmountMinor
93
+ totalAmountMinor
94
+ }
95
+ lines {
96
+ id
97
+ nativeAmountMinor
98
+ reportingAmountMinor
99
+ roundedToZero
100
+ }
101
+ reasons {
102
+ code
103
+ lineId
104
+ detail
105
+ }
106
+ warnings {
107
+ code
108
+ lineId
109
+ detail
110
+ }
111
+ }
112
+ evidence {
113
+ fileId
114
+ versionId
115
+ sha256Hash
116
+ checkedAt
117
+ }
118
+ recordedAt
119
+ createdBy
120
+ actorProvenance
121
+ onBehalfOf
122
+ validityAtRead
123
+ commercialCapture {
124
+ schemaVersion
125
+ selectedLegs {
126
+ id
127
+ expectedUpdatedAt
128
+ }
129
+ origin {
130
+ status
131
+ value {
132
+ kind
133
+ label
134
+ jurisdictionLabel
135
+ }
136
+ reason
137
+ provenance {
138
+ ...CommercialProvenance
139
+ }
140
+ }
141
+ destination {
142
+ status
143
+ value {
144
+ kind
145
+ label
146
+ jurisdictionLabel
147
+ }
148
+ reason
149
+ provenance {
150
+ ...CommercialProvenance
151
+ }
152
+ }
153
+ carrier {
154
+ status
155
+ value {
156
+ reference
157
+ label
158
+ }
159
+ reason
160
+ provenance {
161
+ ...CommercialProvenance
162
+ }
163
+ }
164
+ service {
165
+ status
166
+ value
167
+ reason
168
+ provenance {
169
+ ...CommercialProvenance
170
+ }
171
+ }
172
+ cargo {
173
+ status
174
+ value {
175
+ classificationLabel
176
+ description
177
+ }
178
+ reason
179
+ provenance {
180
+ ...CommercialProvenance
181
+ }
182
+ }
183
+ weight {
184
+ status
185
+ value {
186
+ amount
187
+ unit
188
+ zeroReason
189
+ }
190
+ reason
191
+ provenance {
192
+ ...CommercialProvenance
193
+ }
194
+ }
195
+ volume {
196
+ status
197
+ value {
198
+ amount
199
+ unit
200
+ zeroReason
201
+ }
202
+ reason
203
+ provenance {
204
+ ...CommercialProvenance
205
+ }
206
+ }
207
+ equipment {
208
+ status
209
+ value {
210
+ typeLabel
211
+ count
212
+ }
213
+ reason
214
+ provenance {
215
+ ...CommercialProvenance
216
+ }
217
+ }
218
+ ownerShipment {
219
+ shipmentId
220
+ updatedAt
221
+ primaryMode
222
+ }
223
+ ownerLegs {
224
+ id
225
+ updatedAt
226
+ legNumber
227
+ mode
228
+ carrierId
229
+ carrierName
230
+ weightKg
231
+ volumeCbm
232
+ containerType
233
+ containerCount
234
+ }
235
+ }
236
+ }
237
+ }
238
+ query FreightCommercialVersion($shipmentId: ID!, $id: ID!) {
239
+ mtwFreightEstimateVersion(shipmentId: $shipmentId, id: $id) {
240
+ id
241
+ shipmentId
242
+ estimateReference
243
+ version
244
+ previousVersionId
245
+ shipmentCapture {
246
+ shipmentNumber
247
+ primaryMode
248
+ capturedUpdatedAt
249
+ }
250
+ facts {
251
+ kind
252
+ title
253
+ commercialScope
254
+ sourceReference
255
+ sourceRevision
256
+ pricingAt
257
+ quotedAt
258
+ validFrom
259
+ validUntil
260
+ reportingCurrency {
261
+ code
262
+ minorUnitDigits
263
+ }
264
+ rounding
265
+ lines {
266
+ id
267
+ category
268
+ description
269
+ payerReference
270
+ payerLabel
271
+ disposition
272
+ inclusionParentLineId
273
+ currency {
274
+ code
275
+ minorUnitDigits
276
+ }
277
+ amountBasis
278
+ quantity
279
+ unit
280
+ unitRateMajor
281
+ amountMinor
282
+ zeroReason
283
+ sourceReference
284
+ sourceRevision
285
+ }
286
+ requirements {
287
+ category
288
+ status
289
+ reason
290
+ sourceReference
291
+ sourceRevision
292
+ }
293
+ fx {
294
+ fromCurrency {
295
+ code
296
+ minorUnitDigits
297
+ }
298
+ toCurrency {
299
+ code
300
+ minorUnitDigits
301
+ }
302
+ rate
303
+ observedAt
304
+ effectiveFrom
305
+ effectiveUntil
306
+ sourceReference
307
+ sourceRevision
308
+ }
309
+ }
310
+ totals {
311
+ completeRelativeToDeclarations
312
+ reportingTotalMinor
313
+ subtotals {
314
+ currency {
315
+ code
316
+ minorUnitDigits
317
+ }
318
+ payerReference
319
+ payerLabel
320
+ knownAmountMinor
321
+ totalAmountMinor
322
+ }
323
+ lines {
324
+ id
325
+ nativeAmountMinor
326
+ reportingAmountMinor
327
+ roundedToZero
328
+ }
329
+ reasons {
330
+ code
331
+ lineId
332
+ detail
333
+ }
334
+ warnings {
335
+ code
336
+ lineId
337
+ detail
338
+ }
339
+ }
340
+ evidence {
341
+ fileId
342
+ versionId
343
+ sha256Hash
344
+ checkedAt
345
+ }
346
+ recordedAt
347
+ createdBy
348
+ actorProvenance
349
+ onBehalfOf
350
+ validityAtRead
351
+ commercialCapture {
352
+ schemaVersion
353
+ selectedLegs {
354
+ id
355
+ expectedUpdatedAt
356
+ }
357
+ origin {
358
+ status
359
+ value {
360
+ kind
361
+ label
362
+ jurisdictionLabel
363
+ }
364
+ reason
365
+ provenance {
366
+ ...CommercialProvenance
367
+ }
368
+ }
369
+ destination {
370
+ status
371
+ value {
372
+ kind
373
+ label
374
+ jurisdictionLabel
375
+ }
376
+ reason
377
+ provenance {
378
+ ...CommercialProvenance
379
+ }
380
+ }
381
+ carrier {
382
+ status
383
+ value {
384
+ reference
385
+ label
386
+ }
387
+ reason
388
+ provenance {
389
+ ...CommercialProvenance
390
+ }
391
+ }
392
+ service {
393
+ status
394
+ value
395
+ reason
396
+ provenance {
397
+ ...CommercialProvenance
398
+ }
399
+ }
400
+ cargo {
401
+ status
402
+ value {
403
+ classificationLabel
404
+ description
405
+ }
406
+ reason
407
+ provenance {
408
+ ...CommercialProvenance
409
+ }
410
+ }
411
+ weight {
412
+ status
413
+ value {
414
+ amount
415
+ unit
416
+ zeroReason
417
+ }
418
+ reason
419
+ provenance {
420
+ ...CommercialProvenance
421
+ }
422
+ }
423
+ volume {
424
+ status
425
+ value {
426
+ amount
427
+ unit
428
+ zeroReason
429
+ }
430
+ reason
431
+ provenance {
432
+ ...CommercialProvenance
433
+ }
434
+ }
435
+ equipment {
436
+ status
437
+ value {
438
+ typeLabel
439
+ count
440
+ }
441
+ reason
442
+ provenance {
443
+ ...CommercialProvenance
444
+ }
445
+ }
446
+ ownerShipment {
447
+ shipmentId
448
+ updatedAt
449
+ primaryMode
450
+ }
451
+ ownerLegs {
452
+ id
453
+ updatedAt
454
+ legNumber
455
+ mode
456
+ carrierId
457
+ carrierName
458
+ weightKg
459
+ volumeCbm
460
+ containerType
461
+ containerCount
462
+ }
463
+ }
464
+ }
465
+ }
466
+ query FreightCommercialLegs($shipmentId: ID!, $pagination: PaginationInput!) {
467
+ shipment(id: $shipmentId) {
468
+ id
469
+ legs(pagination: $pagination) {
470
+ id
471
+ shipmentId
472
+ updatedAt
473
+ legNumber
474
+ mode
475
+ carrierId
476
+ carrierName
477
+ weightKg
478
+ volumeCbm
479
+ containerType
480
+ containerCount
481
+ }
482
+ }
483
+ }
@@ -0,0 +1,40 @@
1
+ fragment InvoiceSourceFacts on MtwFreightInvoiceFacts {
2
+ schemaVersion supplierReference supplierLabel invoiceReference sourceReference sourceRevision invoiceDate
3
+ currency { code minorUnitDigits }
4
+ rows { id description estimateLineId currency { code minorUnitDigits } payerReference payerLabel quantity unit unitRateMajor amountMinor zeroReason }
5
+ }
6
+ fragment InvoiceOutcome on MtwFreightInvoiceOutcome {
7
+ flags allLinesMatched missingExpectedLineIds
8
+ unknownExpectedCoverage { estimateLineId flag reason }
9
+ rows { invoiceLineId estimateLineId flags reasons deltaMinor }
10
+ comparableSubtotals { currency { code minorUnitDigits } payerReference estimateMinor invoiceMinor deltaMinor invoiceLineIds }
11
+ }
12
+ fragment InvoiceDeclaredSubtotal on MtwFreightSubtotal { currency { code minorUnitDigits } payerReference payerLabel knownAmountMinor totalAmountMinor }
13
+ fragment InvoiceEstimatePin on MtwFreightInvoiceEstimatePin { id estimateReference version kind sourceReference sourceRevision quotedAt validFrom validUntil acceptance }
14
+ fragment InvoiceReceipt on MtwFreightInvoiceComparison {
15
+ id shipmentId invoiceIdentityId revision previousComparisonId correctionReason methodVersion idempotencyKey requestFingerprint
16
+ estimate { ...InvoiceEstimatePin } facts { ...InvoiceSourceFacts } outcome { ...InvoiceOutcome }
17
+ estimateDeclaredSubtotals { ...InvoiceDeclaredSubtotal } invoiceDeclaredSubtotals { ...InvoiceDeclaredSubtotal }
18
+ evidence { fileId versionId sha256Hash checkedAt }
19
+ recordedAt createdBy actorProvenance onBehalfOf
20
+ }
21
+ query InvoiceShipments($pagination: PaginationInput) { shipments(pagination: $pagination) { id shipmentNumber primaryMode status } shipmentsCount }
22
+ query InvoiceEstimatePage($shipmentId: ID!, $pagination: MtwContainerPagination) {
23
+ mtwFreightEstimatePage(shipmentId: $shipmentId, pagination: $pagination) { items { id shipmentId estimateReference version facts { title kind } } total limit offset hasMore nextOffset }
24
+ }
25
+ query InvoiceEstimateVersion($shipmentId: ID!, $id: ID!) {
26
+ mtwFreightEstimateVersion(shipmentId: $shipmentId, id: $id) {
27
+ id shipmentId estimateReference version validityAtRead
28
+ facts { title kind sourceReference sourceRevision quotedAt validFrom validUntil lines { id description disposition amountBasis quantity unit unitRateMajor amountMinor currency { code minorUnitDigits } payerReference payerLabel inclusionParentLineId } }
29
+ totals { completeRelativeToDeclarations lines { id nativeAmountMinor } }
30
+ }
31
+ }
32
+ query InvoiceStructuralPreview($input: PreviewMtwFreightInvoiceInput!) {
33
+ previewMtwFreightInvoice(input: $input) { methodVersion recordable blockers estimate { ...InvoiceEstimatePin } facts { ...InvoiceSourceFacts } outcome { ...InvoiceOutcome } estimateDeclaredSubtotals { ...InvoiceDeclaredSubtotal } invoiceDeclaredSubtotals { ...InvoiceDeclaredSubtotal } }
34
+ }
35
+ mutation RecordInvoiceComparison($input: CompareMtwFreightInvoiceInput!) { compareMtwFreightInvoice(input: $input) { ...InvoiceReceipt } }
36
+ query InvoiceComparisonExact($shipmentId: ID!, $id: ID!) { mtwFreightInvoiceComparison(shipmentId: $shipmentId, id: $id) { ...InvoiceReceipt } }
37
+ query InvoiceComparisonHistory($shipmentId: ID!, $invoiceIdentityId: ID!, $pagination: MtwContainerPagination) {
38
+ mtwFreightInvoiceComparisonPage(shipmentId: $shipmentId, invoiceIdentityId: $invoiceIdentityId, pagination: $pagination) { items { ...InvoiceReceipt } total limit offset hasMore nextOffset }
39
+ }
40
+ query RecoverInvoiceComparison($shipmentId: ID!, $requestKey: String!) { mtwFreightInvoiceComparisonByRequestKey(shipmentId: $shipmentId, requestKey: $requestKey) { ...InvoiceReceipt } }
@@ -0,0 +1,6 @@
1
+ query InvoiceEvidenceVersions($fileId: ID!, $pagination: PaginationInput) {
2
+ getFileVersions(fileId: $fileId, pagination: $pagination) {
3
+ versions { id fileId name versionNumber versionLabel sha256Hash createdAt isCurrentVersion }
4
+ hasMore
5
+ }
6
+ }
@@ -1,87 +0,0 @@
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
- +};