universal-parcel-scraper 0.0.0-stage → 0.2.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/LICENSE +201 -0
- package/NOTICE +15 -0
- package/README.md +123 -2
- package/data/carrier-order.json +107 -0
- package/data/carrier.schema.json +415 -0
- package/data/catalog.json +3969 -0
- package/data/coverage-summary.json +17 -0
- package/data/detection-golden.json +5375 -0
- package/data/stages.json +13 -0
- package/dist/browser/scraper.js +9292 -0
- package/dist/carriers/aliexpress/adapter.d.ts +30 -0
- package/dist/carriers/aliexpress/adapter.js +164 -0
- package/dist/carriers/aliexpress/carrier.json +59 -0
- package/dist/carriers/aliexpress/numbers.json +36 -0
- package/dist/carriers/aliexpress/status.d.ts +31 -0
- package/dist/carriers/aliexpress/status.js +79 -0
- package/dist/carriers/aliexpress/statuses.json +355 -0
- package/dist/carriers/amazon-logistics/carrier.json +94 -0
- package/dist/carriers/amazon-logistics/numbers.json +307 -0
- package/dist/carriers/amazon-shipping/adapter.d.ts +34 -0
- package/dist/carriers/amazon-shipping/adapter.js +292 -0
- package/dist/carriers/amazon-shipping/carrier.json +96 -0
- package/dist/carriers/amazon-shipping/eligibility.d.ts +3 -0
- package/dist/carriers/amazon-shipping/eligibility.js +16 -0
- package/dist/carriers/amazon-shipping/numbers.json +67 -0
- package/dist/carriers/amazon-shipping/status.d.ts +26 -0
- package/dist/carriers/amazon-shipping/status.js +118 -0
- package/dist/carriers/amazon-shipping/statuses.json +19 -0
- package/dist/carriers/an-post/carrier.json +38 -0
- package/dist/carriers/an-post/numbers.json +33 -0
- package/dist/carriers/aramex/adapter.d.ts +11 -0
- package/dist/carriers/aramex/adapter.js +49 -0
- package/dist/carriers/aramex/carrier.json +62 -0
- package/dist/carriers/aramex/numbers.json +71 -0
- package/dist/carriers/aramex/parser.d.ts +5 -0
- package/dist/carriers/aramex/parser.js +83 -0
- package/dist/carriers/aramex/status.d.ts +2 -0
- package/dist/carriers/aramex/status.js +16 -0
- package/dist/carriers/aramex/statuses.json +41 -0
- package/dist/carriers/asendia/adapter.d.ts +82 -0
- package/dist/carriers/asendia/adapter.js +342 -0
- package/dist/carriers/asendia/carrier.json +91 -0
- package/dist/carriers/asendia/numbers.json +177 -0
- package/dist/carriers/asendia/probe.d.ts +31 -0
- package/dist/carriers/asendia/probe.js +355 -0
- package/dist/carriers/asendia/status.d.ts +41 -0
- package/dist/carriers/asendia/status.js +147 -0
- package/dist/carriers/asendia/statuses.json +877 -0
- package/dist/carriers/australia-post/adapter.d.ts +20 -0
- package/dist/carriers/australia-post/adapter.js +175 -0
- package/dist/carriers/australia-post/carrier.json +72 -0
- package/dist/carriers/australia-post/numbers.json +66 -0
- package/dist/carriers/australia-post/status.d.ts +2 -0
- package/dist/carriers/australia-post/status.js +34 -0
- package/dist/carriers/australia-post/statuses.json +172 -0
- package/dist/carriers/austrian-post/adapter.d.ts +13 -0
- package/dist/carriers/austrian-post/adapter.js +101 -0
- package/dist/carriers/austrian-post/carrier.json +58 -0
- package/dist/carriers/austrian-post/numbers.json +73 -0
- package/dist/carriers/austrian-post/status.d.ts +3 -0
- package/dist/carriers/austrian-post/status.js +30 -0
- package/dist/carriers/austrian-post/statuses.json +47 -0
- package/dist/carriers/blue-dart/adapter.d.ts +11 -0
- package/dist/carriers/blue-dart/adapter.js +34 -0
- package/dist/carriers/blue-dart/carrier.json +59 -0
- package/dist/carriers/blue-dart/numbers.json +113 -0
- package/dist/carriers/blue-dart/parser.d.ts +3 -0
- package/dist/carriers/blue-dart/parser.js +75 -0
- package/dist/carriers/blue-dart/status.d.ts +2 -0
- package/dist/carriers/blue-dart/status.js +14 -0
- package/dist/carriers/blue-dart/statuses.json +59 -0
- package/dist/carriers/bpost/adapter.d.ts +11 -0
- package/dist/carriers/bpost/adapter.js +46 -0
- package/dist/carriers/bpost/carrier.json +81 -0
- package/dist/carriers/bpost/numbers.json +103 -0
- package/dist/carriers/bpost/parser.d.ts +3 -0
- package/dist/carriers/bpost/parser.js +84 -0
- package/dist/carriers/bpost/status.d.ts +2 -0
- package/dist/carriers/bpost/status.js +18 -0
- package/dist/carriers/bpost/statuses.json +96 -0
- package/dist/carriers/bring-posten/adapter.d.ts +11 -0
- package/dist/carriers/bring-posten/adapter.js +35 -0
- package/dist/carriers/bring-posten/carrier.json +91 -0
- package/dist/carriers/bring-posten/numbers.json +33 -0
- package/dist/carriers/bring-posten/parser.d.ts +3 -0
- package/dist/carriers/bring-posten/parser.js +95 -0
- package/dist/carriers/bring-posten/status.d.ts +3 -0
- package/dist/carriers/bring-posten/status.js +23 -0
- package/dist/carriers/bring-posten/statuses.json +33 -0
- package/dist/carriers/brt/adapter.d.ts +11 -0
- package/dist/carriers/brt/adapter.js +36 -0
- package/dist/carriers/brt/carrier.json +80 -0
- package/dist/carriers/brt/numbers.json +91 -0
- package/dist/carriers/brt/parser.d.ts +3 -0
- package/dist/carriers/brt/parser.js +84 -0
- package/dist/carriers/brt/status.d.ts +2 -0
- package/dist/carriers/brt/status.js +14 -0
- package/dist/carriers/brt/statuses.json +53 -0
- package/dist/carriers/c-chez-vous/adapter.d.ts +31 -0
- package/dist/carriers/c-chez-vous/adapter.js +181 -0
- package/dist/carriers/c-chez-vous/carrier.json +69 -0
- package/dist/carriers/c-chez-vous/numbers.json +31 -0
- package/dist/carriers/c-chez-vous/status.d.ts +27 -0
- package/dist/carriers/c-chez-vous/status.js +19 -0
- package/dist/carriers/c-chez-vous/statuses.json +10 -0
- package/dist/carriers/canada-post/adapter.d.ts +40 -0
- package/dist/carriers/canada-post/adapter.js +78 -0
- package/dist/carriers/canada-post/carrier.json +77 -0
- package/dist/carriers/canada-post/numbers.json +81 -0
- package/dist/carriers/canada-post/parser.d.ts +5 -0
- package/dist/carriers/canada-post/parser.js +202 -0
- package/dist/carriers/canada-post/status.d.ts +9 -0
- package/dist/carriers/canada-post/status.js +67 -0
- package/dist/carriers/canada-post/statuses.json +171 -0
- package/dist/carriers/canpar/adapter.d.ts +11 -0
- package/dist/carriers/canpar/adapter.js +40 -0
- package/dist/carriers/canpar/carrier.json +74 -0
- package/dist/carriers/canpar/numbers.json +71 -0
- package/dist/carriers/canpar/parser.d.ts +3 -0
- package/dist/carriers/canpar/parser.js +75 -0
- package/dist/carriers/canpar/status.d.ts +2 -0
- package/dist/carriers/canpar/status.js +16 -0
- package/dist/carriers/canpar/statuses.json +82 -0
- package/dist/carriers/china-post/carrier.json +38 -0
- package/dist/carriers/china-post/numbers.json +59 -0
- package/dist/carriers/chronopost/carrier.json +84 -0
- package/dist/carriers/chronopost/numbers.json +110 -0
- package/dist/carriers/chronopost/statuses.json +47 -0
- package/dist/carriers/ciblex/adapter.d.ts +17 -0
- package/dist/carriers/ciblex/adapter.js +46 -0
- package/dist/carriers/ciblex/carrier.json +71 -0
- package/dist/carriers/ciblex/numbers.json +63 -0
- package/dist/carriers/ciblex/parser.d.ts +4 -0
- package/dist/carriers/ciblex/parser.js +100 -0
- package/dist/carriers/ciblex/status.d.ts +24 -0
- package/dist/carriers/ciblex/status.js +55 -0
- package/dist/carriers/ciblex/statuses.json +221 -0
- package/dist/carriers/colis-prive/adapter.d.ts +39 -0
- package/dist/carriers/colis-prive/adapter.js +0 -0
- package/dist/carriers/colis-prive/carrier.json +72 -0
- package/dist/carriers/colis-prive/numbers.json +97 -0
- package/dist/carriers/colis-prive/status.d.ts +30 -0
- package/dist/carriers/colis-prive/status.js +85 -0
- package/dist/carriers/colis-prive/statuses.json +39 -0
- package/dist/carriers/colisweb/adapter.d.ts +29 -0
- package/dist/carriers/colisweb/adapter.js +166 -0
- package/dist/carriers/colisweb/carrier.json +63 -0
- package/dist/carriers/colisweb/numbers.json +39 -0
- package/dist/carriers/colisweb/status.d.ts +32 -0
- package/dist/carriers/colisweb/status.js +61 -0
- package/dist/carriers/colisweb/statuses.json +25 -0
- package/dist/carriers/correios-br/adapter.d.ts +16 -0
- package/dist/carriers/correios-br/adapter.js +78 -0
- package/dist/carriers/correios-br/carrier.json +64 -0
- package/dist/carriers/correios-br/model/LICENSE +21 -0
- package/dist/carriers/correios-br/model/captcha.onnx +0 -0
- package/dist/carriers/correios-br/numbers.json +72 -0
- package/dist/carriers/correios-br/ocr-worker.mjs +53 -0
- package/dist/carriers/correios-br/ocr.d.ts +10 -0
- package/dist/carriers/correios-br/ocr.js +83 -0
- package/dist/carriers/correios-br/parser.d.ts +4 -0
- package/dist/carriers/correios-br/parser.js +79 -0
- package/dist/carriers/correios-br/status.d.ts +2 -0
- package/dist/carriers/correios-br/status.js +17 -0
- package/dist/carriers/correios-br/statuses.json +16 -0
- package/dist/carriers/correos-chile/adapter.d.ts +12 -0
- package/dist/carriers/correos-chile/adapter.js +85 -0
- package/dist/carriers/correos-chile/carrier.json +62 -0
- package/dist/carriers/correos-chile/numbers.json +38 -0
- package/dist/carriers/correos-chile/parser.d.ts +9 -0
- package/dist/carriers/correos-chile/parser.js +120 -0
- package/dist/carriers/correos-chile/status.d.ts +3 -0
- package/dist/carriers/correos-chile/status.js +17 -0
- package/dist/carriers/correos-chile/statuses.json +12 -0
- package/dist/carriers/correos-express/adapter.d.ts +11 -0
- package/dist/carriers/correos-express/adapter.js +32 -0
- package/dist/carriers/correos-express/carrier.json +65 -0
- package/dist/carriers/correos-express/numbers.json +80 -0
- package/dist/carriers/correos-express/parser.d.ts +3 -0
- package/dist/carriers/correos-express/parser.js +97 -0
- package/dist/carriers/correos-express/status.d.ts +2 -0
- package/dist/carriers/correos-express/status.js +25 -0
- package/dist/carriers/correos-express/statuses.json +19 -0
- package/dist/carriers/correos-spain/adapter.d.ts +15 -0
- package/dist/carriers/correos-spain/adapter.js +191 -0
- package/dist/carriers/correos-spain/carrier.json +92 -0
- package/dist/carriers/correos-spain/numbers.json +149 -0
- package/dist/carriers/correos-spain/status.d.ts +17 -0
- package/dist/carriers/correos-spain/status.js +51 -0
- package/dist/carriers/correos-spain/statuses.json +46 -0
- package/dist/carriers/ctt/adapter.d.ts +34 -0
- package/dist/carriers/ctt/adapter.js +320 -0
- package/dist/carriers/ctt/carrier.json +72 -0
- package/dist/carriers/ctt/numbers.json +33 -0
- package/dist/carriers/ctt/status.d.ts +16 -0
- package/dist/carriers/ctt/status.js +16 -0
- package/dist/carriers/ctt/statuses.json +15 -0
- package/dist/carriers/ctt-express/adapter.d.ts +11 -0
- package/dist/carriers/ctt-express/adapter.js +41 -0
- package/dist/carriers/ctt-express/carrier.json +64 -0
- package/dist/carriers/ctt-express/numbers.json +59 -0
- package/dist/carriers/ctt-express/parser.d.ts +3 -0
- package/dist/carriers/ctt-express/parser.js +107 -0
- package/dist/carriers/ctt-express/status.d.ts +2 -0
- package/dist/carriers/ctt-express/status.js +17 -0
- package/dist/carriers/ctt-express/statuses.json +15 -0
- package/dist/carriers/dachser/adapter.d.ts +25 -0
- package/dist/carriers/dachser/adapter.js +168 -0
- package/dist/carriers/dachser/carrier.json +80 -0
- package/dist/carriers/dachser/numbers.json +66 -0
- package/dist/carriers/dachser/status.d.ts +40 -0
- package/dist/carriers/dachser/status.js +57 -0
- package/dist/carriers/dachser/statuses.json +18 -0
- package/dist/carriers/delhivery/adapter.d.ts +11 -0
- package/dist/carriers/delhivery/adapter.js +36 -0
- package/dist/carriers/delhivery/carrier.json +50 -0
- package/dist/carriers/delhivery/numbers.json +108 -0
- package/dist/carriers/delhivery/parser.d.ts +3 -0
- package/dist/carriers/delhivery/parser.js +81 -0
- package/dist/carriers/delhivery/status.d.ts +2 -0
- package/dist/carriers/delhivery/status.js +11 -0
- package/dist/carriers/delhivery/statuses.json +11 -0
- package/dist/carriers/delivengo/carrier.json +56 -0
- package/dist/carriers/delivengo/numbers.json +31 -0
- package/dist/carriers/delivengo/statuses.json +5 -0
- package/dist/carriers/dhl/adapter.d.ts +70 -0
- package/dist/carriers/dhl/adapter.js +308 -0
- package/dist/carriers/dhl/carrier.json +98 -0
- package/dist/carriers/dhl/numbers.json +153 -0
- package/dist/carriers/dhl/status.d.ts +14 -0
- package/dist/carriers/dhl/status.js +45 -0
- package/dist/carriers/dhl/statuses.json +27 -0
- package/dist/carriers/dhl-ecommerce/adapter.d.ts +50 -0
- package/dist/carriers/dhl-ecommerce/adapter.js +179 -0
- package/dist/carriers/dhl-ecommerce/carrier.json +97 -0
- package/dist/carriers/dhl-ecommerce/numbers.json +130 -0
- package/dist/carriers/dhl-ecommerce/status.d.ts +13 -0
- package/dist/carriers/dhl-ecommerce/status.js +57 -0
- package/dist/carriers/dhl-ecommerce/statuses.json +23 -0
- package/dist/carriers/dpd/adapter.d.ts +70 -0
- package/dist/carriers/dpd/adapter.js +809 -0
- package/dist/carriers/dpd/carrier.json +111 -0
- package/dist/carriers/dpd/numbers.json +43 -0
- package/dist/carriers/dpd/status.d.ts +39 -0
- package/dist/carriers/dpd/status.js +93 -0
- package/dist/carriers/dpd/statuses.json +144 -0
- package/dist/carriers/dpd-fr/adapter.d.ts +42 -0
- package/dist/carriers/dpd-fr/adapter.js +288 -0
- package/dist/carriers/dpd-fr/carrier.json +83 -0
- package/dist/carriers/dpd-fr/numbers.json +80 -0
- package/dist/carriers/dpd-fr/status.d.ts +21 -0
- package/dist/carriers/dpd-fr/status.js +93 -0
- package/dist/carriers/dpd-fr/statuses.json +325 -0
- package/dist/carriers/dtdc/adapter.d.ts +11 -0
- package/dist/carriers/dtdc/adapter.js +39 -0
- package/dist/carriers/dtdc/carrier.json +77 -0
- package/dist/carriers/dtdc/numbers.json +50 -0
- package/dist/carriers/dtdc/parser.d.ts +3 -0
- package/dist/carriers/dtdc/parser.js +90 -0
- package/dist/carriers/dtdc/status.d.ts +2 -0
- package/dist/carriers/dtdc/status.js +15 -0
- package/dist/carriers/dtdc/statuses.json +65 -0
- package/dist/carriers/ecoscooting/adapter.d.ts +11 -0
- package/dist/carriers/ecoscooting/adapter.js +42 -0
- package/dist/carriers/ecoscooting/carrier.json +76 -0
- package/dist/carriers/ecoscooting/numbers.json +291 -0
- package/dist/carriers/ecoscooting/parser.d.ts +3 -0
- package/dist/carriers/ecoscooting/parser.js +88 -0
- package/dist/carriers/ecoscooting/status.d.ts +2 -0
- package/dist/carriers/ecoscooting/status.js +50 -0
- package/dist/carriers/ecoscooting/statuses.json +295 -0
- package/dist/carriers/ems/adapter.d.ts +14 -0
- package/dist/carriers/ems/adapter.js +124 -0
- package/dist/carriers/ems/carrier.json +61 -0
- package/dist/carriers/ems/numbers.json +43 -0
- package/dist/carriers/ems/status.d.ts +2 -0
- package/dist/carriers/ems/status.js +24 -0
- package/dist/carriers/ems/statuses.json +128 -0
- package/dist/carriers/estafeta/adapter.d.ts +11 -0
- package/dist/carriers/estafeta/adapter.js +45 -0
- package/dist/carriers/estafeta/carrier.json +79 -0
- package/dist/carriers/estafeta/numbers.json +85 -0
- package/dist/carriers/estafeta/parser.d.ts +11 -0
- package/dist/carriers/estafeta/parser.js +123 -0
- package/dist/carriers/estafeta/status.d.ts +3 -0
- package/dist/carriers/estafeta/status.js +17 -0
- package/dist/carriers/estafeta/statuses.json +47 -0
- package/dist/carriers/evri/adapter.d.ts +14 -0
- package/dist/carriers/evri/adapter.js +146 -0
- package/dist/carriers/evri/carrier.json +69 -0
- package/dist/carriers/evri/numbers.json +32 -0
- package/dist/carriers/evri/status.d.ts +2 -0
- package/dist/carriers/evri/status.js +24 -0
- package/dist/carriers/evri/statuses.json +133 -0
- package/dist/carriers/fedex/adapter.d.ts +32 -0
- package/dist/carriers/fedex/adapter.js +307 -0
- package/dist/carriers/fedex/carrier.json +74 -0
- package/dist/carriers/fedex/numbers.json +198 -0
- package/dist/carriers/fedex/status.d.ts +33 -0
- package/dist/carriers/fedex/status.js +114 -0
- package/dist/carriers/fedex/statuses.json +34 -0
- package/dist/carriers/four-px/adapter.d.ts +12 -0
- package/dist/carriers/four-px/adapter.js +113 -0
- package/dist/carriers/four-px/carrier.json +60 -0
- package/dist/carriers/four-px/numbers.json +32 -0
- package/dist/carriers/four-px/status.d.ts +2 -0
- package/dist/carriers/four-px/status.js +22 -0
- package/dist/carriers/four-px/statuses.json +141 -0
- package/dist/carriers/geodis/adapter.d.ts +37 -0
- package/dist/carriers/geodis/adapter.js +275 -0
- package/dist/carriers/geodis/carrier.json +75 -0
- package/dist/carriers/geodis/numbers.json +45 -0
- package/dist/carriers/geodis/status.d.ts +37 -0
- package/dist/carriers/geodis/status.js +105 -0
- package/dist/carriers/geodis/statuses.json +51 -0
- package/dist/carriers/gls-ch/adapter.d.ts +39 -0
- package/dist/carriers/gls-ch/adapter.js +405 -0
- package/dist/carriers/gls-ch/carrier.json +122 -0
- package/dist/carriers/gls-ch/numbers.json +31 -0
- package/dist/carriers/gls-ch/status.d.ts +19 -0
- package/dist/carriers/gls-ch/status.js +79 -0
- package/dist/carriers/gls-ch/statuses.json +31 -0
- package/dist/carriers/gls-de/adapter.d.ts +28 -0
- package/dist/carriers/gls-de/adapter.js +113 -0
- package/dist/carriers/gls-de/carrier.json +126 -0
- package/dist/carriers/gls-de/numbers.json +111 -0
- package/dist/carriers/gls-de/status.d.ts +10 -0
- package/dist/carriers/gls-de/status.js +10 -0
- package/dist/carriers/gls-de/statuses.json +31 -0
- package/dist/carriers/gls-fr/adapter.d.ts +29 -0
- package/dist/carriers/gls-fr/adapter.js +220 -0
- package/dist/carriers/gls-fr/carrier.json +107 -0
- package/dist/carriers/gls-fr/numbers.json +113 -0
- package/dist/carriers/gls-fr/status.d.ts +28 -0
- package/dist/carriers/gls-fr/status.js +58 -0
- package/dist/carriers/gls-fr/statuses.json +34 -0
- package/dist/carriers/gofo/adapter.d.ts +11 -0
- package/dist/carriers/gofo/adapter.js +41 -0
- package/dist/carriers/gofo/carrier.json +80 -0
- package/dist/carriers/gofo/numbers.json +59 -0
- package/dist/carriers/gofo/parser.d.ts +5 -0
- package/dist/carriers/gofo/parser.js +131 -0
- package/dist/carriers/gofo/status.d.ts +2 -0
- package/dist/carriers/gofo/status.js +7 -0
- package/dist/carriers/gofo/statuses.json +54 -0
- package/dist/carriers/heppner/adapter.d.ts +27 -0
- package/dist/carriers/heppner/adapter.js +247 -0
- package/dist/carriers/heppner/carrier.json +74 -0
- package/dist/carriers/heppner/numbers.json +39 -0
- package/dist/carriers/heppner/status.d.ts +28 -0
- package/dist/carriers/heppner/status.js +43 -0
- package/dist/carriers/heppner/statuses.json +69 -0
- package/dist/carriers/hermes/adapter.d.ts +17 -0
- package/dist/carriers/hermes/adapter.js +103 -0
- package/dist/carriers/hermes/carrier.json +58 -0
- package/dist/carriers/hermes/numbers.json +20 -0
- package/dist/carriers/hermes/status.d.ts +15 -0
- package/dist/carriers/hermes/status.js +61 -0
- package/dist/carriers/hermes/statuses.json +31 -0
- package/dist/carriers/hermes-de/adapter.d.ts +22 -0
- package/dist/carriers/hermes-de/adapter.js +168 -0
- package/dist/carriers/hermes-de/carrier.json +90 -0
- package/dist/carriers/hermes-de/numbers.json +125 -0
- package/dist/carriers/hermes-de/status.d.ts +24 -0
- package/dist/carriers/hermes-de/status.js +52 -0
- package/dist/carriers/hermes-de/statuses.json +277 -0
- package/dist/carriers/hongkong-post/carrier.json +38 -0
- package/dist/carriers/hongkong-post/numbers.json +32 -0
- package/dist/carriers/india-post/adapter.d.ts +33 -0
- package/dist/carriers/india-post/adapter.js +415 -0
- package/dist/carriers/india-post/carrier.json +74 -0
- package/dist/carriers/india-post/numbers.json +58 -0
- package/dist/carriers/india-post/status.d.ts +23 -0
- package/dist/carriers/india-post/status.js +99 -0
- package/dist/carriers/india-post/statuses.json +18 -0
- package/dist/carriers/inpost/adapter.d.ts +14 -0
- package/dist/carriers/inpost/adapter.js +143 -0
- package/dist/carriers/inpost/carrier.json +75 -0
- package/dist/carriers/inpost/numbers.json +130 -0
- package/dist/carriers/inpost/status.d.ts +16 -0
- package/dist/carriers/inpost/status.js +31 -0
- package/dist/carriers/inpost/statuses.json +26 -0
- package/dist/carriers/intl-post/carrier.json +46 -0
- package/dist/carriers/intl-post/numbers.json +29 -0
- package/dist/carriers/j-and-t/carrier.json +66 -0
- package/dist/carriers/j-and-t/numbers.json +90 -0
- package/dist/carriers/japan-post/adapter.d.ts +13 -0
- package/dist/carriers/japan-post/adapter.js +159 -0
- package/dist/carriers/japan-post/carrier.json +71 -0
- package/dist/carriers/japan-post/numbers.json +35 -0
- package/dist/carriers/japan-post/status.d.ts +2 -0
- package/dist/carriers/japan-post/status.js +25 -0
- package/dist/carriers/japan-post/statuses.json +136 -0
- package/dist/carriers/jd-logistics/carrier.json +37 -0
- package/dist/carriers/jd-logistics/numbers.json +19 -0
- package/dist/carriers/korea-post/adapter.d.ts +12 -0
- package/dist/carriers/korea-post/adapter.js +101 -0
- package/dist/carriers/korea-post/carrier.json +74 -0
- package/dist/carriers/korea-post/numbers.json +54 -0
- package/dist/carriers/korea-post/status.d.ts +2 -0
- package/dist/carriers/korea-post/status.js +19 -0
- package/dist/carriers/korea-post/statuses.json +103 -0
- package/dist/carriers/la-poste/adapter.d.ts +29 -0
- package/dist/carriers/la-poste/adapter.js +241 -0
- package/dist/carriers/la-poste/carrier.json +87 -0
- package/dist/carriers/la-poste/numbers.json +140 -0
- package/dist/carriers/la-poste/status.d.ts +30 -0
- package/dist/carriers/la-poste/status.js +110 -0
- package/dist/carriers/la-poste/statuses.json +163 -0
- package/dist/carriers/landmark-global/adapter.d.ts +11 -0
- package/dist/carriers/landmark-global/adapter.js +30 -0
- package/dist/carriers/landmark-global/carrier.json +64 -0
- package/dist/carriers/landmark-global/numbers.json +58 -0
- package/dist/carriers/landmark-global/parser.d.ts +3 -0
- package/dist/carriers/landmark-global/parser.js +78 -0
- package/dist/carriers/landmark-global/status.d.ts +2 -0
- package/dist/carriers/landmark-global/status.js +13 -0
- package/dist/carriers/landmark-global/statuses.json +125 -0
- package/dist/carriers/mondial-relay/adapter.d.ts +32 -0
- package/dist/carriers/mondial-relay/adapter.js +352 -0
- package/dist/carriers/mondial-relay/carrier.json +94 -0
- package/dist/carriers/mondial-relay/numbers.json +130 -0
- package/dist/carriers/mondial-relay/status.d.ts +31 -0
- package/dist/carriers/mondial-relay/status.js +98 -0
- package/dist/carriers/mondial-relay/statuses.json +50 -0
- package/dist/carriers/mrw/adapter.d.ts +13 -0
- package/dist/carriers/mrw/adapter.js +131 -0
- package/dist/carriers/mrw/carrier.json +60 -0
- package/dist/carriers/mrw/numbers.json +116 -0
- package/dist/carriers/mrw/parser.d.ts +12 -0
- package/dist/carriers/mrw/parser.js +149 -0
- package/dist/carriers/mrw/status.d.ts +2 -0
- package/dist/carriers/mrw/status.js +14 -0
- package/dist/carriers/mrw/statuses.json +13 -0
- package/dist/carriers/nacex/adapter.d.ts +11 -0
- package/dist/carriers/nacex/adapter.js +99 -0
- package/dist/carriers/nacex/carrier.json +78 -0
- package/dist/carriers/nacex/numbers.json +47 -0
- package/dist/carriers/nacex/parser.d.ts +4 -0
- package/dist/carriers/nacex/parser.js +119 -0
- package/dist/carriers/nacex/status.d.ts +2 -0
- package/dist/carriers/nacex/status.js +12 -0
- package/dist/carriers/nacex/statuses.json +11 -0
- package/dist/carriers/ninja-van/adapter.d.ts +11 -0
- package/dist/carriers/ninja-van/adapter.js +45 -0
- package/dist/carriers/ninja-van/carrier.json +79 -0
- package/dist/carriers/ninja-van/numbers.json +67 -0
- package/dist/carriers/ninja-van/parser.d.ts +5 -0
- package/dist/carriers/ninja-van/parser.js +95 -0
- package/dist/carriers/ninja-van/status.d.ts +3 -0
- package/dist/carriers/ninja-van/status.js +25 -0
- package/dist/carriers/ninja-van/statuses.json +11 -0
- package/dist/carriers/nz-post/adapter.d.ts +11 -0
- package/dist/carriers/nz-post/adapter.js +45 -0
- package/dist/carriers/nz-post/carrier.json +82 -0
- package/dist/carriers/nz-post/numbers.json +49 -0
- package/dist/carriers/nz-post/parser.d.ts +3 -0
- package/dist/carriers/nz-post/parser.js +97 -0
- package/dist/carriers/nz-post/status.d.ts +2 -0
- package/dist/carriers/nz-post/status.js +29 -0
- package/dist/carriers/nz-post/statuses.json +68 -0
- package/dist/carriers/old-dominion/carrier.json +51 -0
- package/dist/carriers/old-dominion/numbers.json +83 -0
- package/dist/carriers/ontrac/adapter.d.ts +11 -0
- package/dist/carriers/ontrac/adapter.js +34 -0
- package/dist/carriers/ontrac/carrier.json +81 -0
- package/dist/carriers/ontrac/numbers.json +214 -0
- package/dist/carriers/ontrac/parser.d.ts +3 -0
- package/dist/carriers/ontrac/parser.js +72 -0
- package/dist/carriers/ontrac/status.d.ts +2 -0
- package/dist/carriers/ontrac/status.js +19 -0
- package/dist/carriers/ontrac/statuses.json +61 -0
- package/dist/carriers/paack/adapter.d.ts +19 -0
- package/dist/carriers/paack/adapter.js +255 -0
- package/dist/carriers/paack/carrier.json +79 -0
- package/dist/carriers/paack/numbers.json +106 -0
- package/dist/carriers/paack/status.d.ts +26 -0
- package/dist/carriers/paack/status.js +82 -0
- package/dist/carriers/paack/statuses.json +357 -0
- package/dist/carriers/packeta/adapter.d.ts +15 -0
- package/dist/carriers/packeta/adapter.js +166 -0
- package/dist/carriers/packeta/carrier.json +90 -0
- package/dist/carriers/packeta/numbers.json +71 -0
- package/dist/carriers/packeta/status.d.ts +23 -0
- package/dist/carriers/packeta/status.js +40 -0
- package/dist/carriers/packeta/statuses.json +21 -0
- package/dist/carriers/parcelforce/carrier.json +47 -0
- package/dist/carriers/parcelforce/numbers.json +32 -0
- package/dist/carriers/planzer/adapter.d.ts +40 -0
- package/dist/carriers/planzer/adapter.js +148 -0
- package/dist/carriers/planzer/carrier.json +85 -0
- package/dist/carriers/planzer/numbers.json +118 -0
- package/dist/carriers/planzer/shared.d.ts +19 -0
- package/dist/carriers/planzer/shared.js +135 -0
- package/dist/carriers/planzer/status.d.ts +33 -0
- package/dist/carriers/planzer/status.js +89 -0
- package/dist/carriers/planzer/statuses.json +229 -0
- package/dist/carriers/poczta-polska/adapter.d.ts +15 -0
- package/dist/carriers/poczta-polska/adapter.js +65 -0
- package/dist/carriers/poczta-polska/carrier.json +79 -0
- package/dist/carriers/poczta-polska/numbers.json +130 -0
- package/dist/carriers/poczta-polska/parser.d.ts +3 -0
- package/dist/carriers/poczta-polska/parser.js +96 -0
- package/dist/carriers/poczta-polska/status.d.ts +2 -0
- package/dist/carriers/poczta-polska/status.js +21 -0
- package/dist/carriers/poczta-polska/statuses.json +47 -0
- package/dist/carriers/pos-malaysia/adapter.d.ts +18 -0
- package/dist/carriers/pos-malaysia/adapter.js +199 -0
- package/dist/carriers/pos-malaysia/carrier.json +78 -0
- package/dist/carriers/pos-malaysia/numbers.json +73 -0
- package/dist/carriers/pos-malaysia/status.d.ts +17 -0
- package/dist/carriers/pos-malaysia/status.js +21 -0
- package/dist/carriers/pos-malaysia/statuses.json +17 -0
- package/dist/carriers/poste-italiane/adapter.d.ts +15 -0
- package/dist/carriers/poste-italiane/adapter.js +211 -0
- package/dist/carriers/poste-italiane/carrier.json +86 -0
- package/dist/carriers/poste-italiane/numbers.json +117 -0
- package/dist/carriers/poste-italiane/status.d.ts +19 -0
- package/dist/carriers/poste-italiane/status.js +44 -0
- package/dist/carriers/poste-italiane/statuses.json +22 -0
- package/dist/carriers/posti/adapter.d.ts +17 -0
- package/dist/carriers/posti/adapter.js +195 -0
- package/dist/carriers/posti/carrier.json +69 -0
- package/dist/carriers/posti/numbers.json +52 -0
- package/dist/carriers/posti/status.d.ts +4 -0
- package/dist/carriers/posti/status.js +41 -0
- package/dist/carriers/posti/statuses.json +18 -0
- package/dist/carriers/postlogistics/adapter.d.ts +39 -0
- package/dist/carriers/postlogistics/adapter.js +162 -0
- package/dist/carriers/postlogistics/carrier.json +67 -0
- package/dist/carriers/postlogistics/number.d.ts +2 -0
- package/dist/carriers/postlogistics/number.js +7 -0
- package/dist/carriers/postlogistics/numbers.json +54 -0
- package/dist/carriers/postlogistics/status.d.ts +20 -0
- package/dist/carriers/postlogistics/status.js +12 -0
- package/dist/carriers/postlogistics/statuses.json +40 -0
- package/dist/carriers/postnord/adapter.d.ts +11 -0
- package/dist/carriers/postnord/adapter.js +76 -0
- package/dist/carriers/postnord/carrier.json +82 -0
- package/dist/carriers/postnord/numbers.json +66 -0
- package/dist/carriers/postnord/parser.d.ts +3 -0
- package/dist/carriers/postnord/parser.js +75 -0
- package/dist/carriers/postnord/status.d.ts +3 -0
- package/dist/carriers/postnord/status.js +38 -0
- package/dist/carriers/postnord/statuses.json +16 -0
- package/dist/carriers/purolator/adapter.d.ts +11 -0
- package/dist/carriers/purolator/adapter.js +45 -0
- package/dist/carriers/purolator/carrier.json +75 -0
- package/dist/carriers/purolator/numbers.json +146 -0
- package/dist/carriers/purolator/parser.d.ts +3 -0
- package/dist/carriers/purolator/parser.js +79 -0
- package/dist/carriers/purolator/status.d.ts +2 -0
- package/dist/carriers/purolator/status.js +17 -0
- package/dist/carriers/purolator/statuses.json +15 -0
- package/dist/carriers/quickpac/carrier.json +68 -0
- package/dist/carriers/quickpac/numbers.json +31 -0
- package/dist/carriers/quickpac/statuses.json +213 -0
- package/dist/carriers/relais-colis/adapter.d.ts +28 -0
- package/dist/carriers/relais-colis/adapter.js +242 -0
- package/dist/carriers/relais-colis/carrier.json +77 -0
- package/dist/carriers/relais-colis/numbers.json +64 -0
- package/dist/carriers/relais-colis/status.d.ts +26 -0
- package/dist/carriers/relais-colis/status.js +91 -0
- package/dist/carriers/relais-colis/statuses.json +341 -0
- package/dist/carriers/royal-mail/adapter.d.ts +32 -0
- package/dist/carriers/royal-mail/adapter.js +260 -0
- package/dist/carriers/royal-mail/carrier.json +60 -0
- package/dist/carriers/royal-mail/numbers.json +57 -0
- package/dist/carriers/royal-mail/status.d.ts +19 -0
- package/dist/carriers/royal-mail/status.js +80 -0
- package/dist/carriers/royal-mail/statuses.json +16 -0
- package/dist/carriers/seur/adapter.d.ts +11 -0
- package/dist/carriers/seur/adapter.js +35 -0
- package/dist/carriers/seur/carrier.json +89 -0
- package/dist/carriers/seur/numbers.json +80 -0
- package/dist/carriers/seur/parser.d.ts +3 -0
- package/dist/carriers/seur/parser.js +78 -0
- package/dist/carriers/seur/status.d.ts +2 -0
- package/dist/carriers/seur/status.js +14 -0
- package/dist/carriers/seur/statuses.json +47 -0
- package/dist/carriers/sf-express/adapter.d.ts +17 -0
- package/dist/carriers/sf-express/adapter.js +87 -0
- package/dist/carriers/sf-express/carrier.json +78 -0
- package/dist/carriers/sf-express/numbers.json +66 -0
- package/dist/carriers/sf-express/parser.d.ts +4 -0
- package/dist/carriers/sf-express/parser.js +102 -0
- package/dist/carriers/sf-express/status.d.ts +4 -0
- package/dist/carriers/sf-express/status.js +28 -0
- package/dist/carriers/sf-express/statuses.json +334 -0
- package/dist/carriers/shipup/carrier.json +28 -0
- package/dist/carriers/shipup/numbers.json +20 -0
- package/dist/carriers/singapore-post/adapter.d.ts +12 -0
- package/dist/carriers/singapore-post/adapter.js +106 -0
- package/dist/carriers/singapore-post/carrier.json +62 -0
- package/dist/carriers/singapore-post/numbers.json +77 -0
- package/dist/carriers/singapore-post/status.d.ts +2 -0
- package/dist/carriers/singapore-post/status.js +17 -0
- package/dist/carriers/singapore-post/statuses.json +101 -0
- package/dist/carriers/spee-dee/carrier.json +51 -0
- package/dist/carriers/spee-dee/numbers.json +55 -0
- package/dist/carriers/speedx/carrier.json +49 -0
- package/dist/carriers/speedx/numbers.json +112 -0
- package/dist/carriers/spring-gds/adapter.d.ts +35 -0
- package/dist/carriers/spring-gds/adapter.js +212 -0
- package/dist/carriers/spring-gds/carrier.json +90 -0
- package/dist/carriers/spring-gds/numbers.json +224 -0
- package/dist/carriers/spring-gds/status.d.ts +19 -0
- package/dist/carriers/spring-gds/status.js +28 -0
- package/dist/carriers/spring-gds/statuses.json +140 -0
- package/dist/carriers/sto/carrier.json +37 -0
- package/dist/carriers/sto/numbers.json +33 -0
- package/dist/carriers/sunyou/adapter.d.ts +18 -0
- package/dist/carriers/sunyou/adapter.js +156 -0
- package/dist/carriers/sunyou/carrier.json +64 -0
- package/dist/carriers/sunyou/numbers.json +44 -0
- package/dist/carriers/sunyou/status.d.ts +17 -0
- package/dist/carriers/sunyou/status.js +13 -0
- package/dist/carriers/sunyou/statuses.json +53 -0
- package/dist/carriers/swiss-post/adapter.d.ts +18 -0
- package/dist/carriers/swiss-post/adapter.js +282 -0
- package/dist/carriers/swiss-post/carrier.json +84 -0
- package/dist/carriers/swiss-post/numbers.json +55 -0
- package/dist/carriers/swiss-post/status.d.ts +27 -0
- package/dist/carriers/swiss-post/status.js +64 -0
- package/dist/carriers/swiss-post/statuses.json +33 -0
- package/dist/carriers/swiss-post-cargo/adapter.d.ts +19 -0
- package/dist/carriers/swiss-post-cargo/adapter.js +173 -0
- package/dist/carriers/swiss-post-cargo/carrier.json +60 -0
- package/dist/carriers/swiss-post-cargo/numbers.json +23 -0
- package/dist/carriers/swiss-post-cargo/reference.d.ts +13 -0
- package/dist/carriers/swiss-post-cargo/reference.js +48 -0
- package/dist/carriers/swiss-post-cargo/status.d.ts +13 -0
- package/dist/carriers/swiss-post-cargo/status.js +53 -0
- package/dist/carriers/swiss-post-cargo/statuses.json +19 -0
- package/dist/carriers/thailand-post/carrier.json +38 -0
- package/dist/carriers/thailand-post/numbers.json +33 -0
- package/dist/carriers/the-courier-guy/adapter.d.ts +11 -0
- package/dist/carriers/the-courier-guy/adapter.js +49 -0
- package/dist/carriers/the-courier-guy/carrier.json +73 -0
- package/dist/carriers/the-courier-guy/number.d.ts +3 -0
- package/dist/carriers/the-courier-guy/number.js +18 -0
- package/dist/carriers/the-courier-guy/numbers.json +74 -0
- package/dist/carriers/the-courier-guy/parser.d.ts +3 -0
- package/dist/carriers/the-courier-guy/parser.js +104 -0
- package/dist/carriers/the-courier-guy/status.d.ts +5 -0
- package/dist/carriers/the-courier-guy/status.js +21 -0
- package/dist/carriers/the-courier-guy/statuses.json +61 -0
- package/dist/carriers/tipsa/adapter.d.ts +12 -0
- package/dist/carriers/tipsa/adapter.js +52 -0
- package/dist/carriers/tipsa/carrier.json +92 -0
- package/dist/carriers/tipsa/numbers.json +100 -0
- package/dist/carriers/tipsa/parser.d.ts +17 -0
- package/dist/carriers/tipsa/parser.js +114 -0
- package/dist/carriers/tipsa/status.d.ts +3 -0
- package/dist/carriers/tipsa/status.js +25 -0
- package/dist/carriers/tipsa/statuses.json +12 -0
- package/dist/carriers/tnt/adapter.d.ts +23 -0
- package/dist/carriers/tnt/adapter.js +210 -0
- package/dist/carriers/tnt/carrier.json +66 -0
- package/dist/carriers/tnt/numbers.json +116 -0
- package/dist/carriers/tnt/status.d.ts +3 -0
- package/dist/carriers/tnt/status.js +35 -0
- package/dist/carriers/tnt/statuses.json +126 -0
- package/dist/carriers/ukrposhta/adapter.d.ts +13 -0
- package/dist/carriers/ukrposhta/adapter.js +152 -0
- package/dist/carriers/ukrposhta/carrier.json +62 -0
- package/dist/carriers/ukrposhta/numbers.json +53 -0
- package/dist/carriers/ukrposhta/parser.d.ts +15 -0
- package/dist/carriers/ukrposhta/parser.js +130 -0
- package/dist/carriers/ukrposhta/status.d.ts +3 -0
- package/dist/carriers/ukrposhta/status.js +34 -0
- package/dist/carriers/ukrposhta/statuses.json +208 -0
- package/dist/carriers/uniuni/adapter.d.ts +11 -0
- package/dist/carriers/uniuni/adapter.js +48 -0
- package/dist/carriers/uniuni/carrier.json +90 -0
- package/dist/carriers/uniuni/numbers.json +72 -0
- package/dist/carriers/uniuni/parser.d.ts +5 -0
- package/dist/carriers/uniuni/parser.js +114 -0
- package/dist/carriers/uniuni/status.d.ts +2 -0
- package/dist/carriers/uniuni/status.js +16 -0
- package/dist/carriers/uniuni/statuses.json +54 -0
- package/dist/carriers/unknown/carrier.json +57 -0
- package/dist/carriers/unknown/numbers.json +257 -0
- package/dist/carriers/ups/adapter.d.ts +40 -0
- package/dist/carriers/ups/adapter.js +473 -0
- package/dist/carriers/ups/carrier.json +69 -0
- package/dist/carriers/ups/numbers.json +134 -0
- package/dist/carriers/ups/status.d.ts +25 -0
- package/dist/carriers/ups/status.js +41 -0
- package/dist/carriers/ups/statuses.json +35 -0
- package/dist/carriers/usps/adapter.d.ts +25 -0
- package/dist/carriers/usps/adapter.js +261 -0
- package/dist/carriers/usps/carrier.json +74 -0
- package/dist/carriers/usps/numbers.json +286 -0
- package/dist/carriers/usps/status.d.ts +25 -0
- package/dist/carriers/usps/status.js +72 -0
- package/dist/carriers/usps/statuses.json +24 -0
- package/dist/carriers/yamato/adapter.d.ts +13 -0
- package/dist/carriers/yamato/adapter.js +130 -0
- package/dist/carriers/yamato/carrier.json +72 -0
- package/dist/carriers/yamato/numbers.json +57 -0
- package/dist/carriers/yamato/status.d.ts +2 -0
- package/dist/carriers/yamato/status.js +27 -0
- package/dist/carriers/yamato/statuses.json +159 -0
- package/dist/carriers/yanwen/adapter.d.ts +13 -0
- package/dist/carriers/yanwen/adapter.js +130 -0
- package/dist/carriers/yanwen/carrier.json +66 -0
- package/dist/carriers/yanwen/numbers.json +45 -0
- package/dist/carriers/yanwen/status.d.ts +2 -0
- package/dist/carriers/yanwen/status.js +25 -0
- package/dist/carriers/yanwen/statuses.json +131 -0
- package/dist/carriers/yto/adapter.d.ts +11 -0
- package/dist/carriers/yto/adapter.js +36 -0
- package/dist/carriers/yto/carrier.json +75 -0
- package/dist/carriers/yto/numbers.json +33 -0
- package/dist/carriers/yto/parser.d.ts +3 -0
- package/dist/carriers/yto/parser.js +92 -0
- package/dist/carriers/yto/status.d.ts +10 -0
- package/dist/carriers/yto/status.js +46 -0
- package/dist/carriers/yto/statuses.json +206 -0
- package/dist/carriers/yunda/adapter.d.ts +11 -0
- package/dist/carriers/yunda/adapter.js +68 -0
- package/dist/carriers/yunda/carrier.json +69 -0
- package/dist/carriers/yunda/challenge.d.ts +5 -0
- package/dist/carriers/yunda/challenge.js +68 -0
- package/dist/carriers/yunda/numbers.json +43 -0
- package/dist/carriers/yunda/parser.d.ts +4 -0
- package/dist/carriers/yunda/parser.js +105 -0
- package/dist/carriers/yunda/status.d.ts +4 -0
- package/dist/carriers/yunda/status.js +9 -0
- package/dist/carriers/yunda/statuses.json +40 -0
- package/dist/carriers/yunexpress/adapter.d.ts +20 -0
- package/dist/carriers/yunexpress/adapter.js +240 -0
- package/dist/carriers/yunexpress/carrier.json +69 -0
- package/dist/carriers/yunexpress/numbers.json +32 -0
- package/dist/carriers/yunexpress/status.d.ts +2 -0
- package/dist/carriers/yunexpress/status.js +23 -0
- package/dist/carriers/yunexpress/statuses.json +112 -0
- package/dist/carriers/zto/carrier.json +37 -0
- package/dist/carriers/zto/numbers.json +30 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +82 -0
- package/dist/core/adapter/index.d.ts +90 -0
- package/dist/core/adapter/index.js +103 -0
- package/dist/core/adapter/track.d.ts +10 -0
- package/dist/core/adapter/track.js +20 -0
- package/dist/core/catalog/amazon.d.ts +5 -0
- package/dist/core/catalog/amazon.js +33 -0
- package/dist/core/catalog/definitions.d.ts +24 -0
- package/dist/core/catalog/definitions.js +44 -0
- package/dist/core/catalog/handoff.d.ts +9 -0
- package/dist/core/catalog/handoff.js +56 -0
- package/dist/core/catalog/hints.d.ts +45 -0
- package/dist/core/catalog/hints.js +162 -0
- package/dist/core/catalog/index.d.ts +38 -0
- package/dist/core/catalog/index.js +223 -0
- package/dist/core/catalog/inputs.d.ts +6 -0
- package/dist/core/catalog/inputs.js +89 -0
- package/dist/core/catalog/linkRules.d.ts +24 -0
- package/dist/core/catalog/linkRules.js +20 -0
- package/dist/core/catalog/networks.d.ts +9 -0
- package/dist/core/catalog/networks.js +13 -0
- package/dist/core/catalog/recognition.d.ts +22 -0
- package/dist/core/catalog/recognition.js +52 -0
- package/dist/core/catalog/types.d.ts +135 -0
- package/dist/core/catalog/types.js +1 -0
- package/dist/core/catalog/urls.d.ts +2 -0
- package/dist/core/catalog/urls.js +125 -0
- package/dist/core/detection/amazon.d.ts +2 -0
- package/dist/core/detection/amazon.js +14 -0
- package/dist/core/detection/candidates.d.ts +5 -0
- package/dist/core/detection/candidates.js +41 -0
- package/dist/core/detection/detect.d.ts +17 -0
- package/dist/core/detection/detect.js +52 -0
- package/dist/core/detection/gls.d.ts +16 -0
- package/dist/core/detection/gls.js +21 -0
- package/dist/core/detection/hermes.d.ts +14 -0
- package/dist/core/detection/hermes.js +19 -0
- package/dist/core/detection/index.d.ts +19 -0
- package/dist/core/detection/index.js +9 -0
- package/dist/core/detection/mondialRelay.d.ts +13 -0
- package/dist/core/detection/mondialRelay.js +25 -0
- package/dist/core/detection/normalize.d.ts +15 -0
- package/dist/core/detection/normalize.js +39 -0
- package/dist/core/detection/parse.d.ts +6 -0
- package/dist/core/detection/parse.js +112 -0
- package/dist/core/detection/s10.d.ts +4 -0
- package/dist/core/detection/s10.js +25 -0
- package/dist/core/detection/types.d.ts +22 -0
- package/dist/core/detection/types.js +1 -0
- package/dist/core/errors/hint.d.ts +7 -0
- package/dist/core/errors/hint.js +7 -0
- package/dist/core/errors/index.d.ts +98 -0
- package/dist/core/errors/index.js +178 -0
- package/dist/core/recognition/index.d.ts +24 -0
- package/dist/core/recognition/index.js +65 -0
- package/dist/core/result/index.d.ts +57 -0
- package/dist/core/result/index.js +114 -0
- package/dist/core/result/resolve.d.ts +18 -0
- package/dist/core/result/resolve.js +49 -0
- package/dist/core/runner/index.d.ts +33 -0
- package/dist/core/runner/index.js +109 -0
- package/dist/core/status/index.d.ts +22 -0
- package/dist/core/status/index.js +3 -0
- package/dist/core/status/language.d.ts +11 -0
- package/dist/core/status/language.js +149 -0
- package/dist/core/status/wording.d.ts +25 -0
- package/dist/core/status/wording.js +91 -0
- package/dist/core/telemetry/index.d.ts +62 -0
- package/dist/core/telemetry/index.js +55 -0
- package/dist/core/time/index.d.ts +84 -0
- package/dist/core/time/index.js +243 -0
- package/dist/core/time/result.d.ts +5 -0
- package/dist/core/time/result.js +55 -0
- package/dist/core/transport/boundedFetch.d.ts +26 -0
- package/dist/core/transport/boundedFetch.js +152 -0
- package/dist/core/transport/browser.d.ts +14 -0
- package/dist/core/transport/browser.js +113 -0
- package/dist/core/transport/index.d.ts +8 -0
- package/dist/core/transport/index.js +5 -0
- package/dist/core/transport/optional.d.ts +2 -0
- package/dist/core/transport/optional.js +17 -0
- package/dist/core/transport/text.d.ts +8 -0
- package/dist/core/transport/text.js +18 -0
- package/dist/core/transport/trawl.d.ts +80 -0
- package/dist/core/transport/trawl.js +212 -0
- package/dist/core/transport/upstreamHttpDiagnostics.d.ts +16 -0
- package/dist/core/transport/upstreamHttpDiagnostics.js +97 -0
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.js +11 -0
- package/dist/data/catalog.json +3969 -0
- package/dist/facade/index.d.ts +57 -0
- package/dist/facade/index.js +195 -0
- package/dist/generated/catalog.d.ts +2671 -0
- package/dist/generated/catalog.js +4090 -0
- package/dist/generated/recognition.d.ts +2 -0
- package/dist/generated/recognition.js +31 -0
- package/dist/generated/regionTowns.d.ts +2 -0
- package/dist/generated/regionTowns.js +11 -0
- package/dist/generated/registry.d.ts +4 -0
- package/dist/generated/registry.js +286 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +18 -0
- package/dist/node.d.ts +11 -0
- package/dist/node.js +11 -0
- package/dist/places/countries.json +1670 -0
- package/dist/places/facilities.json +11 -0
- package/dist/places/index.d.ts +42 -0
- package/dist/places/index.js +307 -0
- package/dist/places/names.d.mts +15 -0
- package/dist/places/names.mjs +36 -0
- package/dist/places/places.tsv.br +0 -0
- package/dist/places/trackingLocation.d.ts +18 -0
- package/dist/places/trackingLocation.js +89 -0
- package/dist/providers/coverage.d.ts +31 -0
- package/dist/providers/coverage.js +70 -0
- package/dist/providers/coverage.json +1744 -0
- package/dist/providers/parcelsapp/adapter.d.ts +23 -0
- package/dist/providers/parcelsapp/adapter.js +391 -0
- package/dist/providers/parcelsapp/http.d.ts +9 -0
- package/dist/providers/parcelsapp/http.js +67 -0
- package/dist/providers/plan.d.ts +38 -0
- package/dist/providers/plan.js +54 -0
- package/dist/providers/postal-ninja/adapter.d.ts +17 -0
- package/dist/providers/postal-ninja/adapter.js +200 -0
- package/dist/providers/seventeentrack/adapter.d.ts +50 -0
- package/dist/providers/seventeentrack/adapter.js +165 -0
- package/dist/providers/seventeentrack/events.d.ts +4 -0
- package/dist/providers/seventeentrack/events.js +56 -0
- package/dist/providers/shared/capture.d.ts +46 -0
- package/dist/providers/shared/capture.js +92 -0
- package/dist/providers/shared/hints.d.ts +16 -0
- package/dist/providers/shared/hints.js +37 -0
- package/dist/providers/shared/result.d.ts +15 -0
- package/dist/providers/shared/result.js +161 -0
- package/dist/providers/shared/scans.d.ts +22 -0
- package/dist/providers/shared/scans.js +29 -0
- package/dist/providers/ship24/adapter.d.ts +17 -0
- package/dist/providers/ship24/adapter.js +140 -0
- package/dist/providers/ship24/http.d.ts +7 -0
- package/dist/providers/ship24/http.js +75 -0
- package/dist/providers/types.d.ts +1 -0
- package/dist/providers/types.js +1 -0
- package/dist/providers/universal.d.ts +66 -0
- package/dist/providers/universal.js +95 -0
- package/dist/providers/upu/adapter.d.ts +5 -0
- package/dist/providers/upu/adapter.js +107 -0
- package/dist/scripts/canary-report.d.mts +22 -0
- package/dist/scripts/canary-report.mjs +69 -0
- package/dist/scripts/carrier-canary.d.ts +50 -0
- package/dist/scripts/carrier-canary.js +220 -0
- package/dist/server/index.d.ts +20 -0
- package/dist/server/index.js +226 -0
- package/dist/server/openapi.json +487 -0
- package/dist/server/page.d.ts +1 -0
- package/dist/server/page.js +33 -0
- package/package.json +102 -4
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DHL Paket and tracked mail, through the public recipient endpoint behind
|
|
3
|
+
* www.dhl.de (`/int-verfolgen/data`).
|
|
4
|
+
*
|
|
5
|
+
* The lookup establishes a cookie and CSRF session on `/config`, then reads
|
|
6
|
+
* `/search` with the same `verfolgen-CSRF-token` and `verfolgen-wg` headers
|
|
7
|
+
* DHL's own recipient page sends. Cookies stay in memory. A rejected or
|
|
8
|
+
* expired session, and an interrupted read, get one fresh HTTP session inside
|
|
9
|
+
* the `direct` step; only then does the `trawl` step ask the private browser
|
|
10
|
+
* service for a solved session, whose cookies and user agent seed a new HTTP
|
|
11
|
+
* session. Rate limits and server errors stay errors: they are never routed
|
|
12
|
+
* through a browser.
|
|
13
|
+
*
|
|
14
|
+
* DHL's business API credentials are not needed for this public flow.
|
|
15
|
+
*/
|
|
16
|
+
import makeFetchCookie from 'fetch-cookie';
|
|
17
|
+
import { Cookie, CookieJar } from 'tough-cookie';
|
|
18
|
+
import { ChallengeError, IndeterminateError, InputRequiredError, RateLimitedError, SchemaError, } from '../../core/errors/index.js';
|
|
19
|
+
import { carrierIdFromPartnerLinks } from '../../core/catalog/hints.js';
|
|
20
|
+
import { runSteps, singleFlight } from '../../core/runner/index.js';
|
|
21
|
+
import { NOOP_RECORDER } from '../../core/telemetry/index.js';
|
|
22
|
+
import { isoTime } from '../../core/time/index.js';
|
|
23
|
+
import { clean as cleanText, fetchBounded, parseJsonBytes, TrawlClient, UpstreamHttpError, UpstreamNetworkError, } from '../../core/transport/index.js';
|
|
24
|
+
import { isRecord } from '../../core/types.js';
|
|
25
|
+
import { stageForText, statusForStage } from './status.js';
|
|
26
|
+
const PROVIDER = 'DHL';
|
|
27
|
+
const TIMEZONE = 'Europe/Berlin';
|
|
28
|
+
const ORIGIN = 'https://www.dhl.de';
|
|
29
|
+
const DATA_PATH = '/int-verfolgen/data';
|
|
30
|
+
const CONFIG_URL = `${ORIGIN}${DATA_PATH}/config?domain=de&language=en`;
|
|
31
|
+
const TRACKING_PAGE = `${ORIGIN}/en/privatkunden/dhl-sendungsverfolgung.html`;
|
|
32
|
+
const USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36';
|
|
33
|
+
const MAX_BYTES = 2_000_000;
|
|
34
|
+
/**
|
|
35
|
+
* DHL status wording occasionally carries markup. Tags are dropped without a
|
|
36
|
+
* separator, as this adapter has always done, before the shared cleaner
|
|
37
|
+
* collapses whitespace and caps the length.
|
|
38
|
+
*/
|
|
39
|
+
function clean(value, limit = 500) {
|
|
40
|
+
return typeof value === 'string' ? cleanText(value.replace(/<[^>]*>/g, ''), limit) : '';
|
|
41
|
+
}
|
|
42
|
+
export function normalizeDHLTrackingNumber(raw) {
|
|
43
|
+
const value = raw.toUpperCase().replace(/[\s.-]/g, '');
|
|
44
|
+
if (!/^[A-Z0-9]{5,40}$/.test(value))
|
|
45
|
+
throw new TypeError('DHL tracking number is invalid');
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
export function dhlTrackingUrl(number) {
|
|
49
|
+
const url = new URL(TRACKING_PAGE);
|
|
50
|
+
url.searchParams.set('piececode', normalizeDHLTrackingNumber(number));
|
|
51
|
+
return url.toString();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* DHL timestamps carry their own offset and its delivery window is a calendar
|
|
55
|
+
* day; both are kept verbatim rather than normalized, so `core/time` is used
|
|
56
|
+
* to validate them in the German zone only.
|
|
57
|
+
*/
|
|
58
|
+
function date(value) {
|
|
59
|
+
const raw = clean(value, 64);
|
|
60
|
+
if (!/^\d{4}-\d{2}-\d{2}(?:T[\d:.+-]+Z?)?$/.test(raw))
|
|
61
|
+
return '';
|
|
62
|
+
return isoTime(raw, TIMEZONE) ? raw : '';
|
|
63
|
+
}
|
|
64
|
+
function millis(value) {
|
|
65
|
+
return isoTime(value, TIMEZONE)?.timestamp ?? 0;
|
|
66
|
+
}
|
|
67
|
+
function noData() {
|
|
68
|
+
return { status: 'unknown', last_status_text: 'DHL has not published tracking information for this shipment yet', last_update: null, expected_delivery: null, events: [] };
|
|
69
|
+
}
|
|
70
|
+
/** Parse only public status fields: never persist recipient, address, signature or service data. */
|
|
71
|
+
export function parseDHLTrackingResponse(payload, trackingNumber) {
|
|
72
|
+
const requested = normalizeDHLTrackingNumber(trackingNumber);
|
|
73
|
+
if (!isRecord(payload))
|
|
74
|
+
throw new SchemaError(PROVIDER, 'DHL returned an invalid tracking response');
|
|
75
|
+
if (payload.rateLimited === true || payload.isRateLimited === true)
|
|
76
|
+
throw new RateLimitedError(PROVIDER);
|
|
77
|
+
if (!Array.isArray(payload.sendungen))
|
|
78
|
+
throw new SchemaError(PROVIDER, 'DHL returned an invalid tracking response');
|
|
79
|
+
if (payload.sendungen.length === 0)
|
|
80
|
+
throw new SchemaError(PROVIDER, 'DHL returned an empty tracking response');
|
|
81
|
+
const matches = payload.sendungen.filter(isRecord).filter((shipment) => {
|
|
82
|
+
const info = isRecord(shipment.sendungsinfo) ? shipment.sendungsinfo : {};
|
|
83
|
+
const details = isRecord(shipment.sendungsdetails) ? shipment.sendungsdetails : {};
|
|
84
|
+
const numbers = isRecord(details.sendungsnummern) ? details.sendungsnummern : {};
|
|
85
|
+
return [shipment.id, info.gesuchteSendungsnummer, numbers.sendungsnummer]
|
|
86
|
+
.some((value) => clean(value, 64).toUpperCase() === requested);
|
|
87
|
+
});
|
|
88
|
+
if (matches.length !== 1)
|
|
89
|
+
throw new SchemaError(PROVIDER, 'DHL did not return one matching shipment');
|
|
90
|
+
const shipment = matches[0];
|
|
91
|
+
if (shipment.plzBenoetigt === true || shipment.versandDatumBenoetigt === true) {
|
|
92
|
+
throw new InputRequiredError(PROVIDER, 'a postcode or shipping date', 'DHL requires additional verification on its tracking website');
|
|
93
|
+
}
|
|
94
|
+
const missing = isRecord(shipment.sendungNichtGefunden) ? shipment.sendungNichtGefunden : {};
|
|
95
|
+
if (missing.keineDhlPaketSendung === true || missing.sendungsnummerNichtSuchbar === true) {
|
|
96
|
+
throw new IndeterminateError(PROVIDER, 'This DHL service needs its own tracking website');
|
|
97
|
+
}
|
|
98
|
+
const details = isRecord(shipment.sendungsdetails) ? shipment.sendungsdetails : {};
|
|
99
|
+
const timeline = isRecord(details.sendungsverlauf) ? details.sendungsverlauf : {};
|
|
100
|
+
if (timeline.events !== undefined && !Array.isArray(timeline.events))
|
|
101
|
+
throw new SchemaError(PROVIDER, 'DHL returned invalid tracking events');
|
|
102
|
+
const events = (Array.isArray(timeline.events) ? timeline.events : []).filter(isRecord).flatMap((event) => {
|
|
103
|
+
const description = clean(event.status);
|
|
104
|
+
if (!description)
|
|
105
|
+
return [];
|
|
106
|
+
return [{ time: date(event.datum), location: clean(event.ort, 160), description, stage: stageForText(description) }];
|
|
107
|
+
}).sort((left, right) => millis(right.time) - millis(left.time)).slice(0, 100);
|
|
108
|
+
// Arrival notices link to the delivery operator. The catalog resolves its
|
|
109
|
+
// identity; the host still confirms progress through that operator's adapter.
|
|
110
|
+
const deliveryCarrier = carrierIdFromPartnerLinks(events.map((event) => event.description), 'dhl');
|
|
111
|
+
const summary = clean(timeline.status);
|
|
112
|
+
if (!events.length && !summary && details.istZugestellt !== true) {
|
|
113
|
+
if (Object.values(missing).some((flag) => flag === true))
|
|
114
|
+
return noData();
|
|
115
|
+
throw new SchemaError(PROVIDER, 'DHL returned no usable tracking status');
|
|
116
|
+
}
|
|
117
|
+
const currentText = summary || events[0]?.description || 'Delivered';
|
|
118
|
+
const fallback = Number(timeline.fortschritt) <= 1 ? 'registered' : String(events[0]?.stage || 'in_transit');
|
|
119
|
+
const stage = details.istZugestellt === true
|
|
120
|
+
? details.ruecksendung === true ? 'returned' : 'delivered'
|
|
121
|
+
: stageForText(currentText, fallback);
|
|
122
|
+
const delivery = isRecord(details.zustellung) ? details.zustellung : {};
|
|
123
|
+
const expected = date(delivery.zustellzeitfensterVon) || date(delivery.zustellzeitfensterBis);
|
|
124
|
+
return {
|
|
125
|
+
status: statusForStage(stage), current_stage: stage,
|
|
126
|
+
last_status_text: currentText,
|
|
127
|
+
last_update: date(timeline.datumAktuellerStatus) || events[0]?.time || null,
|
|
128
|
+
expected_delivery: ['delivered', 'returned'].includes(stage) ? null : expected.slice(0, 10) || null,
|
|
129
|
+
timezone: TIMEZONE, events,
|
|
130
|
+
...(deliveryCarrier ? { delivery_carrier: deliveryCarrier } : {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* DHL answered with a redirect, an unauthorized status or a non-JSON body:
|
|
135
|
+
* the session is no longer accepted and has to be established again, from a
|
|
136
|
+
* browser when plain HTTP keeps being refused.
|
|
137
|
+
*/
|
|
138
|
+
export class DHLSessionError extends ChallengeError {
|
|
139
|
+
constructor(options) {
|
|
140
|
+
super(PROVIDER, 'DHL rejected the tracking session', options);
|
|
141
|
+
this.name = 'DHLSessionError';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** A rejected session or an interrupted read may be retried; anything else is an answer. */
|
|
145
|
+
/**
|
|
146
|
+
* DHL's edge stops answering a session about two hours after it was opened. It
|
|
147
|
+
* does not reject it: the request hangs until the timeout, and only then does
|
|
148
|
+
* the renewal below succeed in well under a second. Replace the session before
|
|
149
|
+
* that age so the refresh that crosses it does not wait out the timeout first.
|
|
150
|
+
*/
|
|
151
|
+
const SESSION_MAX_AGE_MS = 100 * 60_000;
|
|
152
|
+
function renewable(error) {
|
|
153
|
+
return error instanceof DHLSessionError || error instanceof UpstreamNetworkError;
|
|
154
|
+
}
|
|
155
|
+
class DHLSession {
|
|
156
|
+
timeoutMs;
|
|
157
|
+
jar = new CookieJar();
|
|
158
|
+
fetcher;
|
|
159
|
+
userAgent = USER_AGENT;
|
|
160
|
+
token = '';
|
|
161
|
+
wg = '0';
|
|
162
|
+
constructor(timeoutMs, fetcher) {
|
|
163
|
+
this.timeoutMs = timeoutMs;
|
|
164
|
+
this.fetcher = makeFetchCookie(fetcher ?? fetch, this.jar);
|
|
165
|
+
}
|
|
166
|
+
async seed(cookies, userAgent) {
|
|
167
|
+
this.userAgent = clean(userAgent, 1_024) || USER_AGENT;
|
|
168
|
+
for (const value of cookies) {
|
|
169
|
+
if (!isRecord(value))
|
|
170
|
+
continue;
|
|
171
|
+
const domain = clean(value.domain).toLowerCase().replace(/^\./, '');
|
|
172
|
+
if (domain !== 'dhl.de' && !domain.endsWith('.dhl.de'))
|
|
173
|
+
continue;
|
|
174
|
+
const name = clean(value.name);
|
|
175
|
+
if (!name || typeof value.value !== 'string')
|
|
176
|
+
continue;
|
|
177
|
+
const path = clean(value.path).startsWith('/') ? clean(value.path) : '/';
|
|
178
|
+
await this.jar.setCookie(new Cookie({
|
|
179
|
+
key: name, value: value.value, domain, path,
|
|
180
|
+
secure: value.secure === true, httpOnly: value.httpOnly === true,
|
|
181
|
+
expires: typeof value.expires === 'number' && value.expires > 0 ? new Date(value.expires * 1_000) : 'Infinity',
|
|
182
|
+
}), `https://${domain}${path}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async fetch(number) {
|
|
186
|
+
if (!this.token) {
|
|
187
|
+
const config = await this.request(CONFIG_URL);
|
|
188
|
+
if (typeof config.verfolgenCsrfToken !== 'string' || !config.verfolgenCsrfToken)
|
|
189
|
+
throw new DHLSessionError();
|
|
190
|
+
this.token = config.verfolgenCsrfToken;
|
|
191
|
+
this.wg = typeof config.initialWG === 'number' ? String(config.initialWG) : '0';
|
|
192
|
+
}
|
|
193
|
+
const url = new URL(`${ORIGIN}${DATA_PATH}/search`);
|
|
194
|
+
url.search = new URLSearchParams({ piececode: number, noRedirect: 'true', language: 'en' }).toString();
|
|
195
|
+
return parseDHLTrackingResponse(await this.request(url), number);
|
|
196
|
+
}
|
|
197
|
+
async request(url) {
|
|
198
|
+
const { response, bytes } = await fetchBounded(url, { headers: {
|
|
199
|
+
Accept: 'application/json, text/plain, */*', 'Accept-Language': 'en-US,en;q=0.9',
|
|
200
|
+
'User-Agent': this.userAgent, Referer: TRACKING_PAGE,
|
|
201
|
+
'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Dest': 'empty',
|
|
202
|
+
...(this.token ? { 'verfolgen-CSRF-token': this.token, 'verfolgen-wg': this.wg } : {}),
|
|
203
|
+
} }, {
|
|
204
|
+
provider: PROVIDER, timeoutMs: this.timeoutMs, maxBytes: MAX_BYTES,
|
|
205
|
+
fetcher: this.fetcher, redirect: 'manual', allowHttpError: true,
|
|
206
|
+
});
|
|
207
|
+
if ([301, 302, 303, 307, 308, 401, 403, 419].includes(response.status))
|
|
208
|
+
throw new DHLSessionError();
|
|
209
|
+
if (!response.ok)
|
|
210
|
+
throw new UpstreamHttpError(PROVIDER, response.status);
|
|
211
|
+
if (!response.headers.get('content-type')?.includes('application/json'))
|
|
212
|
+
throw new DHLSessionError();
|
|
213
|
+
const value = parseJsonBytes(bytes, PROVIDER);
|
|
214
|
+
if (!isRecord(value))
|
|
215
|
+
throw new SchemaError(PROVIDER, 'DHL returned an invalid tracking response');
|
|
216
|
+
const token = response.headers.get('verfolgen-CSRF-token');
|
|
217
|
+
if (token)
|
|
218
|
+
this.token = token;
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
export class DHLTracker {
|
|
223
|
+
timeoutMs;
|
|
224
|
+
directTimeoutMs;
|
|
225
|
+
budgetMs;
|
|
226
|
+
trawlUrl;
|
|
227
|
+
trawl;
|
|
228
|
+
fetcher;
|
|
229
|
+
recorder;
|
|
230
|
+
serialize = singleFlight();
|
|
231
|
+
now;
|
|
232
|
+
session = null;
|
|
233
|
+
sessionOpenedAt = 0;
|
|
234
|
+
constructor(options = {}) {
|
|
235
|
+
this.timeoutMs = options.timeoutMs ?? 60_000;
|
|
236
|
+
this.directTimeoutMs = options.directTimeoutMs ?? 15_000;
|
|
237
|
+
// Two direct sessions (config plus search each) and a browser solve
|
|
238
|
+
// followed by the session it seeds, with room for the transport itself.
|
|
239
|
+
this.budgetMs = options.budgetMs ?? this.timeoutMs + 4 * this.directTimeoutMs + 30_000;
|
|
240
|
+
this.trawl = options.trawl ?? null;
|
|
241
|
+
this.trawlUrl = (options.trawlUrl ?? '').trim();
|
|
242
|
+
this.fetcher = options.fetcher;
|
|
243
|
+
this.recorder = options.recorder ?? NOOP_RECORDER;
|
|
244
|
+
this.now = options.now ?? Date.now;
|
|
245
|
+
}
|
|
246
|
+
open(session) {
|
|
247
|
+
this.session = session;
|
|
248
|
+
this.sessionOpenedAt = this.now();
|
|
249
|
+
return session;
|
|
250
|
+
}
|
|
251
|
+
/** Lookups share one session, so two parcels never renew it at the same time. */
|
|
252
|
+
async fetch(trackingNumber) {
|
|
253
|
+
const number = normalizeDHLTrackingNumber(trackingNumber);
|
|
254
|
+
return this.serialize(() => this.lookup(number));
|
|
255
|
+
}
|
|
256
|
+
async lookup(number) {
|
|
257
|
+
try {
|
|
258
|
+
return await runSteps({ carrier: 'dhl', budgetMs: this.budgetMs, recorder: this.recorder }, [
|
|
259
|
+
{ id: 'direct', run: () => this.direct(number) },
|
|
260
|
+
{ id: 'trawl', enabled: this.trawl !== null || this.trawlUrl !== '', recovers: renewable, run: () => this.browser(number) },
|
|
261
|
+
]);
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
// A session that ended the lookup is never reused by the next one.
|
|
265
|
+
if (renewable(error))
|
|
266
|
+
this.session = null;
|
|
267
|
+
throw error;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/** The direct session, renewing a stale one or an interrupted read once. */
|
|
271
|
+
async direct(number) {
|
|
272
|
+
if (this.session !== null && this.now() - this.sessionOpenedAt >= SESSION_MAX_AGE_MS)
|
|
273
|
+
this.session = null;
|
|
274
|
+
const cached = this.session !== null;
|
|
275
|
+
const session = this.session ?? this.open(new DHLSession(this.directTimeoutMs, this.fetcher));
|
|
276
|
+
try {
|
|
277
|
+
return await session.fetch(number);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
// A fresh session that was rejected outright needs a browser, not a
|
|
281
|
+
// second identical attempt; a cached one may simply have expired.
|
|
282
|
+
if (!renewable(error) || (!cached && !(error instanceof UpstreamNetworkError)))
|
|
283
|
+
throw error;
|
|
284
|
+
return await this.open(new DHLSession(this.directTimeoutMs, this.fetcher)).fetch(number);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** A solved browser session, replayed over HTTP with its cookies and user agent. */
|
|
288
|
+
async browser(number) {
|
|
289
|
+
this.session = null;
|
|
290
|
+
const trawl = this.trawl ?? new TrawlClient(this.trawlUrl, this.fetcher);
|
|
291
|
+
const solved = await trawl.scrape({ url: dhlTrackingUrl(number), skipHttp: true, maxTier: 3, maxTimeout: this.timeoutMs }, { provider: `TRAWL while fetching ${PROVIDER}`, timeoutMs: this.timeoutMs, maxBytes: 10_000_000, fetcher: this.fetcher });
|
|
292
|
+
const session = new DHLSession(this.directTimeoutMs, this.fetcher);
|
|
293
|
+
await session.seed(solved.cookies, solved.userAgent);
|
|
294
|
+
const result = await session.fetch(number);
|
|
295
|
+
this.open(session);
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
export const adapter = (environment) => {
|
|
300
|
+
const tracker = new DHLTracker({
|
|
301
|
+
fetcher: environment.fetcher, trawl: environment.trawl, trawlUrl: '', recorder: environment.recorder,
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
id: 'dhl',
|
|
305
|
+
steps: ['direct', 'trawl'],
|
|
306
|
+
track: (input) => tracker.fetch(input.number),
|
|
307
|
+
};
|
|
308
|
+
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "dhl",
|
|
3
|
+
"displayName": "DHL",
|
|
4
|
+
"aliases": [
|
|
5
|
+
"DHL Paket",
|
|
6
|
+
"Deutsche Post DHL"
|
|
7
|
+
],
|
|
8
|
+
"region": {
|
|
9
|
+
"countries": [
|
|
10
|
+
"DE"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"brand": {
|
|
14
|
+
"color": "#ffcc00"
|
|
15
|
+
},
|
|
16
|
+
"selectable": true,
|
|
17
|
+
"timezone": "Europe/Berlin",
|
|
18
|
+
"tracking": {
|
|
19
|
+
"mode": "automatic",
|
|
20
|
+
"adapter": "dhl",
|
|
21
|
+
"steps": [
|
|
22
|
+
"direct",
|
|
23
|
+
"trawl"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"capabilities": [
|
|
27
|
+
"history",
|
|
28
|
+
"location",
|
|
29
|
+
"eta"
|
|
30
|
+
],
|
|
31
|
+
"portal": {
|
|
32
|
+
"url": "https://www.dhl.de/en/privatkunden/dhl-sendungsverfolgung.html?piececode={trackingNumber}",
|
|
33
|
+
"canaryUrl": "https://www.dhl.de/en/privatkunden/dhl-sendungsverfolgung.html",
|
|
34
|
+
"shows": [
|
|
35
|
+
"status",
|
|
36
|
+
"history",
|
|
37
|
+
"location",
|
|
38
|
+
"eta",
|
|
39
|
+
"recipient_name",
|
|
40
|
+
"recipient_address",
|
|
41
|
+
"signature"
|
|
42
|
+
],
|
|
43
|
+
"scraped": [
|
|
44
|
+
"status",
|
|
45
|
+
"history",
|
|
46
|
+
"location",
|
|
47
|
+
"eta"
|
|
48
|
+
],
|
|
49
|
+
"discarded": [
|
|
50
|
+
"recipient_name",
|
|
51
|
+
"recipient_address",
|
|
52
|
+
"signature"
|
|
53
|
+
],
|
|
54
|
+
"unavailable": []
|
|
55
|
+
},
|
|
56
|
+
"links": [
|
|
57
|
+
{
|
|
58
|
+
"domains": [
|
|
59
|
+
"dhl.com",
|
|
60
|
+
"dhl.de",
|
|
61
|
+
"deutschepost.de"
|
|
62
|
+
],
|
|
63
|
+
"params": [
|
|
64
|
+
"tracking-id",
|
|
65
|
+
"trackingId",
|
|
66
|
+
"piececode"
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"detection": [
|
|
71
|
+
{
|
|
72
|
+
"id": "dhl-1",
|
|
73
|
+
"pattern": "^[CL][A-Z]\\d{9}DE$",
|
|
74
|
+
"confidence": "high",
|
|
75
|
+
"checksum": "s10"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "dhl-2",
|
|
79
|
+
"pattern": "^(JJD|JVGL)[A-Z0-9]{8,}$",
|
|
80
|
+
"confidence": "high"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "dhl-3",
|
|
84
|
+
"pattern": "^\\d{10}$",
|
|
85
|
+
"confidence": "low"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"id": "dhl-4",
|
|
89
|
+
"pattern": "^JD\\d{18}$",
|
|
90
|
+
"confidence": "high"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "dhl-5",
|
|
94
|
+
"pattern": "^00340434\\d{12}$",
|
|
95
|
+
"confidence": "high"
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
{
|
|
2
|
+
"carrier": "dhl",
|
|
3
|
+
"records": [
|
|
4
|
+
{
|
|
5
|
+
"number": "00340434633751428115",
|
|
6
|
+
"role": "shipment",
|
|
7
|
+
"evidence": "public_shipment_report",
|
|
8
|
+
"source": {
|
|
9
|
+
"url": "https://www.paketda.de/fragen-antworten",
|
|
10
|
+
"date": "2026-04-10"
|
|
11
|
+
},
|
|
12
|
+
"expect": {
|
|
13
|
+
"carrier": "dhl",
|
|
14
|
+
"confidence": "high"
|
|
15
|
+
},
|
|
16
|
+
"note": "Publicly reported shipment number; the attribution was not independently verified."
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"number": "8449089972",
|
|
20
|
+
"role": "shipment",
|
|
21
|
+
"evidence": "merchant_published_example",
|
|
22
|
+
"source": {
|
|
23
|
+
"url": "https://marketplace.fnacdarty.com/s/article/Dois-je-obligatoirement-renseigner-un-num%C3%A9ro-de-suivi-tracking-pour-ma-commande?language=fr_BE"
|
|
24
|
+
},
|
|
25
|
+
"expect": {
|
|
26
|
+
"carrier": "unknown",
|
|
27
|
+
"confidence": "low",
|
|
28
|
+
"candidates": [
|
|
29
|
+
"dhl",
|
|
30
|
+
"mondial-relay",
|
|
31
|
+
"relais-colis",
|
|
32
|
+
"tipsa",
|
|
33
|
+
"estafeta"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"note": "Published integration example, not a real shipment. The source attributes it to DHL, which stays one candidate among several."
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"number": "CG738165082DE",
|
|
40
|
+
"role": "shipment",
|
|
41
|
+
"evidence": "public_shipment_report",
|
|
42
|
+
"source": {
|
|
43
|
+
"url": "https://fr.trustpilot.com/review/www.dhl.fr",
|
|
44
|
+
"date": "2026-08-31"
|
|
45
|
+
},
|
|
46
|
+
"expect": {
|
|
47
|
+
"carrier": "dhl",
|
|
48
|
+
"confidence": "high"
|
|
49
|
+
},
|
|
50
|
+
"note": "Publicly reported shipment number; the attribution was not independently verified."
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"number": "CY123456785DE",
|
|
54
|
+
"role": "shipment",
|
|
55
|
+
"evidence": "synthetic",
|
|
56
|
+
"derivedFrom": "official_shape",
|
|
57
|
+
"shapeConfirmed": "2026-09-12",
|
|
58
|
+
"expect": {
|
|
59
|
+
"carrier": "dhl",
|
|
60
|
+
"confidence": "high"
|
|
61
|
+
},
|
|
62
|
+
"note": "Made-up number that follows the published format."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"number": "JD014600011678034918",
|
|
66
|
+
"role": "shipment",
|
|
67
|
+
"evidence": "merchant_published_example",
|
|
68
|
+
"source": {
|
|
69
|
+
"url": "https://marketplace.fnacdarty.com/s/article/Dois-je-obligatoirement-renseigner-un-num%C3%A9ro-de-suivi-tracking-pour-ma-commande?language=fr_BE"
|
|
70
|
+
},
|
|
71
|
+
"expect": {
|
|
72
|
+
"carrier": "dhl",
|
|
73
|
+
"confidence": "high"
|
|
74
|
+
},
|
|
75
|
+
"note": "Published integration example, not a real shipment."
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"number": "JJD0099999999",
|
|
79
|
+
"role": "shipment",
|
|
80
|
+
"evidence": "synthetic",
|
|
81
|
+
"derivedFrom": "official_shape",
|
|
82
|
+
"shapeConfirmed": "2026-09-12",
|
|
83
|
+
"expect": {
|
|
84
|
+
"carrier": "dhl",
|
|
85
|
+
"confidence": "high"
|
|
86
|
+
},
|
|
87
|
+
"note": "Made-up number that follows the published format."
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"number": "JVGL0099999999",
|
|
91
|
+
"role": "shipment",
|
|
92
|
+
"evidence": "synthetic",
|
|
93
|
+
"derivedFrom": "official_shape",
|
|
94
|
+
"shapeConfirmed": "2026-09-12",
|
|
95
|
+
"expect": {
|
|
96
|
+
"carrier": "dhl",
|
|
97
|
+
"confidence": "high"
|
|
98
|
+
},
|
|
99
|
+
"note": "Made-up number that follows the published format."
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"number": "LF123456785DE",
|
|
103
|
+
"role": "shipment",
|
|
104
|
+
"evidence": "synthetic",
|
|
105
|
+
"derivedFrom": "official_shape",
|
|
106
|
+
"shapeConfirmed": "2026-09-12",
|
|
107
|
+
"expect": {
|
|
108
|
+
"carrier": "dhl",
|
|
109
|
+
"confidence": "high"
|
|
110
|
+
},
|
|
111
|
+
"note": "Made-up number that follows the published format."
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"number": "LF123456785US",
|
|
115
|
+
"role": "shipment",
|
|
116
|
+
"evidence": "synthetic",
|
|
117
|
+
"derivedFrom": "official_shape",
|
|
118
|
+
"shapeConfirmed": "2026-09-12",
|
|
119
|
+
"expect": {
|
|
120
|
+
"carrier": "intl-post",
|
|
121
|
+
"confidence": "high"
|
|
122
|
+
},
|
|
123
|
+
"note": "Made-up number that follows the published format. Filed under DHL; detection falls back to the generic postal rule."
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"number": "LF123456789DE",
|
|
127
|
+
"role": "shipment",
|
|
128
|
+
"evidence": "synthetic",
|
|
129
|
+
"derivedFrom": "invented",
|
|
130
|
+
"shapeConfirmed": "2026-09-12",
|
|
131
|
+
"expect": {
|
|
132
|
+
"carrier": "unknown",
|
|
133
|
+
"confidence": "low",
|
|
134
|
+
"candidates": [
|
|
135
|
+
"chronopost"
|
|
136
|
+
]
|
|
137
|
+
},
|
|
138
|
+
"note": "Invented placeholder used as a shape check. Filed under DHL, which no rule claims."
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"number": "LX123456785DE",
|
|
142
|
+
"role": "shipment",
|
|
143
|
+
"evidence": "synthetic",
|
|
144
|
+
"derivedFrom": "official_shape",
|
|
145
|
+
"shapeConfirmed": "2026-09-12",
|
|
146
|
+
"expect": {
|
|
147
|
+
"carrier": "dhl",
|
|
148
|
+
"confidence": "high"
|
|
149
|
+
},
|
|
150
|
+
"note": "Made-up number that follows the published format."
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DHL wording → product stage.
|
|
3
|
+
*
|
|
4
|
+
* DHL's public `/int-verfolgen/data` payload carries no status code: the
|
|
5
|
+
* shipment history is free text in the language the page was requested in
|
|
6
|
+
* (English here, with German wording still returned for domestic scans), so
|
|
7
|
+
* this map is a wording classifier rather than a code table. Rules are
|
|
8
|
+
* ordered so that a negative, a forecast or a handoff wins before the broad
|
|
9
|
+
* delivery words, and anything unrecognized keeps the caller's fallback
|
|
10
|
+
* instead of inventing progress.
|
|
11
|
+
*/
|
|
12
|
+
import type { CarrierStatus } from '../../core/result/index.js';
|
|
13
|
+
export declare function stageForText(text: string, fallback?: string): string;
|
|
14
|
+
export declare function statusForStage(stage: string): CarrierStatus;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { trackingLanguageStage } from '../../core/status/index.js';
|
|
2
|
+
export function stageForText(text, fallback = 'in_transit') {
|
|
3
|
+
const value = text.toLowerCase();
|
|
4
|
+
if (/return(?:ed|ing)? to (?:the )?sender|zurück.*absender|rücksendung|retour/.test(value))
|
|
5
|
+
return 'returned';
|
|
6
|
+
if (/not delivered|could not be delivered|unable to deliver|delivery attempt|nicht.*zugestellt|zustellversuch|nicht angetroffen/.test(value))
|
|
7
|
+
return 'failed_attempt';
|
|
8
|
+
// GENERATED equivalents of DHL's existing forecast behavior: a forecast retains
|
|
9
|
+
// the structured progress fallback; it cannot establish delivery or pre-advice.
|
|
10
|
+
if (/will be delivered|sera livr[ée]|wird\s+(?!zugestellt\b).+zugestellt|sar[àa] consegnat/.test(value))
|
|
11
|
+
return fallback;
|
|
12
|
+
const translated = trackingLanguageStage(text);
|
|
13
|
+
if (translated)
|
|
14
|
+
return translated;
|
|
15
|
+
if (/ready for (?:pickup|collection)|ready to (?:collect|pick up)|awaiting collection|abholbereit|zur abholung bereit/.test(value))
|
|
16
|
+
return 'ready_for_pickup';
|
|
17
|
+
if (/has been delivered|was delivered|successfully delivered|^delivered\b|erfolgreich zugestellt|wurde.*zugestellt/.test(value))
|
|
18
|
+
return 'delivered';
|
|
19
|
+
if (/^being delivered[.!]?$|out for delivery|loaded (?:into|onto).*delivery vehicle|in das zustellfahrzeug geladen|in zustellung/.test(value))
|
|
20
|
+
return 'out_for_delivery';
|
|
21
|
+
if (/customs clearance process\b[^.]*\bhas been completed\b/.test(value))
|
|
22
|
+
return 'in_transit';
|
|
23
|
+
if (/customs|zoll/.test(value))
|
|
24
|
+
return 'customs';
|
|
25
|
+
if (/electronically|elektronisch|label created|shipment information|instruction data/.test(value))
|
|
26
|
+
return 'registered';
|
|
27
|
+
if (/will be transported to the destination country/.test(value))
|
|
28
|
+
return 'in_transit';
|
|
29
|
+
if (/pick-up was successful|accepted|handed (?:over|to)|eingeliefert|übergeben/.test(value))
|
|
30
|
+
return 'accepted';
|
|
31
|
+
if (/processed|sorted|sorting|sortierung|bearbeitet|briefzentrum|paketzentrum|transit|transport|arrived|departed/.test(value))
|
|
32
|
+
return 'in_transit';
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
export function statusForStage(stage) {
|
|
36
|
+
if (stage === 'registered' || stage === 'pending')
|
|
37
|
+
return 'pending';
|
|
38
|
+
if (stage === 'delivered')
|
|
39
|
+
return 'delivered';
|
|
40
|
+
if (stage === 'out_for_delivery' || stage === 'ready_for_pickup')
|
|
41
|
+
return 'out_for_delivery';
|
|
42
|
+
if (stage === 'failed_attempt' || stage === 'returned')
|
|
43
|
+
return 'exception';
|
|
44
|
+
return 'in_transit';
|
|
45
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"carrier": "dhl",
|
|
3
|
+
"entries": [
|
|
4
|
+
{ "wording": "The instruction data for this shipment have been provided by the sender to DHL electronically", "language": "en", "stage": "registered", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Pre-advice; matched on \"electronically\"." },
|
|
5
|
+
{ "wording": "Die Sendung wurde vom Absender elektronisch angekündigt.", "language": "de", "stage": "registered", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "German pre-advice; matched on \"elektronisch\"." },
|
|
6
|
+
{ "wording": "The shipment was handed over to DHL.", "language": "en", "stage": "accepted", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
7
|
+
{ "wording": "Die Sendung wurde im Briefzentrum bearbeitet.", "language": "de", "stage": "in_transit", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Mail-centre processing scan." },
|
|
8
|
+
{ "wording": "The shipment has been processed in the parcel center", "language": "en", "stage": "in_transit", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
9
|
+
{ "wording": "The shipment will be transported to the destination country/destination area and, from there, handed over to the delivery organization.", "language": "en", "stage": "in_transit", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Explicitly transit, never the handover it announces." },
|
|
10
|
+
{ "wording": "The shipment has arrived in the destination country/destination area.", "language": "en", "stage": "in_transit", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Carries the destination operator's link; an exact post.ch host marks a Swiss Post last mile." },
|
|
11
|
+
{ "wording": "The shipment is being processed by customs", "language": "en", "stage": "customs", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
12
|
+
{ "wording": "The customs clearance process for import into the destination country/region has been completed.", "language": "en", "stage": "in_transit", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Completion leaves customs; the started variant stays in customs." },
|
|
13
|
+
{ "wording": "The shipment has been loaded into the delivery vehicle", "language": "en", "stage": "out_for_delivery", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
14
|
+
{ "wording": "Die Sendung wurde in das Zustellfahrzeug geladen.", "language": "de", "stage": "out_for_delivery", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
15
|
+
{ "wording": "The shipment is ready for collection", "language": "en", "stage": "ready_for_pickup", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
16
|
+
{ "wording": "Die Sendung liegt zur Abholung bereit.", "language": "de", "stage": "ready_for_pickup", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
17
|
+
{ "wording": "The shipment has been delivered", "language": "en", "stage": "delivered", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
18
|
+
{ "wording": "Die Sendung wurde erfolgreich zugestellt.", "language": "de", "stage": "delivered", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "The negated form maps to failed_attempt, not delivery." },
|
|
19
|
+
{ "wording": "The shipment could not be delivered", "language": "en", "stage": "failed_attempt", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
20
|
+
{ "wording": "Die Sendung konnte nicht zugestellt werden.", "language": "de", "stage": "failed_attempt", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
21
|
+
{ "wording": "Die Sendung wurde nicht erfolgreich zugestellt.", "language": "de", "stage": "failed_attempt", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Negation is matched before the delivery wording." },
|
|
22
|
+
{ "wording": "The shipment is returning to sender", "language": "en", "stage": "returned", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "" },
|
|
23
|
+
{ "wording": "The shipment will be delivered tomorrow", "language": "en", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Forecast: deliberately unmapped. It keeps the structured progress fallback rather than announcing delivery or pre-advice." },
|
|
24
|
+
{ "code": "istZugestellt=true", "stage": "delivered", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "Structured completion flag; outranks the wording." },
|
|
25
|
+
{ "code": "istZugestellt=true,ruecksendung=true", "stage": "returned", "confirmedBy": "fixture", "firstSeen": "2026-09-12", "note": "A completed return, not a delivery." }
|
|
26
|
+
]
|
|
27
|
+
}
|