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.
Files changed (897) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +15 -0
  3. package/README.md +123 -2
  4. package/data/carrier-order.json +107 -0
  5. package/data/carrier.schema.json +415 -0
  6. package/data/catalog.json +3969 -0
  7. package/data/coverage-summary.json +17 -0
  8. package/data/detection-golden.json +5375 -0
  9. package/data/stages.json +13 -0
  10. package/dist/browser/scraper.js +9292 -0
  11. package/dist/carriers/aliexpress/adapter.d.ts +30 -0
  12. package/dist/carriers/aliexpress/adapter.js +164 -0
  13. package/dist/carriers/aliexpress/carrier.json +59 -0
  14. package/dist/carriers/aliexpress/numbers.json +36 -0
  15. package/dist/carriers/aliexpress/status.d.ts +31 -0
  16. package/dist/carriers/aliexpress/status.js +79 -0
  17. package/dist/carriers/aliexpress/statuses.json +355 -0
  18. package/dist/carriers/amazon-logistics/carrier.json +94 -0
  19. package/dist/carriers/amazon-logistics/numbers.json +307 -0
  20. package/dist/carriers/amazon-shipping/adapter.d.ts +34 -0
  21. package/dist/carriers/amazon-shipping/adapter.js +292 -0
  22. package/dist/carriers/amazon-shipping/carrier.json +96 -0
  23. package/dist/carriers/amazon-shipping/eligibility.d.ts +3 -0
  24. package/dist/carriers/amazon-shipping/eligibility.js +16 -0
  25. package/dist/carriers/amazon-shipping/numbers.json +67 -0
  26. package/dist/carriers/amazon-shipping/status.d.ts +26 -0
  27. package/dist/carriers/amazon-shipping/status.js +118 -0
  28. package/dist/carriers/amazon-shipping/statuses.json +19 -0
  29. package/dist/carriers/an-post/carrier.json +38 -0
  30. package/dist/carriers/an-post/numbers.json +33 -0
  31. package/dist/carriers/aramex/adapter.d.ts +11 -0
  32. package/dist/carriers/aramex/adapter.js +49 -0
  33. package/dist/carriers/aramex/carrier.json +62 -0
  34. package/dist/carriers/aramex/numbers.json +71 -0
  35. package/dist/carriers/aramex/parser.d.ts +5 -0
  36. package/dist/carriers/aramex/parser.js +83 -0
  37. package/dist/carriers/aramex/status.d.ts +2 -0
  38. package/dist/carriers/aramex/status.js +16 -0
  39. package/dist/carriers/aramex/statuses.json +41 -0
  40. package/dist/carriers/asendia/adapter.d.ts +82 -0
  41. package/dist/carriers/asendia/adapter.js +342 -0
  42. package/dist/carriers/asendia/carrier.json +91 -0
  43. package/dist/carriers/asendia/numbers.json +177 -0
  44. package/dist/carriers/asendia/probe.d.ts +31 -0
  45. package/dist/carriers/asendia/probe.js +355 -0
  46. package/dist/carriers/asendia/status.d.ts +41 -0
  47. package/dist/carriers/asendia/status.js +147 -0
  48. package/dist/carriers/asendia/statuses.json +877 -0
  49. package/dist/carriers/australia-post/adapter.d.ts +20 -0
  50. package/dist/carriers/australia-post/adapter.js +175 -0
  51. package/dist/carriers/australia-post/carrier.json +72 -0
  52. package/dist/carriers/australia-post/numbers.json +66 -0
  53. package/dist/carriers/australia-post/status.d.ts +2 -0
  54. package/dist/carriers/australia-post/status.js +34 -0
  55. package/dist/carriers/australia-post/statuses.json +172 -0
  56. package/dist/carriers/austrian-post/adapter.d.ts +13 -0
  57. package/dist/carriers/austrian-post/adapter.js +101 -0
  58. package/dist/carriers/austrian-post/carrier.json +58 -0
  59. package/dist/carriers/austrian-post/numbers.json +73 -0
  60. package/dist/carriers/austrian-post/status.d.ts +3 -0
  61. package/dist/carriers/austrian-post/status.js +30 -0
  62. package/dist/carriers/austrian-post/statuses.json +47 -0
  63. package/dist/carriers/blue-dart/adapter.d.ts +11 -0
  64. package/dist/carriers/blue-dart/adapter.js +34 -0
  65. package/dist/carriers/blue-dart/carrier.json +59 -0
  66. package/dist/carriers/blue-dart/numbers.json +113 -0
  67. package/dist/carriers/blue-dart/parser.d.ts +3 -0
  68. package/dist/carriers/blue-dart/parser.js +75 -0
  69. package/dist/carriers/blue-dart/status.d.ts +2 -0
  70. package/dist/carriers/blue-dart/status.js +14 -0
  71. package/dist/carriers/blue-dart/statuses.json +59 -0
  72. package/dist/carriers/bpost/adapter.d.ts +11 -0
  73. package/dist/carriers/bpost/adapter.js +46 -0
  74. package/dist/carriers/bpost/carrier.json +81 -0
  75. package/dist/carriers/bpost/numbers.json +103 -0
  76. package/dist/carriers/bpost/parser.d.ts +3 -0
  77. package/dist/carriers/bpost/parser.js +84 -0
  78. package/dist/carriers/bpost/status.d.ts +2 -0
  79. package/dist/carriers/bpost/status.js +18 -0
  80. package/dist/carriers/bpost/statuses.json +96 -0
  81. package/dist/carriers/bring-posten/adapter.d.ts +11 -0
  82. package/dist/carriers/bring-posten/adapter.js +35 -0
  83. package/dist/carriers/bring-posten/carrier.json +91 -0
  84. package/dist/carriers/bring-posten/numbers.json +33 -0
  85. package/dist/carriers/bring-posten/parser.d.ts +3 -0
  86. package/dist/carriers/bring-posten/parser.js +95 -0
  87. package/dist/carriers/bring-posten/status.d.ts +3 -0
  88. package/dist/carriers/bring-posten/status.js +23 -0
  89. package/dist/carriers/bring-posten/statuses.json +33 -0
  90. package/dist/carriers/brt/adapter.d.ts +11 -0
  91. package/dist/carriers/brt/adapter.js +36 -0
  92. package/dist/carriers/brt/carrier.json +80 -0
  93. package/dist/carriers/brt/numbers.json +91 -0
  94. package/dist/carriers/brt/parser.d.ts +3 -0
  95. package/dist/carriers/brt/parser.js +84 -0
  96. package/dist/carriers/brt/status.d.ts +2 -0
  97. package/dist/carriers/brt/status.js +14 -0
  98. package/dist/carriers/brt/statuses.json +53 -0
  99. package/dist/carriers/c-chez-vous/adapter.d.ts +31 -0
  100. package/dist/carriers/c-chez-vous/adapter.js +181 -0
  101. package/dist/carriers/c-chez-vous/carrier.json +69 -0
  102. package/dist/carriers/c-chez-vous/numbers.json +31 -0
  103. package/dist/carriers/c-chez-vous/status.d.ts +27 -0
  104. package/dist/carriers/c-chez-vous/status.js +19 -0
  105. package/dist/carriers/c-chez-vous/statuses.json +10 -0
  106. package/dist/carriers/canada-post/adapter.d.ts +40 -0
  107. package/dist/carriers/canada-post/adapter.js +78 -0
  108. package/dist/carriers/canada-post/carrier.json +77 -0
  109. package/dist/carriers/canada-post/numbers.json +81 -0
  110. package/dist/carriers/canada-post/parser.d.ts +5 -0
  111. package/dist/carriers/canada-post/parser.js +202 -0
  112. package/dist/carriers/canada-post/status.d.ts +9 -0
  113. package/dist/carriers/canada-post/status.js +67 -0
  114. package/dist/carriers/canada-post/statuses.json +171 -0
  115. package/dist/carriers/canpar/adapter.d.ts +11 -0
  116. package/dist/carriers/canpar/adapter.js +40 -0
  117. package/dist/carriers/canpar/carrier.json +74 -0
  118. package/dist/carriers/canpar/numbers.json +71 -0
  119. package/dist/carriers/canpar/parser.d.ts +3 -0
  120. package/dist/carriers/canpar/parser.js +75 -0
  121. package/dist/carriers/canpar/status.d.ts +2 -0
  122. package/dist/carriers/canpar/status.js +16 -0
  123. package/dist/carriers/canpar/statuses.json +82 -0
  124. package/dist/carriers/china-post/carrier.json +38 -0
  125. package/dist/carriers/china-post/numbers.json +59 -0
  126. package/dist/carriers/chronopost/carrier.json +84 -0
  127. package/dist/carriers/chronopost/numbers.json +110 -0
  128. package/dist/carriers/chronopost/statuses.json +47 -0
  129. package/dist/carriers/ciblex/adapter.d.ts +17 -0
  130. package/dist/carriers/ciblex/adapter.js +46 -0
  131. package/dist/carriers/ciblex/carrier.json +71 -0
  132. package/dist/carriers/ciblex/numbers.json +63 -0
  133. package/dist/carriers/ciblex/parser.d.ts +4 -0
  134. package/dist/carriers/ciblex/parser.js +100 -0
  135. package/dist/carriers/ciblex/status.d.ts +24 -0
  136. package/dist/carriers/ciblex/status.js +55 -0
  137. package/dist/carriers/ciblex/statuses.json +221 -0
  138. package/dist/carriers/colis-prive/adapter.d.ts +39 -0
  139. package/dist/carriers/colis-prive/adapter.js +0 -0
  140. package/dist/carriers/colis-prive/carrier.json +72 -0
  141. package/dist/carriers/colis-prive/numbers.json +97 -0
  142. package/dist/carriers/colis-prive/status.d.ts +30 -0
  143. package/dist/carriers/colis-prive/status.js +85 -0
  144. package/dist/carriers/colis-prive/statuses.json +39 -0
  145. package/dist/carriers/colisweb/adapter.d.ts +29 -0
  146. package/dist/carriers/colisweb/adapter.js +166 -0
  147. package/dist/carriers/colisweb/carrier.json +63 -0
  148. package/dist/carriers/colisweb/numbers.json +39 -0
  149. package/dist/carriers/colisweb/status.d.ts +32 -0
  150. package/dist/carriers/colisweb/status.js +61 -0
  151. package/dist/carriers/colisweb/statuses.json +25 -0
  152. package/dist/carriers/correios-br/adapter.d.ts +16 -0
  153. package/dist/carriers/correios-br/adapter.js +78 -0
  154. package/dist/carriers/correios-br/carrier.json +64 -0
  155. package/dist/carriers/correios-br/model/LICENSE +21 -0
  156. package/dist/carriers/correios-br/model/captcha.onnx +0 -0
  157. package/dist/carriers/correios-br/numbers.json +72 -0
  158. package/dist/carriers/correios-br/ocr-worker.mjs +53 -0
  159. package/dist/carriers/correios-br/ocr.d.ts +10 -0
  160. package/dist/carriers/correios-br/ocr.js +83 -0
  161. package/dist/carriers/correios-br/parser.d.ts +4 -0
  162. package/dist/carriers/correios-br/parser.js +79 -0
  163. package/dist/carriers/correios-br/status.d.ts +2 -0
  164. package/dist/carriers/correios-br/status.js +17 -0
  165. package/dist/carriers/correios-br/statuses.json +16 -0
  166. package/dist/carriers/correos-chile/adapter.d.ts +12 -0
  167. package/dist/carriers/correos-chile/adapter.js +85 -0
  168. package/dist/carriers/correos-chile/carrier.json +62 -0
  169. package/dist/carriers/correos-chile/numbers.json +38 -0
  170. package/dist/carriers/correos-chile/parser.d.ts +9 -0
  171. package/dist/carriers/correos-chile/parser.js +120 -0
  172. package/dist/carriers/correos-chile/status.d.ts +3 -0
  173. package/dist/carriers/correos-chile/status.js +17 -0
  174. package/dist/carriers/correos-chile/statuses.json +12 -0
  175. package/dist/carriers/correos-express/adapter.d.ts +11 -0
  176. package/dist/carriers/correos-express/adapter.js +32 -0
  177. package/dist/carriers/correos-express/carrier.json +65 -0
  178. package/dist/carriers/correos-express/numbers.json +80 -0
  179. package/dist/carriers/correos-express/parser.d.ts +3 -0
  180. package/dist/carriers/correos-express/parser.js +97 -0
  181. package/dist/carriers/correos-express/status.d.ts +2 -0
  182. package/dist/carriers/correos-express/status.js +25 -0
  183. package/dist/carriers/correos-express/statuses.json +19 -0
  184. package/dist/carriers/correos-spain/adapter.d.ts +15 -0
  185. package/dist/carriers/correos-spain/adapter.js +191 -0
  186. package/dist/carriers/correos-spain/carrier.json +92 -0
  187. package/dist/carriers/correos-spain/numbers.json +149 -0
  188. package/dist/carriers/correos-spain/status.d.ts +17 -0
  189. package/dist/carriers/correos-spain/status.js +51 -0
  190. package/dist/carriers/correos-spain/statuses.json +46 -0
  191. package/dist/carriers/ctt/adapter.d.ts +34 -0
  192. package/dist/carriers/ctt/adapter.js +320 -0
  193. package/dist/carriers/ctt/carrier.json +72 -0
  194. package/dist/carriers/ctt/numbers.json +33 -0
  195. package/dist/carriers/ctt/status.d.ts +16 -0
  196. package/dist/carriers/ctt/status.js +16 -0
  197. package/dist/carriers/ctt/statuses.json +15 -0
  198. package/dist/carriers/ctt-express/adapter.d.ts +11 -0
  199. package/dist/carriers/ctt-express/adapter.js +41 -0
  200. package/dist/carriers/ctt-express/carrier.json +64 -0
  201. package/dist/carriers/ctt-express/numbers.json +59 -0
  202. package/dist/carriers/ctt-express/parser.d.ts +3 -0
  203. package/dist/carriers/ctt-express/parser.js +107 -0
  204. package/dist/carriers/ctt-express/status.d.ts +2 -0
  205. package/dist/carriers/ctt-express/status.js +17 -0
  206. package/dist/carriers/ctt-express/statuses.json +15 -0
  207. package/dist/carriers/dachser/adapter.d.ts +25 -0
  208. package/dist/carriers/dachser/adapter.js +168 -0
  209. package/dist/carriers/dachser/carrier.json +80 -0
  210. package/dist/carriers/dachser/numbers.json +66 -0
  211. package/dist/carriers/dachser/status.d.ts +40 -0
  212. package/dist/carriers/dachser/status.js +57 -0
  213. package/dist/carriers/dachser/statuses.json +18 -0
  214. package/dist/carriers/delhivery/adapter.d.ts +11 -0
  215. package/dist/carriers/delhivery/adapter.js +36 -0
  216. package/dist/carriers/delhivery/carrier.json +50 -0
  217. package/dist/carriers/delhivery/numbers.json +108 -0
  218. package/dist/carriers/delhivery/parser.d.ts +3 -0
  219. package/dist/carriers/delhivery/parser.js +81 -0
  220. package/dist/carriers/delhivery/status.d.ts +2 -0
  221. package/dist/carriers/delhivery/status.js +11 -0
  222. package/dist/carriers/delhivery/statuses.json +11 -0
  223. package/dist/carriers/delivengo/carrier.json +56 -0
  224. package/dist/carriers/delivengo/numbers.json +31 -0
  225. package/dist/carriers/delivengo/statuses.json +5 -0
  226. package/dist/carriers/dhl/adapter.d.ts +70 -0
  227. package/dist/carriers/dhl/adapter.js +308 -0
  228. package/dist/carriers/dhl/carrier.json +98 -0
  229. package/dist/carriers/dhl/numbers.json +153 -0
  230. package/dist/carriers/dhl/status.d.ts +14 -0
  231. package/dist/carriers/dhl/status.js +45 -0
  232. package/dist/carriers/dhl/statuses.json +27 -0
  233. package/dist/carriers/dhl-ecommerce/adapter.d.ts +50 -0
  234. package/dist/carriers/dhl-ecommerce/adapter.js +179 -0
  235. package/dist/carriers/dhl-ecommerce/carrier.json +97 -0
  236. package/dist/carriers/dhl-ecommerce/numbers.json +130 -0
  237. package/dist/carriers/dhl-ecommerce/status.d.ts +13 -0
  238. package/dist/carriers/dhl-ecommerce/status.js +57 -0
  239. package/dist/carriers/dhl-ecommerce/statuses.json +23 -0
  240. package/dist/carriers/dpd/adapter.d.ts +70 -0
  241. package/dist/carriers/dpd/adapter.js +809 -0
  242. package/dist/carriers/dpd/carrier.json +111 -0
  243. package/dist/carriers/dpd/numbers.json +43 -0
  244. package/dist/carriers/dpd/status.d.ts +39 -0
  245. package/dist/carriers/dpd/status.js +93 -0
  246. package/dist/carriers/dpd/statuses.json +144 -0
  247. package/dist/carriers/dpd-fr/adapter.d.ts +42 -0
  248. package/dist/carriers/dpd-fr/adapter.js +288 -0
  249. package/dist/carriers/dpd-fr/carrier.json +83 -0
  250. package/dist/carriers/dpd-fr/numbers.json +80 -0
  251. package/dist/carriers/dpd-fr/status.d.ts +21 -0
  252. package/dist/carriers/dpd-fr/status.js +93 -0
  253. package/dist/carriers/dpd-fr/statuses.json +325 -0
  254. package/dist/carriers/dtdc/adapter.d.ts +11 -0
  255. package/dist/carriers/dtdc/adapter.js +39 -0
  256. package/dist/carriers/dtdc/carrier.json +77 -0
  257. package/dist/carriers/dtdc/numbers.json +50 -0
  258. package/dist/carriers/dtdc/parser.d.ts +3 -0
  259. package/dist/carriers/dtdc/parser.js +90 -0
  260. package/dist/carriers/dtdc/status.d.ts +2 -0
  261. package/dist/carriers/dtdc/status.js +15 -0
  262. package/dist/carriers/dtdc/statuses.json +65 -0
  263. package/dist/carriers/ecoscooting/adapter.d.ts +11 -0
  264. package/dist/carriers/ecoscooting/adapter.js +42 -0
  265. package/dist/carriers/ecoscooting/carrier.json +76 -0
  266. package/dist/carriers/ecoscooting/numbers.json +291 -0
  267. package/dist/carriers/ecoscooting/parser.d.ts +3 -0
  268. package/dist/carriers/ecoscooting/parser.js +88 -0
  269. package/dist/carriers/ecoscooting/status.d.ts +2 -0
  270. package/dist/carriers/ecoscooting/status.js +50 -0
  271. package/dist/carriers/ecoscooting/statuses.json +295 -0
  272. package/dist/carriers/ems/adapter.d.ts +14 -0
  273. package/dist/carriers/ems/adapter.js +124 -0
  274. package/dist/carriers/ems/carrier.json +61 -0
  275. package/dist/carriers/ems/numbers.json +43 -0
  276. package/dist/carriers/ems/status.d.ts +2 -0
  277. package/dist/carriers/ems/status.js +24 -0
  278. package/dist/carriers/ems/statuses.json +128 -0
  279. package/dist/carriers/estafeta/adapter.d.ts +11 -0
  280. package/dist/carriers/estafeta/adapter.js +45 -0
  281. package/dist/carriers/estafeta/carrier.json +79 -0
  282. package/dist/carriers/estafeta/numbers.json +85 -0
  283. package/dist/carriers/estafeta/parser.d.ts +11 -0
  284. package/dist/carriers/estafeta/parser.js +123 -0
  285. package/dist/carriers/estafeta/status.d.ts +3 -0
  286. package/dist/carriers/estafeta/status.js +17 -0
  287. package/dist/carriers/estafeta/statuses.json +47 -0
  288. package/dist/carriers/evri/adapter.d.ts +14 -0
  289. package/dist/carriers/evri/adapter.js +146 -0
  290. package/dist/carriers/evri/carrier.json +69 -0
  291. package/dist/carriers/evri/numbers.json +32 -0
  292. package/dist/carriers/evri/status.d.ts +2 -0
  293. package/dist/carriers/evri/status.js +24 -0
  294. package/dist/carriers/evri/statuses.json +133 -0
  295. package/dist/carriers/fedex/adapter.d.ts +32 -0
  296. package/dist/carriers/fedex/adapter.js +307 -0
  297. package/dist/carriers/fedex/carrier.json +74 -0
  298. package/dist/carriers/fedex/numbers.json +198 -0
  299. package/dist/carriers/fedex/status.d.ts +33 -0
  300. package/dist/carriers/fedex/status.js +114 -0
  301. package/dist/carriers/fedex/statuses.json +34 -0
  302. package/dist/carriers/four-px/adapter.d.ts +12 -0
  303. package/dist/carriers/four-px/adapter.js +113 -0
  304. package/dist/carriers/four-px/carrier.json +60 -0
  305. package/dist/carriers/four-px/numbers.json +32 -0
  306. package/dist/carriers/four-px/status.d.ts +2 -0
  307. package/dist/carriers/four-px/status.js +22 -0
  308. package/dist/carriers/four-px/statuses.json +141 -0
  309. package/dist/carriers/geodis/adapter.d.ts +37 -0
  310. package/dist/carriers/geodis/adapter.js +275 -0
  311. package/dist/carriers/geodis/carrier.json +75 -0
  312. package/dist/carriers/geodis/numbers.json +45 -0
  313. package/dist/carriers/geodis/status.d.ts +37 -0
  314. package/dist/carriers/geodis/status.js +105 -0
  315. package/dist/carriers/geodis/statuses.json +51 -0
  316. package/dist/carriers/gls-ch/adapter.d.ts +39 -0
  317. package/dist/carriers/gls-ch/adapter.js +405 -0
  318. package/dist/carriers/gls-ch/carrier.json +122 -0
  319. package/dist/carriers/gls-ch/numbers.json +31 -0
  320. package/dist/carriers/gls-ch/status.d.ts +19 -0
  321. package/dist/carriers/gls-ch/status.js +79 -0
  322. package/dist/carriers/gls-ch/statuses.json +31 -0
  323. package/dist/carriers/gls-de/adapter.d.ts +28 -0
  324. package/dist/carriers/gls-de/adapter.js +113 -0
  325. package/dist/carriers/gls-de/carrier.json +126 -0
  326. package/dist/carriers/gls-de/numbers.json +111 -0
  327. package/dist/carriers/gls-de/status.d.ts +10 -0
  328. package/dist/carriers/gls-de/status.js +10 -0
  329. package/dist/carriers/gls-de/statuses.json +31 -0
  330. package/dist/carriers/gls-fr/adapter.d.ts +29 -0
  331. package/dist/carriers/gls-fr/adapter.js +220 -0
  332. package/dist/carriers/gls-fr/carrier.json +107 -0
  333. package/dist/carriers/gls-fr/numbers.json +113 -0
  334. package/dist/carriers/gls-fr/status.d.ts +28 -0
  335. package/dist/carriers/gls-fr/status.js +58 -0
  336. package/dist/carriers/gls-fr/statuses.json +34 -0
  337. package/dist/carriers/gofo/adapter.d.ts +11 -0
  338. package/dist/carriers/gofo/adapter.js +41 -0
  339. package/dist/carriers/gofo/carrier.json +80 -0
  340. package/dist/carriers/gofo/numbers.json +59 -0
  341. package/dist/carriers/gofo/parser.d.ts +5 -0
  342. package/dist/carriers/gofo/parser.js +131 -0
  343. package/dist/carriers/gofo/status.d.ts +2 -0
  344. package/dist/carriers/gofo/status.js +7 -0
  345. package/dist/carriers/gofo/statuses.json +54 -0
  346. package/dist/carriers/heppner/adapter.d.ts +27 -0
  347. package/dist/carriers/heppner/adapter.js +247 -0
  348. package/dist/carriers/heppner/carrier.json +74 -0
  349. package/dist/carriers/heppner/numbers.json +39 -0
  350. package/dist/carriers/heppner/status.d.ts +28 -0
  351. package/dist/carriers/heppner/status.js +43 -0
  352. package/dist/carriers/heppner/statuses.json +69 -0
  353. package/dist/carriers/hermes/adapter.d.ts +17 -0
  354. package/dist/carriers/hermes/adapter.js +103 -0
  355. package/dist/carriers/hermes/carrier.json +58 -0
  356. package/dist/carriers/hermes/numbers.json +20 -0
  357. package/dist/carriers/hermes/status.d.ts +15 -0
  358. package/dist/carriers/hermes/status.js +61 -0
  359. package/dist/carriers/hermes/statuses.json +31 -0
  360. package/dist/carriers/hermes-de/adapter.d.ts +22 -0
  361. package/dist/carriers/hermes-de/adapter.js +168 -0
  362. package/dist/carriers/hermes-de/carrier.json +90 -0
  363. package/dist/carriers/hermes-de/numbers.json +125 -0
  364. package/dist/carriers/hermes-de/status.d.ts +24 -0
  365. package/dist/carriers/hermes-de/status.js +52 -0
  366. package/dist/carriers/hermes-de/statuses.json +277 -0
  367. package/dist/carriers/hongkong-post/carrier.json +38 -0
  368. package/dist/carriers/hongkong-post/numbers.json +32 -0
  369. package/dist/carriers/india-post/adapter.d.ts +33 -0
  370. package/dist/carriers/india-post/adapter.js +415 -0
  371. package/dist/carriers/india-post/carrier.json +74 -0
  372. package/dist/carriers/india-post/numbers.json +58 -0
  373. package/dist/carriers/india-post/status.d.ts +23 -0
  374. package/dist/carriers/india-post/status.js +99 -0
  375. package/dist/carriers/india-post/statuses.json +18 -0
  376. package/dist/carriers/inpost/adapter.d.ts +14 -0
  377. package/dist/carriers/inpost/adapter.js +143 -0
  378. package/dist/carriers/inpost/carrier.json +75 -0
  379. package/dist/carriers/inpost/numbers.json +130 -0
  380. package/dist/carriers/inpost/status.d.ts +16 -0
  381. package/dist/carriers/inpost/status.js +31 -0
  382. package/dist/carriers/inpost/statuses.json +26 -0
  383. package/dist/carriers/intl-post/carrier.json +46 -0
  384. package/dist/carriers/intl-post/numbers.json +29 -0
  385. package/dist/carriers/j-and-t/carrier.json +66 -0
  386. package/dist/carriers/j-and-t/numbers.json +90 -0
  387. package/dist/carriers/japan-post/adapter.d.ts +13 -0
  388. package/dist/carriers/japan-post/adapter.js +159 -0
  389. package/dist/carriers/japan-post/carrier.json +71 -0
  390. package/dist/carriers/japan-post/numbers.json +35 -0
  391. package/dist/carriers/japan-post/status.d.ts +2 -0
  392. package/dist/carriers/japan-post/status.js +25 -0
  393. package/dist/carriers/japan-post/statuses.json +136 -0
  394. package/dist/carriers/jd-logistics/carrier.json +37 -0
  395. package/dist/carriers/jd-logistics/numbers.json +19 -0
  396. package/dist/carriers/korea-post/adapter.d.ts +12 -0
  397. package/dist/carriers/korea-post/adapter.js +101 -0
  398. package/dist/carriers/korea-post/carrier.json +74 -0
  399. package/dist/carriers/korea-post/numbers.json +54 -0
  400. package/dist/carriers/korea-post/status.d.ts +2 -0
  401. package/dist/carriers/korea-post/status.js +19 -0
  402. package/dist/carriers/korea-post/statuses.json +103 -0
  403. package/dist/carriers/la-poste/adapter.d.ts +29 -0
  404. package/dist/carriers/la-poste/adapter.js +241 -0
  405. package/dist/carriers/la-poste/carrier.json +87 -0
  406. package/dist/carriers/la-poste/numbers.json +140 -0
  407. package/dist/carriers/la-poste/status.d.ts +30 -0
  408. package/dist/carriers/la-poste/status.js +110 -0
  409. package/dist/carriers/la-poste/statuses.json +163 -0
  410. package/dist/carriers/landmark-global/adapter.d.ts +11 -0
  411. package/dist/carriers/landmark-global/adapter.js +30 -0
  412. package/dist/carriers/landmark-global/carrier.json +64 -0
  413. package/dist/carriers/landmark-global/numbers.json +58 -0
  414. package/dist/carriers/landmark-global/parser.d.ts +3 -0
  415. package/dist/carriers/landmark-global/parser.js +78 -0
  416. package/dist/carriers/landmark-global/status.d.ts +2 -0
  417. package/dist/carriers/landmark-global/status.js +13 -0
  418. package/dist/carriers/landmark-global/statuses.json +125 -0
  419. package/dist/carriers/mondial-relay/adapter.d.ts +32 -0
  420. package/dist/carriers/mondial-relay/adapter.js +352 -0
  421. package/dist/carriers/mondial-relay/carrier.json +94 -0
  422. package/dist/carriers/mondial-relay/numbers.json +130 -0
  423. package/dist/carriers/mondial-relay/status.d.ts +31 -0
  424. package/dist/carriers/mondial-relay/status.js +98 -0
  425. package/dist/carriers/mondial-relay/statuses.json +50 -0
  426. package/dist/carriers/mrw/adapter.d.ts +13 -0
  427. package/dist/carriers/mrw/adapter.js +131 -0
  428. package/dist/carriers/mrw/carrier.json +60 -0
  429. package/dist/carriers/mrw/numbers.json +116 -0
  430. package/dist/carriers/mrw/parser.d.ts +12 -0
  431. package/dist/carriers/mrw/parser.js +149 -0
  432. package/dist/carriers/mrw/status.d.ts +2 -0
  433. package/dist/carriers/mrw/status.js +14 -0
  434. package/dist/carriers/mrw/statuses.json +13 -0
  435. package/dist/carriers/nacex/adapter.d.ts +11 -0
  436. package/dist/carriers/nacex/adapter.js +99 -0
  437. package/dist/carriers/nacex/carrier.json +78 -0
  438. package/dist/carriers/nacex/numbers.json +47 -0
  439. package/dist/carriers/nacex/parser.d.ts +4 -0
  440. package/dist/carriers/nacex/parser.js +119 -0
  441. package/dist/carriers/nacex/status.d.ts +2 -0
  442. package/dist/carriers/nacex/status.js +12 -0
  443. package/dist/carriers/nacex/statuses.json +11 -0
  444. package/dist/carriers/ninja-van/adapter.d.ts +11 -0
  445. package/dist/carriers/ninja-van/adapter.js +45 -0
  446. package/dist/carriers/ninja-van/carrier.json +79 -0
  447. package/dist/carriers/ninja-van/numbers.json +67 -0
  448. package/dist/carriers/ninja-van/parser.d.ts +5 -0
  449. package/dist/carriers/ninja-van/parser.js +95 -0
  450. package/dist/carriers/ninja-van/status.d.ts +3 -0
  451. package/dist/carriers/ninja-van/status.js +25 -0
  452. package/dist/carriers/ninja-van/statuses.json +11 -0
  453. package/dist/carriers/nz-post/adapter.d.ts +11 -0
  454. package/dist/carriers/nz-post/adapter.js +45 -0
  455. package/dist/carriers/nz-post/carrier.json +82 -0
  456. package/dist/carriers/nz-post/numbers.json +49 -0
  457. package/dist/carriers/nz-post/parser.d.ts +3 -0
  458. package/dist/carriers/nz-post/parser.js +97 -0
  459. package/dist/carriers/nz-post/status.d.ts +2 -0
  460. package/dist/carriers/nz-post/status.js +29 -0
  461. package/dist/carriers/nz-post/statuses.json +68 -0
  462. package/dist/carriers/old-dominion/carrier.json +51 -0
  463. package/dist/carriers/old-dominion/numbers.json +83 -0
  464. package/dist/carriers/ontrac/adapter.d.ts +11 -0
  465. package/dist/carriers/ontrac/adapter.js +34 -0
  466. package/dist/carriers/ontrac/carrier.json +81 -0
  467. package/dist/carriers/ontrac/numbers.json +214 -0
  468. package/dist/carriers/ontrac/parser.d.ts +3 -0
  469. package/dist/carriers/ontrac/parser.js +72 -0
  470. package/dist/carriers/ontrac/status.d.ts +2 -0
  471. package/dist/carriers/ontrac/status.js +19 -0
  472. package/dist/carriers/ontrac/statuses.json +61 -0
  473. package/dist/carriers/paack/adapter.d.ts +19 -0
  474. package/dist/carriers/paack/adapter.js +255 -0
  475. package/dist/carriers/paack/carrier.json +79 -0
  476. package/dist/carriers/paack/numbers.json +106 -0
  477. package/dist/carriers/paack/status.d.ts +26 -0
  478. package/dist/carriers/paack/status.js +82 -0
  479. package/dist/carriers/paack/statuses.json +357 -0
  480. package/dist/carriers/packeta/adapter.d.ts +15 -0
  481. package/dist/carriers/packeta/adapter.js +166 -0
  482. package/dist/carriers/packeta/carrier.json +90 -0
  483. package/dist/carriers/packeta/numbers.json +71 -0
  484. package/dist/carriers/packeta/status.d.ts +23 -0
  485. package/dist/carriers/packeta/status.js +40 -0
  486. package/dist/carriers/packeta/statuses.json +21 -0
  487. package/dist/carriers/parcelforce/carrier.json +47 -0
  488. package/dist/carriers/parcelforce/numbers.json +32 -0
  489. package/dist/carriers/planzer/adapter.d.ts +40 -0
  490. package/dist/carriers/planzer/adapter.js +148 -0
  491. package/dist/carriers/planzer/carrier.json +85 -0
  492. package/dist/carriers/planzer/numbers.json +118 -0
  493. package/dist/carriers/planzer/shared.d.ts +19 -0
  494. package/dist/carriers/planzer/shared.js +135 -0
  495. package/dist/carriers/planzer/status.d.ts +33 -0
  496. package/dist/carriers/planzer/status.js +89 -0
  497. package/dist/carriers/planzer/statuses.json +229 -0
  498. package/dist/carriers/poczta-polska/adapter.d.ts +15 -0
  499. package/dist/carriers/poczta-polska/adapter.js +65 -0
  500. package/dist/carriers/poczta-polska/carrier.json +79 -0
  501. package/dist/carriers/poczta-polska/numbers.json +130 -0
  502. package/dist/carriers/poczta-polska/parser.d.ts +3 -0
  503. package/dist/carriers/poczta-polska/parser.js +96 -0
  504. package/dist/carriers/poczta-polska/status.d.ts +2 -0
  505. package/dist/carriers/poczta-polska/status.js +21 -0
  506. package/dist/carriers/poczta-polska/statuses.json +47 -0
  507. package/dist/carriers/pos-malaysia/adapter.d.ts +18 -0
  508. package/dist/carriers/pos-malaysia/adapter.js +199 -0
  509. package/dist/carriers/pos-malaysia/carrier.json +78 -0
  510. package/dist/carriers/pos-malaysia/numbers.json +73 -0
  511. package/dist/carriers/pos-malaysia/status.d.ts +17 -0
  512. package/dist/carriers/pos-malaysia/status.js +21 -0
  513. package/dist/carriers/pos-malaysia/statuses.json +17 -0
  514. package/dist/carriers/poste-italiane/adapter.d.ts +15 -0
  515. package/dist/carriers/poste-italiane/adapter.js +211 -0
  516. package/dist/carriers/poste-italiane/carrier.json +86 -0
  517. package/dist/carriers/poste-italiane/numbers.json +117 -0
  518. package/dist/carriers/poste-italiane/status.d.ts +19 -0
  519. package/dist/carriers/poste-italiane/status.js +44 -0
  520. package/dist/carriers/poste-italiane/statuses.json +22 -0
  521. package/dist/carriers/posti/adapter.d.ts +17 -0
  522. package/dist/carriers/posti/adapter.js +195 -0
  523. package/dist/carriers/posti/carrier.json +69 -0
  524. package/dist/carriers/posti/numbers.json +52 -0
  525. package/dist/carriers/posti/status.d.ts +4 -0
  526. package/dist/carriers/posti/status.js +41 -0
  527. package/dist/carriers/posti/statuses.json +18 -0
  528. package/dist/carriers/postlogistics/adapter.d.ts +39 -0
  529. package/dist/carriers/postlogistics/adapter.js +162 -0
  530. package/dist/carriers/postlogistics/carrier.json +67 -0
  531. package/dist/carriers/postlogistics/number.d.ts +2 -0
  532. package/dist/carriers/postlogistics/number.js +7 -0
  533. package/dist/carriers/postlogistics/numbers.json +54 -0
  534. package/dist/carriers/postlogistics/status.d.ts +20 -0
  535. package/dist/carriers/postlogistics/status.js +12 -0
  536. package/dist/carriers/postlogistics/statuses.json +40 -0
  537. package/dist/carriers/postnord/adapter.d.ts +11 -0
  538. package/dist/carriers/postnord/adapter.js +76 -0
  539. package/dist/carriers/postnord/carrier.json +82 -0
  540. package/dist/carriers/postnord/numbers.json +66 -0
  541. package/dist/carriers/postnord/parser.d.ts +3 -0
  542. package/dist/carriers/postnord/parser.js +75 -0
  543. package/dist/carriers/postnord/status.d.ts +3 -0
  544. package/dist/carriers/postnord/status.js +38 -0
  545. package/dist/carriers/postnord/statuses.json +16 -0
  546. package/dist/carriers/purolator/adapter.d.ts +11 -0
  547. package/dist/carriers/purolator/adapter.js +45 -0
  548. package/dist/carriers/purolator/carrier.json +75 -0
  549. package/dist/carriers/purolator/numbers.json +146 -0
  550. package/dist/carriers/purolator/parser.d.ts +3 -0
  551. package/dist/carriers/purolator/parser.js +79 -0
  552. package/dist/carriers/purolator/status.d.ts +2 -0
  553. package/dist/carriers/purolator/status.js +17 -0
  554. package/dist/carriers/purolator/statuses.json +15 -0
  555. package/dist/carriers/quickpac/carrier.json +68 -0
  556. package/dist/carriers/quickpac/numbers.json +31 -0
  557. package/dist/carriers/quickpac/statuses.json +213 -0
  558. package/dist/carriers/relais-colis/adapter.d.ts +28 -0
  559. package/dist/carriers/relais-colis/adapter.js +242 -0
  560. package/dist/carriers/relais-colis/carrier.json +77 -0
  561. package/dist/carriers/relais-colis/numbers.json +64 -0
  562. package/dist/carriers/relais-colis/status.d.ts +26 -0
  563. package/dist/carriers/relais-colis/status.js +91 -0
  564. package/dist/carriers/relais-colis/statuses.json +341 -0
  565. package/dist/carriers/royal-mail/adapter.d.ts +32 -0
  566. package/dist/carriers/royal-mail/adapter.js +260 -0
  567. package/dist/carriers/royal-mail/carrier.json +60 -0
  568. package/dist/carriers/royal-mail/numbers.json +57 -0
  569. package/dist/carriers/royal-mail/status.d.ts +19 -0
  570. package/dist/carriers/royal-mail/status.js +80 -0
  571. package/dist/carriers/royal-mail/statuses.json +16 -0
  572. package/dist/carriers/seur/adapter.d.ts +11 -0
  573. package/dist/carriers/seur/adapter.js +35 -0
  574. package/dist/carriers/seur/carrier.json +89 -0
  575. package/dist/carriers/seur/numbers.json +80 -0
  576. package/dist/carriers/seur/parser.d.ts +3 -0
  577. package/dist/carriers/seur/parser.js +78 -0
  578. package/dist/carriers/seur/status.d.ts +2 -0
  579. package/dist/carriers/seur/status.js +14 -0
  580. package/dist/carriers/seur/statuses.json +47 -0
  581. package/dist/carriers/sf-express/adapter.d.ts +17 -0
  582. package/dist/carriers/sf-express/adapter.js +87 -0
  583. package/dist/carriers/sf-express/carrier.json +78 -0
  584. package/dist/carriers/sf-express/numbers.json +66 -0
  585. package/dist/carriers/sf-express/parser.d.ts +4 -0
  586. package/dist/carriers/sf-express/parser.js +102 -0
  587. package/dist/carriers/sf-express/status.d.ts +4 -0
  588. package/dist/carriers/sf-express/status.js +28 -0
  589. package/dist/carriers/sf-express/statuses.json +334 -0
  590. package/dist/carriers/shipup/carrier.json +28 -0
  591. package/dist/carriers/shipup/numbers.json +20 -0
  592. package/dist/carriers/singapore-post/adapter.d.ts +12 -0
  593. package/dist/carriers/singapore-post/adapter.js +106 -0
  594. package/dist/carriers/singapore-post/carrier.json +62 -0
  595. package/dist/carriers/singapore-post/numbers.json +77 -0
  596. package/dist/carriers/singapore-post/status.d.ts +2 -0
  597. package/dist/carriers/singapore-post/status.js +17 -0
  598. package/dist/carriers/singapore-post/statuses.json +101 -0
  599. package/dist/carriers/spee-dee/carrier.json +51 -0
  600. package/dist/carriers/spee-dee/numbers.json +55 -0
  601. package/dist/carriers/speedx/carrier.json +49 -0
  602. package/dist/carriers/speedx/numbers.json +112 -0
  603. package/dist/carriers/spring-gds/adapter.d.ts +35 -0
  604. package/dist/carriers/spring-gds/adapter.js +212 -0
  605. package/dist/carriers/spring-gds/carrier.json +90 -0
  606. package/dist/carriers/spring-gds/numbers.json +224 -0
  607. package/dist/carriers/spring-gds/status.d.ts +19 -0
  608. package/dist/carriers/spring-gds/status.js +28 -0
  609. package/dist/carriers/spring-gds/statuses.json +140 -0
  610. package/dist/carriers/sto/carrier.json +37 -0
  611. package/dist/carriers/sto/numbers.json +33 -0
  612. package/dist/carriers/sunyou/adapter.d.ts +18 -0
  613. package/dist/carriers/sunyou/adapter.js +156 -0
  614. package/dist/carriers/sunyou/carrier.json +64 -0
  615. package/dist/carriers/sunyou/numbers.json +44 -0
  616. package/dist/carriers/sunyou/status.d.ts +17 -0
  617. package/dist/carriers/sunyou/status.js +13 -0
  618. package/dist/carriers/sunyou/statuses.json +53 -0
  619. package/dist/carriers/swiss-post/adapter.d.ts +18 -0
  620. package/dist/carriers/swiss-post/adapter.js +282 -0
  621. package/dist/carriers/swiss-post/carrier.json +84 -0
  622. package/dist/carriers/swiss-post/numbers.json +55 -0
  623. package/dist/carriers/swiss-post/status.d.ts +27 -0
  624. package/dist/carriers/swiss-post/status.js +64 -0
  625. package/dist/carriers/swiss-post/statuses.json +33 -0
  626. package/dist/carriers/swiss-post-cargo/adapter.d.ts +19 -0
  627. package/dist/carriers/swiss-post-cargo/adapter.js +173 -0
  628. package/dist/carriers/swiss-post-cargo/carrier.json +60 -0
  629. package/dist/carriers/swiss-post-cargo/numbers.json +23 -0
  630. package/dist/carriers/swiss-post-cargo/reference.d.ts +13 -0
  631. package/dist/carriers/swiss-post-cargo/reference.js +48 -0
  632. package/dist/carriers/swiss-post-cargo/status.d.ts +13 -0
  633. package/dist/carriers/swiss-post-cargo/status.js +53 -0
  634. package/dist/carriers/swiss-post-cargo/statuses.json +19 -0
  635. package/dist/carriers/thailand-post/carrier.json +38 -0
  636. package/dist/carriers/thailand-post/numbers.json +33 -0
  637. package/dist/carriers/the-courier-guy/adapter.d.ts +11 -0
  638. package/dist/carriers/the-courier-guy/adapter.js +49 -0
  639. package/dist/carriers/the-courier-guy/carrier.json +73 -0
  640. package/dist/carriers/the-courier-guy/number.d.ts +3 -0
  641. package/dist/carriers/the-courier-guy/number.js +18 -0
  642. package/dist/carriers/the-courier-guy/numbers.json +74 -0
  643. package/dist/carriers/the-courier-guy/parser.d.ts +3 -0
  644. package/dist/carriers/the-courier-guy/parser.js +104 -0
  645. package/dist/carriers/the-courier-guy/status.d.ts +5 -0
  646. package/dist/carriers/the-courier-guy/status.js +21 -0
  647. package/dist/carriers/the-courier-guy/statuses.json +61 -0
  648. package/dist/carriers/tipsa/adapter.d.ts +12 -0
  649. package/dist/carriers/tipsa/adapter.js +52 -0
  650. package/dist/carriers/tipsa/carrier.json +92 -0
  651. package/dist/carriers/tipsa/numbers.json +100 -0
  652. package/dist/carriers/tipsa/parser.d.ts +17 -0
  653. package/dist/carriers/tipsa/parser.js +114 -0
  654. package/dist/carriers/tipsa/status.d.ts +3 -0
  655. package/dist/carriers/tipsa/status.js +25 -0
  656. package/dist/carriers/tipsa/statuses.json +12 -0
  657. package/dist/carriers/tnt/adapter.d.ts +23 -0
  658. package/dist/carriers/tnt/adapter.js +210 -0
  659. package/dist/carriers/tnt/carrier.json +66 -0
  660. package/dist/carriers/tnt/numbers.json +116 -0
  661. package/dist/carriers/tnt/status.d.ts +3 -0
  662. package/dist/carriers/tnt/status.js +35 -0
  663. package/dist/carriers/tnt/statuses.json +126 -0
  664. package/dist/carriers/ukrposhta/adapter.d.ts +13 -0
  665. package/dist/carriers/ukrposhta/adapter.js +152 -0
  666. package/dist/carriers/ukrposhta/carrier.json +62 -0
  667. package/dist/carriers/ukrposhta/numbers.json +53 -0
  668. package/dist/carriers/ukrposhta/parser.d.ts +15 -0
  669. package/dist/carriers/ukrposhta/parser.js +130 -0
  670. package/dist/carriers/ukrposhta/status.d.ts +3 -0
  671. package/dist/carriers/ukrposhta/status.js +34 -0
  672. package/dist/carriers/ukrposhta/statuses.json +208 -0
  673. package/dist/carriers/uniuni/adapter.d.ts +11 -0
  674. package/dist/carriers/uniuni/adapter.js +48 -0
  675. package/dist/carriers/uniuni/carrier.json +90 -0
  676. package/dist/carriers/uniuni/numbers.json +72 -0
  677. package/dist/carriers/uniuni/parser.d.ts +5 -0
  678. package/dist/carriers/uniuni/parser.js +114 -0
  679. package/dist/carriers/uniuni/status.d.ts +2 -0
  680. package/dist/carriers/uniuni/status.js +16 -0
  681. package/dist/carriers/uniuni/statuses.json +54 -0
  682. package/dist/carriers/unknown/carrier.json +57 -0
  683. package/dist/carriers/unknown/numbers.json +257 -0
  684. package/dist/carriers/ups/adapter.d.ts +40 -0
  685. package/dist/carriers/ups/adapter.js +473 -0
  686. package/dist/carriers/ups/carrier.json +69 -0
  687. package/dist/carriers/ups/numbers.json +134 -0
  688. package/dist/carriers/ups/status.d.ts +25 -0
  689. package/dist/carriers/ups/status.js +41 -0
  690. package/dist/carriers/ups/statuses.json +35 -0
  691. package/dist/carriers/usps/adapter.d.ts +25 -0
  692. package/dist/carriers/usps/adapter.js +261 -0
  693. package/dist/carriers/usps/carrier.json +74 -0
  694. package/dist/carriers/usps/numbers.json +286 -0
  695. package/dist/carriers/usps/status.d.ts +25 -0
  696. package/dist/carriers/usps/status.js +72 -0
  697. package/dist/carriers/usps/statuses.json +24 -0
  698. package/dist/carriers/yamato/adapter.d.ts +13 -0
  699. package/dist/carriers/yamato/adapter.js +130 -0
  700. package/dist/carriers/yamato/carrier.json +72 -0
  701. package/dist/carriers/yamato/numbers.json +57 -0
  702. package/dist/carriers/yamato/status.d.ts +2 -0
  703. package/dist/carriers/yamato/status.js +27 -0
  704. package/dist/carriers/yamato/statuses.json +159 -0
  705. package/dist/carriers/yanwen/adapter.d.ts +13 -0
  706. package/dist/carriers/yanwen/adapter.js +130 -0
  707. package/dist/carriers/yanwen/carrier.json +66 -0
  708. package/dist/carriers/yanwen/numbers.json +45 -0
  709. package/dist/carriers/yanwen/status.d.ts +2 -0
  710. package/dist/carriers/yanwen/status.js +25 -0
  711. package/dist/carriers/yanwen/statuses.json +131 -0
  712. package/dist/carriers/yto/adapter.d.ts +11 -0
  713. package/dist/carriers/yto/adapter.js +36 -0
  714. package/dist/carriers/yto/carrier.json +75 -0
  715. package/dist/carriers/yto/numbers.json +33 -0
  716. package/dist/carriers/yto/parser.d.ts +3 -0
  717. package/dist/carriers/yto/parser.js +92 -0
  718. package/dist/carriers/yto/status.d.ts +10 -0
  719. package/dist/carriers/yto/status.js +46 -0
  720. package/dist/carriers/yto/statuses.json +206 -0
  721. package/dist/carriers/yunda/adapter.d.ts +11 -0
  722. package/dist/carriers/yunda/adapter.js +68 -0
  723. package/dist/carriers/yunda/carrier.json +69 -0
  724. package/dist/carriers/yunda/challenge.d.ts +5 -0
  725. package/dist/carriers/yunda/challenge.js +68 -0
  726. package/dist/carriers/yunda/numbers.json +43 -0
  727. package/dist/carriers/yunda/parser.d.ts +4 -0
  728. package/dist/carriers/yunda/parser.js +105 -0
  729. package/dist/carriers/yunda/status.d.ts +4 -0
  730. package/dist/carriers/yunda/status.js +9 -0
  731. package/dist/carriers/yunda/statuses.json +40 -0
  732. package/dist/carriers/yunexpress/adapter.d.ts +20 -0
  733. package/dist/carriers/yunexpress/adapter.js +240 -0
  734. package/dist/carriers/yunexpress/carrier.json +69 -0
  735. package/dist/carriers/yunexpress/numbers.json +32 -0
  736. package/dist/carriers/yunexpress/status.d.ts +2 -0
  737. package/dist/carriers/yunexpress/status.js +23 -0
  738. package/dist/carriers/yunexpress/statuses.json +112 -0
  739. package/dist/carriers/zto/carrier.json +37 -0
  740. package/dist/carriers/zto/numbers.json +30 -0
  741. package/dist/cli/index.d.ts +2 -0
  742. package/dist/cli/index.js +82 -0
  743. package/dist/core/adapter/index.d.ts +90 -0
  744. package/dist/core/adapter/index.js +103 -0
  745. package/dist/core/adapter/track.d.ts +10 -0
  746. package/dist/core/adapter/track.js +20 -0
  747. package/dist/core/catalog/amazon.d.ts +5 -0
  748. package/dist/core/catalog/amazon.js +33 -0
  749. package/dist/core/catalog/definitions.d.ts +24 -0
  750. package/dist/core/catalog/definitions.js +44 -0
  751. package/dist/core/catalog/handoff.d.ts +9 -0
  752. package/dist/core/catalog/handoff.js +56 -0
  753. package/dist/core/catalog/hints.d.ts +45 -0
  754. package/dist/core/catalog/hints.js +162 -0
  755. package/dist/core/catalog/index.d.ts +38 -0
  756. package/dist/core/catalog/index.js +223 -0
  757. package/dist/core/catalog/inputs.d.ts +6 -0
  758. package/dist/core/catalog/inputs.js +89 -0
  759. package/dist/core/catalog/linkRules.d.ts +24 -0
  760. package/dist/core/catalog/linkRules.js +20 -0
  761. package/dist/core/catalog/networks.d.ts +9 -0
  762. package/dist/core/catalog/networks.js +13 -0
  763. package/dist/core/catalog/recognition.d.ts +22 -0
  764. package/dist/core/catalog/recognition.js +52 -0
  765. package/dist/core/catalog/types.d.ts +135 -0
  766. package/dist/core/catalog/types.js +1 -0
  767. package/dist/core/catalog/urls.d.ts +2 -0
  768. package/dist/core/catalog/urls.js +125 -0
  769. package/dist/core/detection/amazon.d.ts +2 -0
  770. package/dist/core/detection/amazon.js +14 -0
  771. package/dist/core/detection/candidates.d.ts +5 -0
  772. package/dist/core/detection/candidates.js +41 -0
  773. package/dist/core/detection/detect.d.ts +17 -0
  774. package/dist/core/detection/detect.js +52 -0
  775. package/dist/core/detection/gls.d.ts +16 -0
  776. package/dist/core/detection/gls.js +21 -0
  777. package/dist/core/detection/hermes.d.ts +14 -0
  778. package/dist/core/detection/hermes.js +19 -0
  779. package/dist/core/detection/index.d.ts +19 -0
  780. package/dist/core/detection/index.js +9 -0
  781. package/dist/core/detection/mondialRelay.d.ts +13 -0
  782. package/dist/core/detection/mondialRelay.js +25 -0
  783. package/dist/core/detection/normalize.d.ts +15 -0
  784. package/dist/core/detection/normalize.js +39 -0
  785. package/dist/core/detection/parse.d.ts +6 -0
  786. package/dist/core/detection/parse.js +112 -0
  787. package/dist/core/detection/s10.d.ts +4 -0
  788. package/dist/core/detection/s10.js +25 -0
  789. package/dist/core/detection/types.d.ts +22 -0
  790. package/dist/core/detection/types.js +1 -0
  791. package/dist/core/errors/hint.d.ts +7 -0
  792. package/dist/core/errors/hint.js +7 -0
  793. package/dist/core/errors/index.d.ts +98 -0
  794. package/dist/core/errors/index.js +178 -0
  795. package/dist/core/recognition/index.d.ts +24 -0
  796. package/dist/core/recognition/index.js +65 -0
  797. package/dist/core/result/index.d.ts +57 -0
  798. package/dist/core/result/index.js +114 -0
  799. package/dist/core/result/resolve.d.ts +18 -0
  800. package/dist/core/result/resolve.js +49 -0
  801. package/dist/core/runner/index.d.ts +33 -0
  802. package/dist/core/runner/index.js +109 -0
  803. package/dist/core/status/index.d.ts +22 -0
  804. package/dist/core/status/index.js +3 -0
  805. package/dist/core/status/language.d.ts +11 -0
  806. package/dist/core/status/language.js +149 -0
  807. package/dist/core/status/wording.d.ts +25 -0
  808. package/dist/core/status/wording.js +91 -0
  809. package/dist/core/telemetry/index.d.ts +62 -0
  810. package/dist/core/telemetry/index.js +55 -0
  811. package/dist/core/time/index.d.ts +84 -0
  812. package/dist/core/time/index.js +243 -0
  813. package/dist/core/time/result.d.ts +5 -0
  814. package/dist/core/time/result.js +55 -0
  815. package/dist/core/transport/boundedFetch.d.ts +26 -0
  816. package/dist/core/transport/boundedFetch.js +152 -0
  817. package/dist/core/transport/browser.d.ts +14 -0
  818. package/dist/core/transport/browser.js +113 -0
  819. package/dist/core/transport/index.d.ts +8 -0
  820. package/dist/core/transport/index.js +5 -0
  821. package/dist/core/transport/optional.d.ts +2 -0
  822. package/dist/core/transport/optional.js +17 -0
  823. package/dist/core/transport/text.d.ts +8 -0
  824. package/dist/core/transport/text.js +18 -0
  825. package/dist/core/transport/trawl.d.ts +80 -0
  826. package/dist/core/transport/trawl.js +212 -0
  827. package/dist/core/transport/upstreamHttpDiagnostics.d.ts +16 -0
  828. package/dist/core/transport/upstreamHttpDiagnostics.js +97 -0
  829. package/dist/core/types.d.ts +8 -0
  830. package/dist/core/types.js +11 -0
  831. package/dist/data/catalog.json +3969 -0
  832. package/dist/facade/index.d.ts +57 -0
  833. package/dist/facade/index.js +195 -0
  834. package/dist/generated/catalog.d.ts +2671 -0
  835. package/dist/generated/catalog.js +4090 -0
  836. package/dist/generated/recognition.d.ts +2 -0
  837. package/dist/generated/recognition.js +31 -0
  838. package/dist/generated/regionTowns.d.ts +2 -0
  839. package/dist/generated/regionTowns.js +11 -0
  840. package/dist/generated/registry.d.ts +4 -0
  841. package/dist/generated/registry.js +286 -0
  842. package/dist/index.d.ts +19 -0
  843. package/dist/index.js +18 -0
  844. package/dist/node.d.ts +11 -0
  845. package/dist/node.js +11 -0
  846. package/dist/places/countries.json +1670 -0
  847. package/dist/places/facilities.json +11 -0
  848. package/dist/places/index.d.ts +42 -0
  849. package/dist/places/index.js +307 -0
  850. package/dist/places/names.d.mts +15 -0
  851. package/dist/places/names.mjs +36 -0
  852. package/dist/places/places.tsv.br +0 -0
  853. package/dist/places/trackingLocation.d.ts +18 -0
  854. package/dist/places/trackingLocation.js +89 -0
  855. package/dist/providers/coverage.d.ts +31 -0
  856. package/dist/providers/coverage.js +70 -0
  857. package/dist/providers/coverage.json +1744 -0
  858. package/dist/providers/parcelsapp/adapter.d.ts +23 -0
  859. package/dist/providers/parcelsapp/adapter.js +391 -0
  860. package/dist/providers/parcelsapp/http.d.ts +9 -0
  861. package/dist/providers/parcelsapp/http.js +67 -0
  862. package/dist/providers/plan.d.ts +38 -0
  863. package/dist/providers/plan.js +54 -0
  864. package/dist/providers/postal-ninja/adapter.d.ts +17 -0
  865. package/dist/providers/postal-ninja/adapter.js +200 -0
  866. package/dist/providers/seventeentrack/adapter.d.ts +50 -0
  867. package/dist/providers/seventeentrack/adapter.js +165 -0
  868. package/dist/providers/seventeentrack/events.d.ts +4 -0
  869. package/dist/providers/seventeentrack/events.js +56 -0
  870. package/dist/providers/shared/capture.d.ts +46 -0
  871. package/dist/providers/shared/capture.js +92 -0
  872. package/dist/providers/shared/hints.d.ts +16 -0
  873. package/dist/providers/shared/hints.js +37 -0
  874. package/dist/providers/shared/result.d.ts +15 -0
  875. package/dist/providers/shared/result.js +161 -0
  876. package/dist/providers/shared/scans.d.ts +22 -0
  877. package/dist/providers/shared/scans.js +29 -0
  878. package/dist/providers/ship24/adapter.d.ts +17 -0
  879. package/dist/providers/ship24/adapter.js +140 -0
  880. package/dist/providers/ship24/http.d.ts +7 -0
  881. package/dist/providers/ship24/http.js +75 -0
  882. package/dist/providers/types.d.ts +1 -0
  883. package/dist/providers/types.js +1 -0
  884. package/dist/providers/universal.d.ts +66 -0
  885. package/dist/providers/universal.js +95 -0
  886. package/dist/providers/upu/adapter.d.ts +5 -0
  887. package/dist/providers/upu/adapter.js +107 -0
  888. package/dist/scripts/canary-report.d.mts +22 -0
  889. package/dist/scripts/canary-report.mjs +69 -0
  890. package/dist/scripts/carrier-canary.d.ts +50 -0
  891. package/dist/scripts/carrier-canary.js +220 -0
  892. package/dist/server/index.d.ts +20 -0
  893. package/dist/server/index.js +226 -0
  894. package/dist/server/openapi.json +487 -0
  895. package/dist/server/page.d.ts +1 -0
  896. package/dist/server/page.js +33 -0
  897. package/package.json +102 -4
@@ -0,0 +1,809 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ import { randomBytes } from 'node:crypto';
3
+ import { load } from 'cheerio';
4
+ import { ChallengeError, IndeterminateError, NotFoundError, SchemaError, carrierErrorKind, } from '../../core/errors/index.js';
5
+ import { runSteps } from '../../core/runner/index.js';
6
+ import { isoTime, explicitOffsetTime, zonedTime } from '../../core/time/index.js';
7
+ import { TrawlClient, decodeText, fetchBounded, parseJsonBytes } from '../../core/transport/index.js';
8
+ import { isRecord } from '../../core/types.js';
9
+ import { API_LABELS, PROOF_OF_DELIVERY_SCAN, apiStage, apiStatus, scanStage, wordingStatus, } from './status.js';
10
+ // Protocol provenance:
11
+ // - The myDPD Android application talks to a guest JSON API: a Firebase
12
+ // installation identifies the app, Remote Config hands out the guest Basic
13
+ // credential, that credential buys a client-credentials access token, and the
14
+ // token reads `/v10/parcels/details/<number>`. Every value below is shipped
15
+ // publicly in the application; none of it is an account secret.
16
+ // - The delivery postcode is optional. With it, DPD unlocks verified scans and
17
+ // the delivery window; without it the lookup continues with
18
+ // `continueWithoutVerification=true`. A rejected postcode (HTTP 400) is
19
+ // retried once without verification and reported as unverified rather than
20
+ // failing the lookup.
21
+ // - The consignee web page is the fallback when the guest API is inconclusive.
22
+ // It sits behind Cloudflare, so it is fetched through the browser service's
23
+ // legacy command API when one is configured and directly otherwise.
24
+ const TRACKING_BASE = 'https://www.dpdgroup.com/ch/mydpd/my-parcels/incoming';
25
+ const FETCH_BASE = 'https://www.dpdgroup.com/ch/mydpd/my-parcels/track';
26
+ const API_BASE = 'https://www.dpdgroup.com/concept/webservice';
27
+ const OAUTH_URL = `${API_BASE}/oauth/token?grant_type=client_credentials`;
28
+ const DETAILS_BASE = `${API_BASE}/v10/parcels/details`;
29
+ const FIREBASE_PROJECT = 'consignee-portal';
30
+ const FIREBASE_PROJECT_NUMBER = '959401347543';
31
+ const FIREBASE_APP_ID = '1:959401347543:android:8d1a84133332291109e392';
32
+ // Public, app-restricted identifier shipped in the myDPD Android application.
33
+ const FIREBASE_API_KEY = 'AIzaSyDHMkUNUyUwFrQzKJhdC_J-L7QEwNUzwrc'; // gitleaks:allow
34
+ const ANDROID_PACKAGE = 'com.dpdgroup.chatbot.lemny.prod';
35
+ const ANDROID_CERT = '3872ACD98DE975F69C68CAF5119A5A1B2024B873';
36
+ const CLIENT_VERSION = '3.79.14';
37
+ const INSTALLATIONS_URL = `https://firebaseinstallations.googleapis.com/v1/projects/${FIREBASE_PROJECT}/installations`;
38
+ const REMOTE_CONFIG_URL = `https://firebaseremoteconfig.googleapis.com/v1/projects/${FIREBASE_PROJECT_NUMBER}/namespaces/firebase:fetch`;
39
+ const TIMEZONE = 'Europe/Zurich';
40
+ const DEFAULT_TIMEOUT_MS = 90_000;
41
+ /** How long a failed guest login answers new lookups before the next attempt. */
42
+ const TOKEN_FAILURE_MEMORY_MS = 30_000;
43
+ /** The browser service may spend the whole request timeout plus its own transport allowance. */
44
+ const SOLVER_ALLOWANCE_MS = 15_000;
45
+ const MAX_BYTES = 10_000_000;
46
+ /** Cloudflare interrupted the consignee page with an interactive challenge. */
47
+ export class DPDChallengeError extends ChallengeError {
48
+ constructor(message = 'DPD returned a Cloudflare browser challenge', options) {
49
+ super('DPD', message, options);
50
+ this.name = 'DPDChallengeError';
51
+ }
52
+ }
53
+ /**
54
+ * The guest API answered, but the answer proves nothing about the shipment
55
+ * (unreachable, malformed, unauthenticated, or an HTTP status the guest flow
56
+ * handles itself). The rendered page is allowed to recover from it.
57
+ */
58
+ export class DPDAPIError extends IndeterminateError {
59
+ constructor(message, options) {
60
+ super('DPD guest API', message, options);
61
+ this.name = 'DPDAPIError';
62
+ }
63
+ }
64
+ /** DPD positively reports that it does not know the parcel number. */
65
+ export class DPDTrackingError extends NotFoundError {
66
+ constructor(options) {
67
+ super('DPD', 'DPD could not locate the shipment', options);
68
+ this.name = 'DPDTrackingError';
69
+ }
70
+ }
71
+ class DPDAPIHttpError extends DPDAPIError {
72
+ constructor(status) {
73
+ super(`DPD guest API returned HTTP ${status}`, { status });
74
+ this.name = 'DPDAPIHttpError';
75
+ }
76
+ }
77
+ /** The parcel-details call itself refused the lookup (HTTP 400), not a token step. */
78
+ class DPDDetailsRefusedError extends DPDAPIHttpError {
79
+ constructor() {
80
+ super(400);
81
+ this.name = 'DPDDetailsRefusedError';
82
+ }
83
+ }
84
+ /**
85
+ * The rendered page recovers exactly what the guest API path used to hand it:
86
+ * an inconclusive answer, a transport failure, or a payload that did not match
87
+ * the request. A positive "unknown parcel" ends the lookup instead.
88
+ */
89
+ const PAGE_RECOVERS = new Set(['indeterminate', 'transport', 'schema']);
90
+ /**
91
+ * Local to this adapter: the guest API mixes strings and numbers in the fields
92
+ * we project, and its labels are not length-capped here (they are capped at the
93
+ * projection site instead), so `core/transport`'s string-only `clean` would
94
+ * change what a numeric city or code normalizes to. Anything else (objects,
95
+ * arrays, booleans) is empty: `String()` of an object is "[object Object]".
96
+ */
97
+ function clean(value) {
98
+ const text = textual(value);
99
+ return text === undefined ? '' : String(text).trim().split(/\s+/).filter(Boolean).join(' ');
100
+ }
101
+ /**
102
+ * The value when `clean` can read it, otherwise undefined, so a `??` chain
103
+ * passes over an object as it does over null. An empty string still stops the
104
+ * chain: stored events are keyed on what that chain produced.
105
+ */
106
+ function textual(value) {
107
+ return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))
108
+ ? value
109
+ : undefined;
110
+ }
111
+ /** What DPD writes where it has no value, e.g. `country: "UNDEFINED"` on customs scans. */
112
+ const PLACEHOLDERS = new Set(['UNDEFINED', 'UNKNOWN', 'NULL', 'NONE', 'N/A', '-']);
113
+ /** Provider text with DPD's placeholders read as empty. */
114
+ function known(value) {
115
+ const text = clean(value);
116
+ return PLACEHOLDERS.has(text.toUpperCase()) ? '' : text;
117
+ }
118
+ /** The first candidate that carries real text. */
119
+ function firstText(...candidates) {
120
+ for (const candidate of candidates) {
121
+ const text = known(candidate);
122
+ if (text)
123
+ return text;
124
+ }
125
+ return '';
126
+ }
127
+ function optionalText(value) {
128
+ return clean(value) || null;
129
+ }
130
+ /** A guest API code (`DEY`, `PARCEL_HANDED`) fit to travel as `provider_code`, or ''. */
131
+ function scanCode(value) {
132
+ const code = known(value).toUpperCase().replaceAll(' ', '_');
133
+ return /^[A-Z0-9_]{1,40}$/.test(code) ? code : '';
134
+ }
135
+ export function dpdTrackingUrl(trackingNumber, language) {
136
+ const url = new URL(TRACKING_BASE);
137
+ url.searchParams.set('parcelNumber', trackingNumber);
138
+ if (language)
139
+ url.searchParams.set('lang', language);
140
+ return url.toString();
141
+ }
142
+ /** Page timestamps are Swiss wall-clock without an offset; unparsable values stay raw. */
143
+ function eventTime(date, clock) {
144
+ const value = `${date} ${clock}`.trim();
145
+ const formats = clock
146
+ ? ['dd.MM.yyyy HH:mm:ss', 'dd.MM.yyyy HH:mm', 'dd.MM.yyyy']
147
+ : ['dd.MM.yyyy'];
148
+ for (const format of formats) {
149
+ const parsed = zonedTime(value, format, TIMEZONE);
150
+ if (parsed)
151
+ return parsed.iso;
152
+ }
153
+ return value;
154
+ }
155
+ function apiDescription(value) {
156
+ const key = clean(value).toUpperCase().replaceAll(' ', '_');
157
+ return API_LABELS[key] ?? key.toLocaleLowerCase('en-US')
158
+ .replaceAll('_', ' ')
159
+ .replace(/\b\w/g, (character) => character.toUpperCase());
160
+ }
161
+ function apiSender(payload, current) {
162
+ // Webshop sender only; recipient names stay out. A verified lookup sends
163
+ // `sender` as an object with a company, a name, an id and a postal address:
164
+ // only the company, then the name, is read. The `receiver` block never is.
165
+ const sender = isRecord(payload.sender) ? payload.sender : {};
166
+ const value = firstText(sender.companyName, sender.name, payload.senderName, payload.sender, current.senderName);
167
+ return value ? value.slice(0, 200) : null;
168
+ }
169
+ function apiPickupPoint(payload, current, stage) {
170
+ if (stage !== 'ready_for_pickup')
171
+ return null;
172
+ // ParcelShop collection points are operational locations, not private
173
+ // addresses. `receiverName` is the last fallback and is only read as text.
174
+ const value = firstText(...[current.pickupPoint, current.parcelShop, payload.pickupPoint, payload.parcelShop]
175
+ .map((candidate) => (isRecord(candidate) ? firstText(candidate.name, candidate.shopName) : candidate)), current.receiverName, payload.receiverName);
176
+ return value ? value.slice(0, 200) : null;
177
+ }
178
+ function apiLocation(event) {
179
+ const city = known(event.city);
180
+ // A scan's own `country` wins even when it is a placeholder: `depotCountry`
181
+ // names the business unit's depot on every scan, customs and paperwork scans
182
+ // included. It stays the last fallback for a scan that names no country at
183
+ // all, as it always was, so places stored from such scans keep their identity.
184
+ const country = known(textual(event.country) ?? textual(event.countryCode) ?? textual(event.depotCountry));
185
+ return city && country && city.toLocaleLowerCase('en-US') !== country.toLocaleLowerCase('en-US')
186
+ ? `${city}, ${country}`
187
+ : city || country;
188
+ }
189
+ /**
190
+ * A scan's `eventDateAndTimeZoneId` as a zone luxon reads. DPD sends "+02:00"
191
+ * and "Europe/Zurich"; "+0200", "UTC+2", "Z", "UTC" and "GMT" are accepted
192
+ * too. Anything else passes through, and an unreadable zone means Swiss time.
193
+ */
194
+ function scanZone(value) {
195
+ const text = clean(value);
196
+ if (/^(?:Z|UTC|GMT)$/i.test(text))
197
+ return 'UTC';
198
+ const offset = /^(?:UTC|GMT)?([+-])(\d{1,2}):?(\d{2})?$/i.exec(text);
199
+ if (!offset)
200
+ return text;
201
+ const [, sign, hours, minutes = '00'] = offset;
202
+ return Number(hours) <= 14 && Number(minutes) < 60 ? `UTC${sign}${hours.padStart(2, '0')}:${minutes}` : '';
203
+ }
204
+ /** How this adapter read a zone id before `scanZone`; stored events carry its spelling. */
205
+ function storedTime(value, zoneId) {
206
+ const zoneText = clean(zoneId);
207
+ const zone = /^[+-]\d{2}:\d{2}$/.test(zoneText) ? `UTC${zoneText}` : zoneText || TIMEZONE;
208
+ return isoTime(value, zone) ?? (zoneText ? isoTime(value, TIMEZONE) : null);
209
+ }
210
+ /**
211
+ * Guest API timestamps: an explicit offset wins, then the zone DPD names for
212
+ * that scan, then Swiss time. Unparsable values keep their raw text.
213
+ *
214
+ * The sync keys stored events on this exact string. When the instant is the
215
+ * one the adapter read before (with `storedZoneId`, Swiss time for
216
+ * `parcelEvents`), the earlier spelling is returned so no stored scan is
217
+ * duplicated.
218
+ */
219
+ function apiEventTime(date, clock = '', zoneId = null, storedZoneId = zoneId) {
220
+ const dateText = clean(date);
221
+ const clockText = clean(clock);
222
+ const value = clockText ? `${dateText}T${clockText}` : dateText;
223
+ if (!value)
224
+ return '';
225
+ const offsetParsed = explicitOffsetTime(value);
226
+ if (offsetParsed)
227
+ return offsetParsed.iso;
228
+ const zone = scanZone(zoneId);
229
+ const parsed = (zone ? isoTime(value, zone) : null) ?? isoTime(value, TIMEZONE);
230
+ const stored = storedTime(value, storedZoneId);
231
+ return (stored && stored.timestamp === parsed?.timestamp ? stored : parsed)?.iso
232
+ ?? clean(`${dateText} ${clockText}`);
233
+ }
234
+ /** The parcel weight in kilograms; absent, zero and implausible values are dropped. */
235
+ function apiWeight(value) {
236
+ const text = clean(value).replace(',', '.');
237
+ const weight = /^\d+(?:\.\d+)?$/.test(text) ? Number(text) : Number.NaN;
238
+ return Number.isFinite(weight) && weight > 0 && weight < 10_000 ? weight : null;
239
+ }
240
+ function expectedDelivery(payload) {
241
+ const rawDate = clean(payload.deliveryDate);
242
+ if (!rawDate)
243
+ return null;
244
+ const date = /^\d{4}-\d{2}-\d{2}/.exec(rawDate)?.[0] ?? rawDate;
245
+ const shortTime = (value) => /^(\d{2}:\d{2})/.exec(clean(value))?.[1] ?? '';
246
+ const from = shortTime(payload.deliveryTimeFrom);
247
+ const to = shortTime(payload.deliveryTimeTo);
248
+ if (from && to)
249
+ return `${date} ${from}–${to}`;
250
+ return from || to ? `${date} ${from || to}` : date;
251
+ }
252
+ /**
253
+ * Newest scan first. The guest API has listed a parcel's scans oldest first,
254
+ * and the summary and freshness watermark read the first event. Equal or
255
+ * unreadable times keep the payload's order.
256
+ */
257
+ function newestFirst(events) {
258
+ return events
259
+ .map((event, index) => ({ event, index, timestamp: Date.parse(event.time ?? '') || 0 }))
260
+ .sort((left, right) => right.timestamp - left.timestamp || left.index - right.index)
261
+ .map(({ event }) => event);
262
+ }
263
+ export function parseDPDTrackingApi(payload, trackingNumber, postcodeVerified) {
264
+ if (!isRecord(payload))
265
+ throw new DPDAPIError('DPD guest API returned an invalid response');
266
+ if (clean(payload.parcelNumber ?? payload.shipmentId) !== trackingNumber) {
267
+ throw new SchemaError('DPD', 'DPD did not return the requested parcel');
268
+ }
269
+ const history = Array.isArray(payload.parcelHistory) ? payload.parcelHistory.filter(isRecord) : [];
270
+ // A verified lookup lists each movement twice: in `parcelEvents` with its
271
+ // wording, place and scan code but a bare Swiss wall clock, and in
272
+ // `parcelHistory` with the enumeration and DPD's offset for that scan. A
273
+ // scan takes the offset of the history entry at the same wall clock, so the
274
+ // repeated autumn hour keeps its instant; without one it is read in Swiss time.
275
+ // Only a scan alone at its wall clock with a single entry there is paired
276
+ // and lent that entry's stage. Otherwise nothing says which entry is whose:
277
+ // the scans share an offset only when every entry there names the same zone.
278
+ const parcelEvents = Array.isArray(payload.parcelEvents) ? payload.parcelEvents.filter(isRecord) : [];
279
+ const scanWallClock = (raw) => `${clean(raw.date)}T${clean(raw.time)}`;
280
+ const entriesAt = new Map();
281
+ for (const raw of history) {
282
+ const wallClock = clean(raw.eventDateAndTime).slice(0, 19);
283
+ if (wallClock)
284
+ entriesAt.set(wallClock, [...(entriesAt.get(wallClock) ?? []), raw]);
285
+ }
286
+ const scansAt = new Map();
287
+ for (const raw of parcelEvents) {
288
+ const wallClock = scanWallClock(raw);
289
+ scansAt.set(wallClock, (scansAt.get(wallClock) ?? 0) + 1);
290
+ }
291
+ const scans = [];
292
+ const seen = new Set();
293
+ const append = (event) => {
294
+ const key = JSON.stringify([event.time ?? '', event.location ?? '', event.description ?? '']);
295
+ if (!seen.has(key)) {
296
+ seen.add(key);
297
+ scans.push(event);
298
+ }
299
+ };
300
+ // Only the fields below leave a scan. `podUrl` embeds the parcel number, and
301
+ // `pudoId`, `buShortName` and `depotCountry` are DPD's own routing data.
302
+ for (const raw of parcelEvents) {
303
+ const code = scanCode(raw.eventType);
304
+ const wallClock = scanWallClock(raw);
305
+ const entries = entriesAt.get(wallClock) ?? [];
306
+ const twin = entries.length === 1 && scansAt.get(wallClock) === 1 ? entries[0] : undefined;
307
+ const zoneId = new Set(entries.map((entry) => clean(entry.eventDateAndTimeZoneId))).size === 1
308
+ ? entries[0]?.eventDateAndTimeZoneId
309
+ : null;
310
+ const stage = scanStage(code) ?? apiStage(code) ?? (twin ? apiStage(twin.description) : null);
311
+ append({
312
+ time: apiEventTime(raw.date, raw.time, zoneId, null),
313
+ location: apiLocation(raw),
314
+ description: clean(textual(raw.translation) ?? textual(raw.eventTypeText) ?? apiDescription(raw.eventType))
315
+ || 'Tracking update',
316
+ ...(stage ? { stage } : {}),
317
+ ...(code ? { provider_code: code } : {}),
318
+ });
319
+ }
320
+ if (scans.length === 0) {
321
+ for (const raw of history) {
322
+ const code = scanCode(raw.description);
323
+ const stage = apiStage(code);
324
+ append({
325
+ time: apiEventTime(raw.eventDateAndTime, '', raw.eventDateAndTimeZoneId),
326
+ location: apiLocation(raw),
327
+ description: apiDescription(raw.description),
328
+ ...(stage ? { stage } : {}),
329
+ ...(code ? { provider_code: code } : {}),
330
+ });
331
+ }
332
+ }
333
+ const current = isRecord(payload.status) ? payload.status : {};
334
+ const currentDescription = current.description;
335
+ const stage = apiStage(currentDescription);
336
+ // The proof-of-delivery scan follows the delivery scan by minutes, with no
337
+ // place. Next to it the paperwork adds nothing, and as the newest event its
338
+ // wording, which no rule maps, would become the summary and the apps'
339
+ // current stage. Alone it proves the delivery only when the enumeration
340
+ // says delivered; otherwise (a return, say) it would hide the real state.
341
+ const deliveryScanned = scans.some((event) => (event.stage === 'delivered' && event.provider_code !== PROOF_OF_DELIVERY_SCAN));
342
+ const events = newestFirst(scans.flatMap((event) => {
343
+ if (event.provider_code !== PROOF_OF_DELIVERY_SCAN)
344
+ return [event];
345
+ return deliveryScanned || stage !== 'delivered' ? [] : [{ ...event, stage: 'delivered' }];
346
+ }));
347
+ const statusText = events[0]?.description || apiDescription(currentDescription)
348
+ || 'Tracking information received';
349
+ const status = apiStatus(currentDescription, statusText, events.length > 0);
350
+ const sender = apiSender(payload, current);
351
+ const pickupPoint = apiPickupPoint(payload, current, stage);
352
+ const weight = apiWeight(payload.weight);
353
+ const deliveredAt = status === 'delivered'
354
+ ? events.find((event) => event.stage === 'delivered')?.time
355
+ : undefined;
356
+ // Never projected: `receiver` (name, contact, address, geoPosition), the
357
+ // sender's id and address, `customerReference1/2`, `gttsZipCode`, `podUrl`
358
+ // and `product`, which holds the recipient's delivery preference.
359
+ const result = {
360
+ status,
361
+ ...(stage ? { current_stage: stage } : {}),
362
+ last_status_text: statusText,
363
+ last_update: events[0]?.time || apiEventTime(current.eventDateAndTime, '', current.eventDateAndTimeZoneId) || null,
364
+ expected_delivery: status === 'delivered' || status === 'exception' ? null : expectedDelivery(payload),
365
+ events,
366
+ source: 'mydpd_guest_api',
367
+ delivery_date: optionalText(payload.deliveryDate),
368
+ delivery_time_from: optionalText(payload.deliveryTimeFrom),
369
+ delivery_time_to: optionalText(payload.deliveryTimeTo),
370
+ is_predictive_date: Boolean(payload.isPredictiveDate),
371
+ ...(sender ? { sender_name: sender } : {}),
372
+ ...(pickupPoint ? { pickup_point: pickupPoint } : {}),
373
+ ...(weight !== null ? { weight_kg: weight } : {}),
374
+ ...(deliveredAt ? { delivered_at: deliveredAt } : {}),
375
+ };
376
+ if (postcodeVerified !== undefined)
377
+ result.dpd_postcode_verified = postcodeVerified;
378
+ return result;
379
+ }
380
+ export function parseDPDTrackingHtml(html, trackingNumber) {
381
+ if (/Just a moment|cf-mitigated|Enable JavaScript and cookies/i.test(html)) {
382
+ throw new DPDChallengeError();
383
+ }
384
+ const $ = load(html);
385
+ $('script, style').remove();
386
+ const visible = clean($('body').text());
387
+ if (!visible.includes(trackingNumber)) {
388
+ throw new SchemaError('DPD', 'DPD did not return the requested parcel');
389
+ }
390
+ if (/no parcel|not found|nicht gefunden|aucun colis/i.test(visible)) {
391
+ return {
392
+ status: 'unknown',
393
+ last_status_text: 'No parcel found',
394
+ last_update: null,
395
+ expected_delivery: null,
396
+ events: [],
397
+ };
398
+ }
399
+ const events = [];
400
+ $('li.content-item-track').each((_, element) => {
401
+ const row = $(element);
402
+ const description = clean(row.find('.entry-body').text());
403
+ if (!description)
404
+ return;
405
+ events.push({
406
+ time: eventTime(clean(row.find('.entry-date').text()), clean(row.find('.entry-time').text())),
407
+ location: clean(row.find('.place-track').text()),
408
+ description,
409
+ });
410
+ });
411
+ if (events.length === 0) {
412
+ const summary = [];
413
+ $('.parcelStatus .row').each((_, element) => {
414
+ const row = $(element);
415
+ const date = /\d{2}\.\d{2}\.\d{4}/.exec(clean(row.text()))?.[0] ?? '';
416
+ const description = clean(row.find('.col-xs-7').text())
417
+ || clean(row.text()).replace(date, '').trim();
418
+ if (date && description)
419
+ summary.push({ date, description });
420
+ });
421
+ const offsets = new Map();
422
+ for (const item of summary) {
423
+ const offset = offsets.get(item.date) ?? 0;
424
+ offsets.set(item.date, offset + 1);
425
+ events.push({
426
+ time: eventTime(item.date, `00:${String(Math.floor(offset / 60)).padStart(2, '0')}:${String(offset % 60).padStart(2, '0')}`),
427
+ location: '',
428
+ description: item.description,
429
+ });
430
+ }
431
+ events.reverse();
432
+ }
433
+ const labels = $('.gray-out').map((_, element) => clean($(element).text())).get().filter(Boolean);
434
+ const statusText = events[0]?.description ?? labels.at(-1) ?? 'Tracking information received';
435
+ return {
436
+ status: wordingStatus(statusText, events.length > 0),
437
+ last_status_text: statusText,
438
+ last_update: events[0]?.time || null,
439
+ expected_delivery: null,
440
+ events,
441
+ };
442
+ }
443
+ function durationSeconds(value, fallback) {
444
+ const match = /^(\d+)s?$/.exec(String(value ?? ''));
445
+ return match ? Number(match[1]) : fallback;
446
+ }
447
+ export class DPDTracker {
448
+ timeoutMs;
449
+ budgetMs;
450
+ flaresolverrUrl;
451
+ firebaseApiKey;
452
+ fetcher;
453
+ trawl;
454
+ recorder;
455
+ #accessToken = '';
456
+ #accessTokenExpiresAt = 0;
457
+ #basicToken = '';
458
+ #installationFid = '';
459
+ #installationToken = '';
460
+ #installationExpiresAt = 0;
461
+ #tokenRefresh = null;
462
+ #tokenFailure = null;
463
+ constructor(options = {}) {
464
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
465
+ this.budgetMs = options.budgetMs ?? this.timeoutMs * 2 + SOLVER_ALLOWANCE_MS;
466
+ this.flaresolverrUrl = (options.flaresolverrUrl ?? '').trim();
467
+ this.firebaseApiKey = (options.firebaseApiKey ?? FIREBASE_API_KEY).trim();
468
+ this.fetcher = options.fetcher;
469
+ this.trawl = options.trawl;
470
+ this.recorder = options.recorder;
471
+ }
472
+ /** The browser service, resolved late so a malformed URL fails the page step, not construction. */
473
+ browserService() {
474
+ if (this.trawl !== undefined)
475
+ return this.trawl;
476
+ return this.flaresolverrUrl ? new TrawlClient(this.flaresolverrUrl, this.fetcher) : null;
477
+ }
478
+ async fetch(trackingNumber, postcode = '') {
479
+ if (!/^\d{14}$/.test(trackingNumber)) {
480
+ throw new TypeError('DPD tracking numbers must contain 14 digits');
481
+ }
482
+ const resolvedPostcode = postcode.trim();
483
+ if (resolvedPostcode && !/^\d{4}$/.test(resolvedPostcode)) {
484
+ throw new TypeError('DPD postcode must contain exactly 4 digits');
485
+ }
486
+ const result = await runSteps({
487
+ carrier: 'dpd', budgetMs: this.budgetMs, recorder: this.recorder,
488
+ }, [
489
+ { id: 'direct', run: () => this.apiFetch(trackingNumber, resolvedPostcode) },
490
+ {
491
+ id: 'page',
492
+ recovers: (error) => {
493
+ const kind = carrierErrorKind(error);
494
+ return kind !== null && PAGE_RECOVERS.has(kind);
495
+ },
496
+ run: ({ previousError }) => this.pageFetch(trackingNumber, previousError !== undefined),
497
+ },
498
+ ]);
499
+ result.tracking_url = dpdTrackingUrl(trackingNumber);
500
+ return result;
501
+ }
502
+ /**
503
+ * Whether DPD knows a 14-digit number, for the host's carrier-detection
504
+ * route, which promotes the number to `dpd` only when this returns true.
505
+ * Guest API only, never the page tier. A positive not-found (404) and a
506
+ * details lookup DPD refuses without the postcode (400, seen for old
507
+ * parcels) are false; any other failure, a 400 from a token step included,
508
+ * stays a failure.
509
+ */
510
+ async recognizes(trackingNumber) {
511
+ if (!/^\d{14}$/.test(trackingNumber))
512
+ return false;
513
+ try {
514
+ const payload = await this.detailsWithFreshToken(trackingNumber);
515
+ return clean(payload.parcelNumber ?? payload.shipmentId) === trackingNumber;
516
+ }
517
+ catch (error) {
518
+ if (error instanceof DPDTrackingError)
519
+ return false;
520
+ if (error instanceof DPDDetailsRefusedError)
521
+ return false;
522
+ throw error;
523
+ }
524
+ }
525
+ async apiFetch(trackingNumber, postcode) {
526
+ let postcodeVerified;
527
+ let payload;
528
+ try {
529
+ payload = await this.detailsWithFreshToken(trackingNumber, postcode || undefined);
530
+ if (postcode)
531
+ postcodeVerified = true;
532
+ }
533
+ catch (error) {
534
+ if (!(error instanceof DPDAPIHttpError) || !postcode || error.status !== 400)
535
+ throw error;
536
+ payload = await this.detailsWithFreshToken(trackingNumber);
537
+ postcodeVerified = false;
538
+ }
539
+ return parseDPDTrackingApi(payload, trackingNumber, postcodeVerified);
540
+ }
541
+ async detailsWithFreshToken(trackingNumber, postcode) {
542
+ for (let attempt = 0; attempt < 2; attempt += 1) {
543
+ const token = await this.accessToken();
544
+ try {
545
+ return await this.parcelDetails(trackingNumber, postcode, token);
546
+ }
547
+ catch (error) {
548
+ if (!(error instanceof DPDAPIHttpError) || error.status !== 401 || attempt > 0)
549
+ throw error;
550
+ this.#accessToken = '';
551
+ this.#accessTokenExpiresAt = 0;
552
+ }
553
+ }
554
+ throw new DPDAPIError('DPD guest API authentication failed');
555
+ }
556
+ async parcelDetails(trackingNumber, postcode, token) {
557
+ const url = new URL(`${DETAILS_BASE}/${encodeURIComponent(trackingNumber)}`);
558
+ url.searchParams.set('parcelType', 'INCOMING');
559
+ url.searchParams.set('businessUnit', 'DPD-CH');
560
+ url.searchParams.set('lang', 'en');
561
+ url.searchParams.set('continueWithoutVerification', postcode ? 'false' : 'true');
562
+ if (postcode)
563
+ url.searchParams.set('dataForVerification', postcode);
564
+ try {
565
+ return await this.requestJson(url, '', {
566
+ Authorization: `Bearer ${token}`,
567
+ Accept: 'application/json',
568
+ 'Content-Type': 'application/json',
569
+ 'User-Agent': `myDPD/${CLIENT_VERSION} (Android)`,
570
+ }, true);
571
+ }
572
+ catch (error) {
573
+ if (error instanceof DPDAPIHttpError && error.status === 404) {
574
+ throw new DPDTrackingError();
575
+ }
576
+ if (error instanceof DPDAPIHttpError && error.status === 400)
577
+ throw new DPDDetailsRefusedError();
578
+ throw error;
579
+ }
580
+ }
581
+ async accessToken() {
582
+ if (this.#accessToken && Date.now() < this.#accessTokenExpiresAt)
583
+ return this.#accessToken;
584
+ // Concurrent lookups share one refresh and its outcome. A failed guest
585
+ // login is answered from memory for a short while, so a queue of lookups
586
+ // during an outage does not replay the whole token chain one by one.
587
+ if (this.#tokenRefresh)
588
+ return await this.#tokenRefresh;
589
+ if (this.#tokenFailure && Date.now() < this.#tokenFailure.until)
590
+ throw this.#tokenFailure.error;
591
+ this.#tokenRefresh = this.refreshAccessToken().then((token) => {
592
+ this.#tokenFailure = null;
593
+ return token;
594
+ }, (error) => {
595
+ this.#tokenFailure = { error, until: Date.now() + TOKEN_FAILURE_MEMORY_MS };
596
+ throw error;
597
+ }).finally(() => { this.#tokenRefresh = null; });
598
+ return await this.#tokenRefresh;
599
+ }
600
+ async refreshAccessToken() {
601
+ let payload = null;
602
+ for (let attempt = 0; attempt < 2; attempt += 1) {
603
+ const basicToken = this.#basicToken || await this.fetchBasicToken();
604
+ try {
605
+ payload = await this.requestJson(OAUTH_URL, '', {
606
+ Authorization: `Basic ${basicToken}`,
607
+ Accept: 'application/json',
608
+ 'Content-Type': 'application/json',
609
+ 'User-Agent': `myDPD/${CLIENT_VERSION} (Android)`,
610
+ });
611
+ break;
612
+ }
613
+ catch (error) {
614
+ if (!(error instanceof DPDAPIHttpError)
615
+ || ![400, 401].includes(error.status)
616
+ || attempt > 0)
617
+ throw error;
618
+ this.#basicToken = '';
619
+ }
620
+ }
621
+ const token = clean(payload?.access_token);
622
+ if (!token)
623
+ throw new DPDAPIError('DPD guest API did not issue an access token');
624
+ this.#accessToken = token;
625
+ this.#accessTokenExpiresAt = Date.now()
626
+ + Math.max(1, durationSeconds(payload?.expires_in, 3_600) - 60) * 1_000;
627
+ return token;
628
+ }
629
+ async fetchBasicToken() {
630
+ if (!this.firebaseApiKey)
631
+ throw new DPDAPIError('DPD Firebase client configuration is missing');
632
+ for (let attempt = 0; attempt < 2; attempt += 1) {
633
+ const [fid, installationToken] = await this.firebaseInstallation();
634
+ try {
635
+ const payload = await this.requestJson(REMOTE_CONFIG_URL, {
636
+ appId: FIREBASE_APP_ID,
637
+ appInstanceId: fid,
638
+ appInstanceIdToken: installationToken,
639
+ languageCode: 'en-US',
640
+ countryCode: 'CH',
641
+ platformVersion: '36',
642
+ appVersion: CLIENT_VERSION,
643
+ packageName: ANDROID_PACKAGE,
644
+ sdkVersion: '22.1.2',
645
+ analyticsUserProperties: {},
646
+ }, this.firebaseHeaders({ 'X-Goog-Firebase-Installations-Auth': installationToken }));
647
+ const entries = isRecord(payload.entries) ? payload.entries : {};
648
+ const token = clean(entries.basic_dpd_token);
649
+ if (!token)
650
+ throw new DPDAPIError('myDPD Remote Config omitted its guest credential');
651
+ this.#basicToken = token;
652
+ return token;
653
+ }
654
+ catch (error) {
655
+ if (!(error instanceof DPDAPIHttpError)
656
+ || ![401, 403].includes(error.status)
657
+ || attempt > 0)
658
+ throw error;
659
+ this.#installationFid = '';
660
+ this.#installationToken = '';
661
+ this.#installationExpiresAt = 0;
662
+ }
663
+ }
664
+ throw new DPDAPIError('myDPD Remote Config authentication failed');
665
+ }
666
+ async firebaseInstallation() {
667
+ if (this.#installationFid
668
+ && this.#installationToken
669
+ && Date.now() < this.#installationExpiresAt) {
670
+ return [this.#installationFid, this.#installationToken];
671
+ }
672
+ const bytes = randomBytes(17);
673
+ bytes[0] = 0x70 | (bytes[0] & 0x0f);
674
+ const fid = bytes.toString('base64url').slice(0, 22);
675
+ const payload = await this.requestJson(INSTALLATIONS_URL, {
676
+ fid,
677
+ appId: FIREBASE_APP_ID,
678
+ authVersion: 'FIS_v2',
679
+ sdkVersion: 'a:18.0.0',
680
+ }, this.firebaseHeaders());
681
+ const auth = isRecord(payload.authToken) ? payload.authToken : {};
682
+ const token = clean(auth.token);
683
+ if (!token)
684
+ throw new DPDAPIError('Firebase did not issue a myDPD installation token');
685
+ this.#installationFid = clean(payload.fid) || fid;
686
+ this.#installationToken = token;
687
+ this.#installationExpiresAt = Date.now()
688
+ + Math.max(1, durationSeconds(auth.expiresIn, 604_800) - 300) * 1_000;
689
+ return [this.#installationFid, token];
690
+ }
691
+ firebaseHeaders(extra = {}) {
692
+ return {
693
+ Accept: 'application/json',
694
+ 'Content-Type': 'application/json',
695
+ 'X-Goog-Api-Key': this.firebaseApiKey,
696
+ 'X-Android-Package': ANDROID_PACKAGE,
697
+ 'X-Android-Cert': ANDROID_CERT,
698
+ ...extra,
699
+ };
700
+ }
701
+ async requestJson(url, data, headers, retryRead = false) {
702
+ const deadline = performance.now() + this.timeoutMs;
703
+ let result;
704
+ try {
705
+ for (let attempt = 0;; attempt++) {
706
+ result = await fetchBounded(url, {
707
+ method: 'POST',
708
+ headers,
709
+ body: typeof data === 'string' ? data : JSON.stringify(data),
710
+ }, {
711
+ provider: 'DPD guest API',
712
+ timeoutMs: Math.max(1, Math.floor(deadline - performance.now())),
713
+ maxBytes: MAX_BYTES,
714
+ allowHttpError: true,
715
+ fetcher: this.fetcher,
716
+ });
717
+ // Only the read-only parcel-details POST is replayed; auth requests are not.
718
+ const pause = 1_000 + Math.floor(Math.random() * 2_000);
719
+ const retryAfter = result.response.headers.get('retry-after');
720
+ if (!retryRead || attempt > 0 || ![502, 503, 504].includes(result.response.status)
721
+ || retryAfter !== null || deadline - performance.now() < pause + 1_000)
722
+ break;
723
+ await delay(pause);
724
+ }
725
+ }
726
+ catch (error) {
727
+ throw new DPDAPIError('DPD guest API is unreachable', { cause: error });
728
+ }
729
+ if (!result.response.ok)
730
+ throw new DPDAPIHttpError(result.response.status);
731
+ let payload;
732
+ try {
733
+ payload = parseJsonBytes(result.bytes, 'DPD guest API');
734
+ }
735
+ catch (error) {
736
+ throw new DPDAPIError('DPD guest API returned invalid JSON', { cause: error });
737
+ }
738
+ if (!isRecord(payload))
739
+ throw new DPDAPIError('DPD guest API returned an invalid response');
740
+ return payload;
741
+ }
742
+ async pageFetch(trackingNumber, apiFailed) {
743
+ const url = new URL(FETCH_BASE);
744
+ url.searchParams.set('lang', 'en');
745
+ url.searchParams.set('parcelNumber', trackingNumber);
746
+ const trawl = this.browserService();
747
+ let html;
748
+ if (trawl) {
749
+ html = await trawl.solve(url.toString(), {
750
+ provider: 'The browser challenge solver',
751
+ timeoutMs: this.timeoutMs,
752
+ maxBytes: MAX_BYTES,
753
+ fetcher: this.fetcher,
754
+ });
755
+ }
756
+ else {
757
+ try {
758
+ html = await this.directGet(url);
759
+ }
760
+ catch (error) {
761
+ if (!(error instanceof DPDChallengeError))
762
+ throw error;
763
+ const prefix = apiFailed ? 'DPD guest API is unavailable and ' : 'DPD ';
764
+ throw new DPDChallengeError(`${prefix}the web fallback requires a browser challenge solver; configure FLARESOLVERR_URL`, { cause: error });
765
+ }
766
+ }
767
+ return parseDPDTrackingHtml(html, trackingNumber);
768
+ }
769
+ async directGet(url) {
770
+ const result = await fetchBounded(url, {
771
+ headers: {
772
+ Accept: 'text/html,application/xhtml+xml',
773
+ 'Accept-Language': 'en-CH,en;q=0.9',
774
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/140 Safari/537.36',
775
+ },
776
+ }, {
777
+ provider: 'DPD',
778
+ timeoutMs: this.timeoutMs,
779
+ maxBytes: MAX_BYTES,
780
+ redirect: 'follow',
781
+ allowHttpError: true,
782
+ fetcher: this.fetcher,
783
+ });
784
+ const html = decodeText(result.bytes);
785
+ if (result.response.status === 403
786
+ && (result.response.headers.get('cf-mitigated') === 'challenge'
787
+ || /Just a moment|Enable JavaScript and cookies/i.test(html))) {
788
+ throw new DPDChallengeError();
789
+ }
790
+ if (!result.response.ok)
791
+ throw new IndeterminateError('DPD', `DPD returned HTTP ${result.response.status}`);
792
+ return html;
793
+ }
794
+ }
795
+ export const adapter = (environment) => {
796
+ const tracker = new DPDTracker({
797
+ fetcher: environment.fetcher,
798
+ trawl: environment.trawl,
799
+ recorder: environment.recorder,
800
+ });
801
+ return {
802
+ id: 'dpd',
803
+ // The guest JSON protocol first; the Cloudflare-protected consignee page,
804
+ // solved by the browser service when one is configured, second.
805
+ steps: ['direct', 'page'],
806
+ track: (input) => tracker.fetch(input.number, input.postcode ?? ''),
807
+ recognize: async (number) => ({ known: await tracker.recognizes(number) }),
808
+ };
809
+ };