universal-parcel-scraper 0.596.1-main.2797 → 0.598.0-main.2802
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/README.md +1 -1
- package/data/catalog.json +2 -2
- package/data/detection-golden.json +8 -0
- package/dist/browser/scraper.js +5 -5
- package/dist/carriers/chunghwa-post/carrier.json +1 -1
- package/dist/carriers/chunghwa-post/numbers.json +12 -0
- package/dist/carriers/gzyl/parser.js +1 -3
- package/dist/carriers/gzyl/status.d.ts +1 -0
- package/dist/carriers/gzyl/status.js +5 -2
- package/dist/carriers/gzyl/statuses.json +1 -0
- package/dist/carriers/huahan/status.js +8 -4
- package/dist/carriers/huahan/statuses.json +10 -1
- package/dist/carriers/intl-post/carrier.json +1 -1
- package/dist/carriers/royal-mail/parser.js +4 -4
- package/dist/carriers/royal-mail/statuses.json +1 -1
- package/dist/core/status/language.js +3 -3
- package/dist/data/catalog.json +2 -2
- package/dist/generated/catalog.d.ts +2 -2
- package/dist/generated/catalog.js +2 -2
- package/dist/server/openapi.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -155,7 +155,7 @@ createTracker({ providers: ['ParcelsApp', 'Ship24', '17TRACK', 'Postal Ninja', '
|
|
|
155
155
|
<!-- GENERATED:stages -->
|
|
156
156
|
<img src="docs/assets/stages.svg" alt="DHL: Die Sendung wurde in das Zustellfahrzeug geladen.; Mondial Relay: En cours de livraison; Correios Brazil: Objeto saiu para entrega ao destinatário; Correos Express: EN REPARTO; Yamato Transport: 配達中; La Poste / Colissimo: DISTOU. All are filed under out_for_delivery." width="760">
|
|
157
157
|
|
|
158
|
-
The carrier folders record 16,
|
|
158
|
+
The carrier folders record 16,236 such statuses, each filed under one stage.
|
|
159
159
|
<!-- /GENERATED:stages -->
|
|
160
160
|
|
|
161
161
|
Wording nobody recorded yet goes through a classifier that reads seven European languages.
|
package/data/catalog.json
CHANGED
|
@@ -2023,7 +2023,7 @@
|
|
|
2023
2023
|
"linkRules": [],
|
|
2024
2024
|
"detectionRules": [
|
|
2025
2025
|
{
|
|
2026
|
-
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2026
|
+
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2027
2027
|
"confidence": "high",
|
|
2028
2028
|
"checksum": "s10"
|
|
2029
2029
|
}
|
|
@@ -8982,7 +8982,7 @@
|
|
|
8982
8982
|
],
|
|
8983
8983
|
"detectionRules": [
|
|
8984
8984
|
{
|
|
8985
|
-
"pattern": "^[CELR][A-Z]\\d{9}TW$",
|
|
8985
|
+
"pattern": "^(?:[CELR][A-Z]|UH)\\d{9}TW$",
|
|
8986
8986
|
"confidence": "high",
|
|
8987
8987
|
"checksum": "s10"
|
|
8988
8988
|
}
|
|
@@ -88896,6 +88896,14 @@
|
|
|
88896
88896
|
"ues-uy"
|
|
88897
88897
|
]
|
|
88898
88898
|
},
|
|
88899
|
+
{
|
|
88900
|
+
"input": "UH000000005TW",
|
|
88901
|
+
"carrier": "chunghwa-post",
|
|
88902
|
+
"confidence": "high",
|
|
88903
|
+
"candidates": [
|
|
88904
|
+
"chunghwa-post"
|
|
88905
|
+
]
|
|
88906
|
+
},
|
|
88899
88907
|
{
|
|
88900
88908
|
"input": "UH015319935DO",
|
|
88901
88909
|
"carrier": "intl-post",
|
package/dist/browser/scraper.js
CHANGED
|
@@ -1894,7 +1894,7 @@ var Ye = {
|
|
|
1894
1894
|
trackingSiteName: "17TRACK",
|
|
1895
1895
|
linkRules: [],
|
|
1896
1896
|
detectionRules: [{
|
|
1897
|
-
pattern: "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
1897
|
+
pattern: "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
1898
1898
|
confidence: "high",
|
|
1899
1899
|
checksum: "s10"
|
|
1900
1900
|
}]
|
|
@@ -7150,7 +7150,7 @@ var Ye = {
|
|
|
7150
7150
|
params: ["MAILNO"]
|
|
7151
7151
|
}],
|
|
7152
7152
|
detectionRules: [{
|
|
7153
|
-
pattern: "^[CELR][A-Z]\\d{9}TW$",
|
|
7153
|
+
pattern: "^(?:[CELR][A-Z]|UH)\\d{9}TW$",
|
|
7154
7154
|
confidence: "high",
|
|
7155
7155
|
checksum: "s10"
|
|
7156
7156
|
}]
|
|
@@ -29479,7 +29479,7 @@ function Hc(e) {
|
|
|
29479
29479
|
if (/will (?:shortly |soon )?be handed|bientot.*(?:confie|remis)|prochainement.*remis|wird.*(?:kurze|bald).*ubergeben|sara.*(?:breve|presto).*affidat/.test(t) || /\bpendiente de (?:entregar|entrega|recepcion|admision|recibir) (?:a|al|en|por) (?:la |el )?(?:agencia|transportista|operador|correos|seur|mrw|nacex|tipsa|ctt|gls|dhl|dpd|ups|fedex|envialia|zeleris|paack|inpost|celeritas)\b|\bpendiente de (?:recepcion|admision)\b|\baguarda entrada\b|\bpendente de (?:rececao|recepcao|entrada)\b/.test(t) || /or awaiting processing|ou en attente de traitement|oder wartet auf.*bearbeitung|o in attesa di elaborazione/.test(t)) return "registered";
|
|
29480
29480
|
if (/will be transported|\barrange (?:a )?(?:truck|train|rail|road) transfer\b|sera (?:transporte|achemine)|wird.*transportiert|sara trasportat/.test(t) || /will be available|sera disponible|(?:sera|va etre|doit etre) (?:distribue|remis|mis en (?:livraison|distribution))|wird.*verfugbar|sara disponibile|to be delivered|a livrer|noch zuzustellen|da consegnare|(?:once|when|as soon as) (?:the |your )?(?:shipment|parcel|package|item) is out for delivery/.test(t) || /\bestara disponi(?:ble|vel)\b|\bpor entregar\b|\bpendiente de (?:entrega|entregar|reparto)\b|\bpendente de entrega\b|\b(?:aguarda|aguardando|a aguardar) (?:a )?entrega\b|\bsera (?:enviad|transportad|expedid|encaminhad)[oa]s?\b/.test(t)) return "in_transit";
|
|
29481
29481
|
if (/ready for (?:pick ?up|collection)|ready to collect|ready to be (?:picked up|collected)\b(?! (?:by|from) (?:the |a |an |our |your )?(?:courier|carrier|driver|sender|shipper|seller|merchant|warehouse)\b)|available for (?:pick ?up|collection)|(?<!\bnot (?:yet )?)\bavailable (?:at|in|from) (?:the |a |an |your |our )?(?:[\w-]+ )?(?:retrieval point|pick ?up (?:point|location|station)|parcel ?shop|service point|access point|collection point|relay point|parcel locker)\b|awaiting (?:customer |recipient |your )?(?:pick ?up|collection)\b(?! (?:by|from) (?:the |a |an |our |your )?(?:local |destination |last[- ]mile )?(?:courier|carrier|driver|sender|shipper|seller|merchant|warehouse)\b)|pret.*(?:retrait|retire)|disponible.*(?:retrait|collecte)|vous attend (?:au|en|dans|chez|a)\b|mise? a disposition (?:au|en|dans|a)\b.*(?:point (?:de )?retrait|relais|consigne|locker|bureau de poste|agence)|jours? restants? pour (?:le )?retirer|abholbereit|zur abholung bereit|pront[oa] per il ritiro|disponibile per il ritiro|(?:deposited|depose|hinterlegt|depositat[oa]).*mypost24/.test(t) || /(?<!\b(?:no|nao|ya no|ja nao) (?:(?:esta|estara|se encuentra|se encontra|e|era|foi) )?)\bdisponi(?:ble|vel) (?:para (?:su |ser )?(?:recoger|recogida|recogid[oa]|retirar|retiro|retirada|retirad[oa]|levantamento|levantar|levantad[oa]|recolha|recolher)|(?:en|no|na|num|numa|em) (?:el |la |un |una |su |tu |nuestr[oa] )?(?:punto|oficina|tienda|locker|taquilla|consigna|citypaq|parcel ?shop|buzon inteligente|agencia|delegacion|sucursal|ponto|loja|cacifo|estacao|balcao|payshop|posto|unidade))\b|\blist[oa] para (?:su |ser )?(?:recoger|recogida|recogid[oa]|retirar|retiro)\b|\bpront[oa] (?:para|a) (?:ser )?(?:levantamento|levantar|levantad[oa]|recolha|recolher|retirada|retirar)\b|\b(?:ya )?(?:puede|puedes|podra|podras) (?:pasar a )?recoger(?:lo|la)?\b|\b(?:aguarda|aguardando|a aguardar) (?:o |a )?(?:levantamento|retirada)\b|\besperando (?:su|tu) recogida\b|\b(?:pendiente de|esperando|a la espera de) (?:ser )?recogid[oa] por (?:el |la )?destinatari[oa]\b/.test(t)) return "ready_for_pickup";
|
|
29482
|
-
if (/label (?:created|printed)|(?:created|generated) a (?:new )?(?:shipment |shipping )?label|etiquette.*(?:cree|imprime)|cree une etiquette|versandetikett.*(?:erstellt|gedruckt)|etikett erstellt|etichetta.*(?:creata|stampata)|creato un'etichetta|elektronisch|electroni(?:c|que|sch)|elettronic|pre.?advi[cs]|preannunciat|vorangemeldet|preannonce|data.*entered|donnees.*saisies|daten.*erfasst|dati.*inseriti|\bpre ?(?:registered|registration|registr?ad[oa]s?|registrat[oa]|enregistree?s?)\b|\bprerregistr(?:ad[oa]s?|o)\b|\bvorregistriert\b|\bwstepnie zarejestrowan[aey]\b/.test(t) || /\border (?:details|information|info|data) (?:(?:has|have) been |was |were )?(?:received|submitted|transmitted)\b|\breceived (?:your |the )?order (?:details|information|data)\b|\b(?:details|informations|donnees) de (?:la |votre )?commande (?:ont ete )?(?:recu|transmis)e?s?\b|\b(?:auftrags|bestell)daten (?:wurden |sind )?(?:erhalten|ubermittelt|eingegangen)\b|\b(?:dati|dettagli) (?:dell'ordine|ordine) (?:sono stati )?ricevuti\b|\b(?:datos|detalles|informacion) del pedido (?:han sido |fueron )?recibid[oa]s?\b|\b(?:dados|detalhes|informacoes?) d[oa] (?:pedido|encomenda) (?:foram )?recebid[oa]s?\b|\bdane zamowienia (?:zostaly )?(?:otrzymane|przyjete)\b|\botrzymano dane zamowienia\b/.test(t) || /shipment information (?:received|sent to)|\bdata received\b|(?:package|parcel|shipment) data (?:was |has been )?sent to|\bpre ?notification\b|informations d'expedition recues|sendungsinformationen erhalten|informazioni.*spedizione ricevute|(?:consignment|shipment|parcel|package) recorded by|envoi enregistre par|sendung.*absender.*erfasst|spedizione registrata dal/.test(t) || /\b(?:we're|we are) expecting (?:your|the) (?:parcel|package|item|shipment) to arrive with us\b/.test(t) || /preparation chez.*expediteur|preparation.*expediteur|preparazione.*mittente|being prepared.*sender|(?:shipper|sender)(?: that)? (?:they are|is|are) preparing|beim absender.*vorbereitet|warehouse of the sender|shippers warehouse|entrepot de l'expediteur|lager des absenders|magazzino del mittente|demande d'envoi.*prise en compte|collection request.*(?:received|recorded)|abholauftrag.*erfasst|richiesta.*ritiro.*registrata/.test(t) || /\border submitted(?:,| and)? pending (?:to )?rece(?:iv|ipt)|\bshipment data uploaded\b|^sender preparing item\b|^shipping info(?:rmation)? sent to (?!(?:the |your? )?(?:recipient|customer|consignee|addressee|buyer)\b)|\bwe have received your shipment information\b|\bhemos recibido la informacion de su envio\b|\bwe will pick up the (?:package|parcel) from the sender\b|\bpending shipping by (?:the )?(?:seller|sender|shipper|merchant)\b|\bshipment order created\b/.test(t)) return "registered";
|
|
29482
|
+
if (/label (?:created|printed)|(?:created|generated) a (?:new )?(?:shipment |shipping )?label|etiquette.*(?:cree|imprime)|cree une etiquette|versandetikett.*(?:erstellt|gedruckt)|etikett erstellt|etichetta.*(?:creata|stampata)|creato un'etichetta|elektronisch|electroni(?:c|que|sch)|elettronic|pre.?advi[cs]|preannunciat|vorangemeldet|preannonce|data.*entered|donnees.*saisies|daten.*erfasst|dati.*inseriti|\bpre ?(?:registered|registration|registr?ad[oa]s?|registrat[oa]|enregistree?s?)\b|\bprerregistr(?:ad[oa]s?|o)\b|\bvorregistriert\b|\bwstepnie zarejestrowan[aey]\b/.test(t) || /\border (?:details|information|info|data) (?:(?:has|have) been |was |were )?(?:received|submitted|transmitted)\b|\breceived (?:your |the )?order (?:details|information|data)\b|\b(?:details|informations|donnees) de (?:la |votre )?commande (?:ont ete )?(?:recu|transmis)e?s?\b|\b(?:auftrags|bestell)daten (?:wurden |sind )?(?:erhalten|ubermittelt|eingegangen)\b|\b(?:dati|dettagli) (?:dell'ordine|ordine) (?:sono stati )?ricevuti\b|\b(?:datos|detalles|informacion) del pedido (?:han sido |fueron )?recibid[oa]s?\b|\b(?:dados|detalhes|informacoes?) d[oa] (?:pedido|encomenda) (?:foram )?recebid[oa]s?\b|\bdane zamowienia (?:zostaly )?(?:otrzymane|przyjete)\b|\botrzymano dane zamowienia\b/.test(t) || /shipment information (?:received|sent to)|\bdata received\b|(?:package|parcel|shipment) data (?:was |has been )?sent to|\bpre ?notification\b|informations d'expedition recues|sendungsinformationen erhalten|informazioni.*spedizione ricevute|(?:consignment|shipment|parcel|package) recorded by|envoi enregistre par|sendung.*absender.*erfasst|spedizione registrata dal/.test(t) || /\b(?:we're|we are) expecting (?:your|the) (?:parcel|package|item|shipment) to arrive with us\b/.test(t) || /preparation chez.*expediteur|preparation.*expediteur|preparazione.*mittente|being prepared.*sender|(?:shipper|sender)(?: that)? (?:they are|is|are) preparing|beim absender.*vorbereitet|warehouse of the sender|shippers warehouse|entrepot de l'expediteur|lager des absenders|magazzino del mittente|demande d'envoi.*prise en compte|collection request.*(?:received|recorded)|abholauftrag.*erfasst|richiesta.*ritiro.*registrata/.test(t) || /\border submitted(?:,| and)? pending (?:to )?rece(?:iv|ipt)|\bshipment data uploaded\b|^sender preparing item\b|^shipping info(?:rmation)? sent to (?!(?:the |your? )?(?:recipient|customer|consignee|addressee|buyer)\b)|\bwe have received your shipment information\b|\bhemos recibido la informacion de su envio\b|\bwe will pick up (?:the|your) (?:package|parcel) from the sender\b|\bpending shipping by (?:the )?(?:seller|sender|shipper|merchant)\b|\bshipment order created\b/.test(t)) return "registered";
|
|
29483
29483
|
if (!/\b(?:at|in|by) (?:the )?(?:destination|delivery|recipient|consignee|addressee|customer|customs|office of exchange)\b/.test(t)) {
|
|
29484
29484
|
let e = t.replace(_c, " ");
|
|
29485
29485
|
if (e !== t) return Hc(e.replace(/^[\s,;:.!?]+|[\s,;:]+$/g, "")) ?? (Sc.test(t) ? !Cc.test(t) && wc.test(t) ? "in_transit" : "customs" : "registered");
|
|
@@ -29488,7 +29488,7 @@ function Hc(e) {
|
|
|
29488
29488
|
if (/(?:国内|出口|进口|目的国)?清关中/.test(t) || Cc.test(t)) return "customs";
|
|
29489
29489
|
if (wc.test(t)) return "in_transit";
|
|
29490
29490
|
if (Sc.test(t)) return "customs";
|
|
29491
|
-
if (/out for (?:physical )?delivery|\bout with (?:the |a |our |your )?(?:delivery )?(?:courier|driver)s?\b(?! for (?:pick ?up|collection|return))|being delivered|\bin delivery\b(?! (?:terminal|depot|cent(?:er|re)|office|facility|hub|station|base|area|point)s?\b)|(?:loading|loaded).*delivery vehicle|on (?:\w+ )?vehicle for delivery|\bon ?board for delivery\b|(?:courier|driver|delivery champion) has (?:the|your) (?:shipment|parcel|package|item)|en cours de livraison|en livraison|de la livraison de (?:son|votre) colis ce jour|charg(?:e|ement).*vehicule de livraison|in zustellung|zustellfahrzeug.*(?:geladen|verladen)|(?:beladen|verladung).*zustellfahrzeug|in consegna|caric(?:at|amento).*veicolo.*consegna/.test(t) || /^(?:en )?reparto$|\ben reparto\b|\b(?:siendo|sendo|a ser) (?:entregad[oa]s?|entregues?|repartid[oa]s?|distribuid[oa]s?)\b|\b(?:salida|salio|sale|ha salido) (?:a|para) (?:el )?reparto\b|\bruta de (?:reparto|entrega)\b|\ben proceso de entrega\b|\bvehiculo de reparto\b|\b(?:repartidor|mensajero|cartero|conductor) (?:ya )?(?:tiene|lleva) (?:tu|su|el|la) (?:paquete|envio|pedido|encomienda)\b|\bem distribuicao\b|\bsaiu para (?:a )?(?:entrega|distribuicao)\b|\bem (?:rota|processo|curso) de entrega\b|\bem entrega\b|\bveiculo de (?:entrega|distribuicao)\b|\b(?:carteiro|estafeta|motorista|entregador) (?:ja )?(?:tem|leva) (?:a|o) (?:sua |tua )?(?:encomenda|envio|objeto|pacote|volume)\b/.test(t) || bc.test(t) && !/\b(?:pick ?up|collection|return|sender|shipper|seller|merchant|consignor)/.test(t)) return "out_for_delivery";
|
|
29491
|
+
if (/out for (?:physical )?delivery|\bout with (?:the |a |our |your )?(?:delivery )?(?:courier|driver)s?\b(?! for (?:pick ?up|collection|return))|being delivered|\bin delivery\b(?! (?:terminal|depot|cent(?:er|re)|office|facility|hub|station|base|area|point)s?\b)|(?:loading|loaded).*delivery vehicle|on (?:\w+ )?vehicle for delivery|\bon ?board for delivery\b|(?:courier|driver|delivery champion) has (?:the|your) (?:shipment|parcel|package|item)|\bcourier will deliver (?:the|your) (?:parcel|package|shipment|item) (?:soon|today)\b|en cours de livraison|en livraison|de la livraison de (?:son|votre) colis ce jour|charg(?:e|ement).*vehicule de livraison|in zustellung|zustellfahrzeug.*(?:geladen|verladen)|(?:beladen|verladung).*zustellfahrzeug|in consegna|caric(?:at|amento).*veicolo.*consegna/.test(t) || /^(?:en )?reparto$|\ben reparto\b|\b(?:siendo|sendo|a ser) (?:entregad[oa]s?|entregues?|repartid[oa]s?|distribuid[oa]s?)\b|\b(?:salida|salio|sale|ha salido) (?:a|para) (?:el )?reparto\b|\bruta de (?:reparto|entrega)\b|\ben proceso de entrega\b|\bvehiculo de reparto\b|\b(?:repartidor|mensajero|cartero|conductor) (?:ya )?(?:tiene|lleva) (?:tu|su|el|la) (?:paquete|envio|pedido|encomienda)\b|\bem distribuicao\b|\bsaiu para (?:a )?(?:entrega|distribuicao)\b|\bem (?:rota|processo|curso) de entrega\b|\bem entrega\b|\bveiculo de (?:entrega|distribuicao)\b|\b(?:carteiro|estafeta|motorista|entregador) (?:ja )?(?:tem|leva) (?:a|o) (?:sua |tua )?(?:encomenda|envio|objeto|pacote|volume)\b/.test(t) || bc.test(t) && !/\b(?:pick ?up|collection|return|sender|shipper|seller|merchant|consignor)/.test(t)) return "out_for_delivery";
|
|
29492
29492
|
if (/\bdelivered\b|^final delivery$|delivery complete(?:d)?\b|delivery (?:was )?successful|(?:a ete|est) distribue|^(?:livre|livree)(?:$|[ ,])|(?:colis|envoi|est|a ete) livre|zugestellt|\bconsegnat[oa]\b|livraison effectuee|consegna completata/.test(t) || !/\b(?:una vez|cuando|hasta que|antes de que|para que|en cuanto|tan pronto como|uma vez|quando|assim que|ate que|logo que)\b[^.;:]*\bentreg/.test(t) && /(?<!\b(?:sea|sean|fuera|fuese|ser|seja|sejam|fosse|for|forem|que|se) )\b(?:entregad[oa]s?|entregues?)\b|\bentrega (?:realizada|efectuada|efetuada|completada|concluida|finalizada)\b/.test(t)) return "delivered";
|
|
29493
29493
|
if (xc.test(t) || /(?<!\bnot (?:yet )?(?:been )?)\b(?:picked up|collected) by (?:the |a |our )?(?:last|final)[- ]mile (?:carrier|courier|delivery partner)s?\b/.test(t)) return "in_transit";
|
|
29494
29494
|
if (/^(?:the |your )?(?:item|package|parcel|shipment) (?:has been |was |is )?(?:received for transport|(?:dropped off|deposited) by (?:the )?sender (?:at|with) (?:our |the |a )?postal partner)\b/.test(t)) return "accepted";
|
|
@@ -29498,7 +29498,7 @@ function Hc(e) {
|
|
|
29498
29498
|
if (/^(?:posting\/collection|posted|origin scan)$|received at (?:our |the )?(?:[a-z]+ )?origin (?:office|facility|hub)|dropped off (?:after|before) (?:the )?latest drop ?off time/.test(t)) return "accepted";
|
|
29499
29499
|
if (/(?:\b(?:not|never)|n't)(?: (?:be|been|being))? accepted\b/.test(t)) return "exception";
|
|
29500
29500
|
if (/accepted|picked up|pick up was successful|^drop off$|pick ?up scan|prepared the package for return to ups or pickup by ups|handed (?:over )?to (?:dpd|gls)|package received at dhl|item booked|consignment was mailed|posted at a postal point|pris en charge|prise en charge|collecte.*(?:reussi|effectue)|recupere.*boite aux lettres|depose.*point postal|remis a (?:dpd|gls)|envoi.*depose|abholung.*erfolgreich|eingeliefert|an (?:dpd|gls) ubergeben|paket.*(?:angenommen|ubernommen)|ritiro.*(?:riuscito|effettuato)|pres[oa] in carico|affidat[oa] a (?:dpd|gls)|depositat.*punto postale|spedizione.*impostata/.test(t) || /^item received by royal mail$|\btaken over by one of our operators\b|\bwe've received your (?:parcel|package|item) at the parcel ?shop\b|^(?:(?:the |your )?(?:item|parcel|package|shipment) )?(?:was|has been) dropped off at (?:the |a )?parcel ?shop$|^已入库|^(?:(?:the |your )?(?:item|parcel|package|shipment) )?(?:has been |was )?put into storage$/.test(t) || /(?<!\b(?:no|nao) )\badmitid[oa]s?\b|\badmision en origen\b/.test(t)) return "accepted";
|
|
29501
|
-
if (/\bcross ?dock(?:ed|ing)?\b|\bready for outbound\b|\b(?:un)?bagg(?:ed|ing)\b|\bmaster (?:air ?way ?bill|awb)(?: (?:number|no))? (?:received|assigned|allocated)\b|\bhand ?over to (?:the |an )?(?:airline|air carrier)\b|^(?:(?:the |your )?(?:item|parcel|package|shipment) )?(?:has )?left (?:the|our) warehouse$|\b(?:flight|leg)\b[^.;]*\b(?:is taking off|took off|has taken off|landed)\b|\bflight (?:take ?off|landing)\b|^(?:initial|final) landing$|\bcargo tally in the supervised warehouse\b|\bprepared for (?:the )?last[- ]mile hand ?over\b/.test(t) || /transit|\bline ?haul\b|en route|on (?:its|the) way|\bfacility\b|airport|\bleaving\b|\bdispatched\b|^delay(?:ed)?$|received by (?:the )?(?:local )?(?:delivery|logistics) company|\btransfer to (?:the |a |an )?(?:local |destination )?(?:acting |delivery |logistics |courier )?(?:company|agent|carrier|partner)\b|received by postnl|notification.*sent to the recipient|delivery option requested|instruction de livraison recue|expedie (?:depuis|du|de)\b|acheminement|unterwegs|transport|trasport|arriv|depart|processed|processing completed|sorted|sorting|\btri\b|\btriee?s?\b|traitement|traite|sortier|bearbeitet|bearbeitung|elaborat|elaborazion|smistat|parcel cent(?:er|re)|delivery cent(?:er|re)|centre.*(?:colis|distribution)|paketzentrum|verteilzentrum|centro.*(?:pacchi|distribuzione)|depot|import scan|scan.*import|importscan|scansione.*import|delivery.*delayed|livraison.*(?:retard|report)|zustellung.*verzogert|consegna.*ritard|transferred|transfere|weitergeleitet|inoltrato|left.*(?:point|center)|quitte|verlassen|raggiunto|close bag|fermeture du sac|sack.*geschlossen|chiusura.*sacco|scanned into|scanne dans|eingescannt|scansionat|\b(?:un)?loaded\b|^(?:item|parcel|shipment) distributed$|charg.*vehicule de transport|transportfahrzeug.*geladen|caric.*veicolo.*trasporto/.test(t) || /^enviad[oa]$|\bclasificad[oa]s?\b|\bclasificacion\b|\ben ruta\b|\ben camino\b|\bllegad[oa]s? (?:a|al|en)\b|\bllegada (?:a|al|en|de)\b|\bha llegado\b|\bllego (?:a|al)\b|\bsalida (?:de|del|desde)\b|\b(?:ha )?salido (?:de|del)\b|\bsalio (?:de|del)\b|\ben destino\b|\b(?:agencia|delegacion|plataforma|oficina|franquicia) (?:de )?destino\b|\b(?:unidad|centro|oficina|delegacion|base|agencia|plataforma) de reparto\b|\bcentro (?:de )?(?:clasificacion|distribucion|tratamiento|logistico|operaciones|operativo)\b|\blectura\b|\bleid[oa]s?\b|\brecepcionad[oa]s?\b|\bprocesad[oa]s?\b|\bexpedid[oa]s?\b|\btriagem\b|\btriad[oa]s?\b|\bem tratamento\b|\btratad[oa]s?\b|\bcentro (?:de )?(?:distribuicao|tratamento|triagem|operacional)\b|\bchegad[ao] (?:a|ao|no|na|em)\b|\bchegou (?:a|ao|no|na|em)\b|\bsaida (?:do|da|de|dos|das)\b|\bsaiu (?:do|da|de|dos|das)\b|\bem rota\b|\ba caminho\b|\bencaminhad[oa]s?\b|\b(?:em )?transferencia\b|\btransferid[oa]s?\b|\bprocessad[oa]s?\b|\brecebid[oa] (?:no|na|em) (?:centro|armazem|unidade|plataforma)\b|\brecibid[oa] en (?:el |la |nuestr[oa] )?(?:almacen|centro|delegacion|plataforma|hub|agencia)\b/.test(t)) return "in_transit";
|
|
29501
|
+
if (/\bcross ?dock(?:ed|ing)?\b|\bready for outbound\b|\b(?:un)?bagg(?:ed|ing)\b|\bmaster (?:air ?way ?bill|awb)(?: (?:number|no))? (?:received|assigned|allocated)\b|\bhand ?over to (?:the |an )?(?:airline|air carrier)\b|^(?:(?:the |your )?(?:item|parcel|package|shipment) )?(?:has )?left (?:the|our) warehouse$|\b(?:flight|leg)\b[^.;]*\b(?:is taking off|took off|has taken off|landed)\b|\bflight (?:take ?off|landing)\b|^(?:initial|final) landing$|\bcargo tally in the supervised warehouse\b|\bprepared for (?:the )?last[- ]mile hand ?over\b/.test(t) || /transit|\bline ?haul\b|en route|on (?:its|the) way|\bfacility\b|airport|\bleaving\b|\bdispatched\b|^delay(?:ed)?$|received by (?:the )?(?:local )?(?:delivery|logistics) company|\btransfer to (?:the |a |an )?(?:local |destination )?(?:acting |delivery |logistics |courier )?(?:company|agent|carrier|partner)\b|received by (?:postnl|uniuni)\b|notification.*sent to the recipient|delivery option requested|instruction de livraison recue|expedie (?:depuis|du|de)\b|acheminement|unterwegs|transport|trasport|arriv|depart|processed|processing completed|sorted|sorting|\btri\b|\btriee?s?\b|traitement|traite|sortier|bearbeitet|bearbeitung|elaborat|elaborazion|smistat|parcel cent(?:er|re)|delivery cent(?:er|re)|centre.*(?:colis|distribution)|paketzentrum|verteilzentrum|centro.*(?:pacchi|distribuzione)|depot|import scan|scan.*import|importscan|scansione.*import|delivery.*delayed|livraison.*(?:retard|report)|zustellung.*verzogert|consegna.*ritard|transferred|transfere|weitergeleitet|inoltrato|left.*(?:point|center)|quitte|verlassen|raggiunto|close bag|fermeture du sac|sack.*geschlossen|chiusura.*sacco|scanned into|scanne dans|eingescannt|scansionat|\b(?:un)?loaded\b|^(?:item|parcel|shipment) distributed$|charg.*vehicule de transport|transportfahrzeug.*geladen|caric.*veicolo.*trasporto/.test(t) || /^enviad[oa]$|\bclasificad[oa]s?\b|\bclasificacion\b|\ben ruta\b|\ben camino\b|\bllegad[oa]s? (?:a|al|en)\b|\bllegada (?:a|al|en|de)\b|\bha llegado\b|\bllego (?:a|al)\b|\bsalida (?:de|del|desde)\b|\b(?:ha )?salido (?:de|del)\b|\bsalio (?:de|del)\b|\ben destino\b|\b(?:agencia|delegacion|plataforma|oficina|franquicia) (?:de )?destino\b|\b(?:unidad|centro|oficina|delegacion|base|agencia|plataforma) de reparto\b|\bcentro (?:de )?(?:clasificacion|distribucion|tratamiento|logistico|operaciones|operativo)\b|\blectura\b|\bleid[oa]s?\b|\brecepcionad[oa]s?\b|\bprocesad[oa]s?\b|\bexpedid[oa]s?\b|\btriagem\b|\btriad[oa]s?\b|\bem tratamento\b|\btratad[oa]s?\b|\bcentro (?:de )?(?:distribuicao|tratamento|triagem|operacional)\b|\bchegad[ao] (?:a|ao|no|na|em)\b|\bchegou (?:a|ao|no|na|em)\b|\bsaida (?:do|da|de|dos|das)\b|\bsaiu (?:do|da|de|dos|das)\b|\bem rota\b|\ba caminho\b|\bencaminhad[oa]s?\b|\b(?:em )?transferencia\b|\btransferid[oa]s?\b|\bprocessad[oa]s?\b|\brecebid[oa] (?:no|na|em) (?:centro|armazem|unidade|plataforma)\b|\brecibid[oa] en (?:el |la |nuestr[oa] )?(?:almacen|centro|delegacion|plataforma|hub|agencia)\b/.test(t)) return "in_transit";
|
|
29502
29502
|
}
|
|
29503
29503
|
function Uc(e) {
|
|
29504
29504
|
return e === "registered" || e === "pending" ? "pending" : e === "delivered" ? "delivered" : e === "out_for_delivery" || e === "ready_for_pickup" ? "out_for_delivery" : e === "returned" || e === "failed_attempt" || e === "exception" ? "exception" : "in_transit";
|
|
@@ -206,6 +206,18 @@
|
|
|
206
206
|
]
|
|
207
207
|
},
|
|
208
208
|
"note": "Looked up on Chunghwa Post's own tracker, as an archived address shows; the capture was not opened. The former domestic lookup on postserv.post.gov.tw."
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"number": "UH000000005TW",
|
|
212
|
+
"role": "shipment",
|
|
213
|
+
"evidence": "synthetic",
|
|
214
|
+
"derivedFrom": "donated_real",
|
|
215
|
+
"shapeConfirmed": "2026-10-21",
|
|
216
|
+
"expect": {
|
|
217
|
+
"carrier": "chunghwa-post",
|
|
218
|
+
"confidence": "high"
|
|
219
|
+
},
|
|
220
|
+
"note": "Made-up number in the shape of Taiwan-issued letter post that Chunghwa Post's tracker answered."
|
|
209
221
|
}
|
|
210
222
|
]
|
|
211
223
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { normalizeHualeiNumber, parseHualeiPage, parseHualeiTrack } from './hualei.js';
|
|
2
|
-
import { gzylStage, PLACED_WORDINGS } from './status.js';
|
|
2
|
+
import { gzylStage, PLACED_WORDINGS, TOWN } from './status.js';
|
|
3
3
|
export const PROVIDER = 'GZYL';
|
|
4
4
|
export const GZYL_ORIGIN = 'http://134.175.243.207:8082';
|
|
5
|
-
// A town: a letter, then letters, digits, spaces, dots, apostrophes or hyphens.
|
|
6
|
-
const TOWN = /^\p{L}[\p{L}\p{N} .'-]*$/u;
|
|
7
5
|
/**
|
|
8
6
|
* GZYL writes the town of a sorting centre, or of the parcel's way, after some
|
|
9
7
|
* wordings ("Leaving the sorting center Town") and leaves the row's place
|
|
@@ -2,6 +2,7 @@ import type { Stage } from '../../core/status/index.js';
|
|
|
2
2
|
import { type CarrierStatusMap } from '../../core/status/statusMap.js';
|
|
3
3
|
/** Wordings GZYL writes a town after, leaving the row's own place empty. */
|
|
4
4
|
export declare const PLACED_WORDINGS: readonly string[];
|
|
5
|
+
export declare const TOWN: RegExp;
|
|
5
6
|
/**
|
|
6
7
|
* The stage GZYL's map gives a row, by its `normalizeStatusWording` wording.
|
|
7
8
|
* A row's kind code, when it has one, groups many wordings and decides nothing.
|
|
@@ -2,8 +2,11 @@ import { normalizeStatusWording } from '../../core/status/statusMap.js';
|
|
|
2
2
|
import statuses from './statuses.json' with { type: 'json' };
|
|
3
3
|
const WORDINGS = new Map(statuses.entries.map((entry) => [normalizeStatusWording(entry.wording), entry.stage]));
|
|
4
4
|
/** Wordings GZYL writes a town after, leaving the row's own place empty. */
|
|
5
|
-
export const PLACED_WORDINGS = ['Arrival sorting, distribution center', 'Leaving the sorting center', 'Package is on the way'];
|
|
5
|
+
export const PLACED_WORDINGS = ['Arrival sorting, distribution center', 'Leaving the sorting center', 'Package is on the way', 'Delivered'];
|
|
6
6
|
const PLACED = PLACED_WORDINGS.map((wording) => `${normalizeStatusWording(wording)} `);
|
|
7
|
+
// A town: a letter, then letters, digits, spaces, dots, apostrophes or hyphens,
|
|
8
|
+
// but not a phrase such as "to the neighbour" that goes on the wording.
|
|
9
|
+
export const TOWN = /^(?!(?:to|at|in|on|by|with|from|for)\b)\p{L}[\p{L}\p{N} .'-]*$/iu;
|
|
7
10
|
/**
|
|
8
11
|
* The stage GZYL's map gives a row, by its `normalizeStatusWording` wording.
|
|
9
12
|
* A row's kind code, when it has one, groups many wordings and decides nothing.
|
|
@@ -11,7 +14,7 @@ const PLACED = PLACED_WORDINGS.map((wording) => `${normalizeStatusWording(wordin
|
|
|
11
14
|
* as the wording alone.
|
|
12
15
|
*/
|
|
13
16
|
export function gzylStage(_code, wording) {
|
|
14
|
-
const prefix = PLACED.find((placed) => wording.startsWith(placed));
|
|
17
|
+
const prefix = PLACED.find((placed) => wording.startsWith(placed) && TOWN.test(wording.slice(placed.length)));
|
|
15
18
|
return WORDINGS.get(wording) ?? (prefix ? WORDINGS.get(prefix.trimEnd()) : undefined);
|
|
16
19
|
}
|
|
17
20
|
export const statusMap = { stage: gzylStage, gaps: [] };
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
{"wording": "Arrival sorting, distribution center", "language": "en", "stage": "in_transit", "confirmedBy": "live", "note": "The destination network sorts the parcel at a town's distribution centre. GZYL writes the town after the wording; it is read as the place."},
|
|
16
16
|
{"wording": "Leaving the sorting center", "language": "en", "stage": "in_transit", "confirmedBy": "live", "note": "The parcel leaves a town's sorting centre for its next stop. GZYL writes the town after the wording; it is read as the place."},
|
|
17
17
|
{"wording": "Package is on the way", "language": "en", "stage": "in_transit", "confirmedBy": "live", "firstSeen": "2026-10-20", "note": "GZYL writes a town in the destination country after the wording; it is read as the place."},
|
|
18
|
+
{"wording": "Delivered", "language": "en", "stage": "delivered", "confirmedBy": "live", "firstSeen": "2026-10-21", "note": "The destination network's delivery. GZYL writes the town after the wording; it is read as the place."},
|
|
18
19
|
{"wording": "货物电子信息已经收到", "language": "zh", "stage": "registered", "confirmedBy": "prior-art", "note": "The platform writes this row itself for an order without scans, on its creation time."}
|
|
19
20
|
]
|
|
20
21
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { classifyWording } from '../../core/status/index.js';
|
|
2
2
|
import { normalizeStatusWording } from '../../core/status/statusMap.js';
|
|
3
|
-
// The origin milestone codes are documented by getCargoTrack.
|
|
4
|
-
//
|
|
5
|
-
// and
|
|
3
|
+
// The origin milestone codes are documented by getCargoTrack. The web tracker
|
|
4
|
+
// adds the flight and clearance milestones, JY for the hand-off to the
|
|
5
|
+
// destination carrier, and codes for that carrier's out-for-delivery (CB),
|
|
6
|
+
// delivery-point arrival (PB) and delivery (CC) scans. IA covers that carrier's
|
|
7
|
+
// other scans, which its wording places.
|
|
6
8
|
const CODES = new Map([
|
|
7
|
-
['IR', 'registered'], ['AF', 'accepted'], ['DF', 'in_transit'], ['
|
|
9
|
+
['IR', 'registered'], ['AF', 'accepted'], ['DF', 'in_transit'], ['GG', 'in_transit'], ['BG', 'in_transit'],
|
|
10
|
+
['QF', 'in_transit'], ['QG', 'customs'], ['LD', 'in_transit'], ['YG', 'in_transit'], ['JY', 'in_transit'],
|
|
11
|
+
['CB', 'out_for_delivery'], ['PB', 'ready_for_pickup'], ['CC', 'delivered'],
|
|
8
12
|
]);
|
|
9
13
|
// Scans 17TRACK relays without their code: "Data processed" comes between departures from the origin facility.
|
|
10
14
|
const WORDINGS = new Map([['data processed', 'in_transit']]);
|
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
{"code": "DF", "wording": "快件操作完成 Shipment departed from facility", "stage": "in_transit", "language": "zh", "confirmedBy": "official-doc", "note": "In the tracking example of HuaHan's API documentation: the parcel left HuaHan's operations centre in Shenzhen."},
|
|
11
11
|
{"wording": "快件操作完成", "stage": "in_transit", "language": "zh", "confirmedBy": "official-doc", "note": "In the tracking example of HuaHan's API documentation: the latest-event summary form of the departure from the operations centre."},
|
|
12
12
|
{"wording": "Data processed", "stage": "in_transit", "language": "en", "confirmedBy": "source", "note": "Relayed by 17TRACK without a code, between the parcel's departures from the origin facility."},
|
|
13
|
-
{"code": "
|
|
13
|
+
{"code": "GG", "wording": "Transfer to Origin airport", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "The parcel moving from the origin facility to the departure airport."},
|
|
14
|
+
{"code": "BG", "wording": "Export customs clearance completed", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "Export clearance at the origin, before the flight."},
|
|
15
|
+
{"code": "QF", "wording": "Departed from airport of Origin", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "The flight leaving the origin."},
|
|
16
|
+
{"code": "QG", "wording": "Import Customs clearance started", "stage": "customs", "language": "en", "confirmedBy": "live", "note": "Import clearance opening at the destination gateway."},
|
|
17
|
+
{"code": "LD", "wording": "Arrived at destination airport", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "The flight landing at the destination gateway."},
|
|
18
|
+
{"code": "YG", "wording": "Import Customs clearance completed", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "Import clearance released, before the hand-off to the destination carrier."},
|
|
19
|
+
{"code": "JY", "wording": "Has been given to local carrier", "stage": "in_transit", "language": "en", "confirmedBy": "live", "note": "HuaHan handing the parcel to the destination carrier after import clearance; the partner's scans follow it."},
|
|
20
|
+
{"code": "CB", "wording": "Out for Delivery, Parcel is at courier, delivery expected soon.", "stage": "out_for_delivery", "language": "en", "confirmedBy": "live", "note": "The destination carrier's courier scan, relayed under HuaHan's code."},
|
|
21
|
+
{"code": "CC", "wording": "Delivered, Parcel was delivered successfully", "stage": "delivered", "language": "en", "confirmedBy": "live", "note": "The destination carrier's delivery, relayed under HuaHan's code with that carrier's wording."},
|
|
22
|
+
{"code": "CC", "wording": "The parcel has been successfully delivered.", "stage": "delivered", "language": "en", "confirmedBy": "live", "note": "A second delivery wording from the same destination carrier under the same code."}
|
|
14
23
|
]
|
|
15
24
|
}
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"detection": [
|
|
40
40
|
{
|
|
41
41
|
"id": "intl-post-2",
|
|
42
|
-
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
42
|
+
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
43
43
|
"confidence": "high",
|
|
44
44
|
"checksum": "s10"
|
|
45
45
|
}
|
|
@@ -14,7 +14,7 @@ const EVENTS_API_PREFIX = 'https://api-web.royalmail.com/mailpieces/v3/';
|
|
|
14
14
|
const MAX_EVENTS_TO_INSPECT = 500;
|
|
15
15
|
const MAX_EVENTS_TO_RETURN = 100;
|
|
16
16
|
// A parcel hub's or a mail centre's receipt, without an acceptance before it.
|
|
17
|
-
const FIRST_RECEIPTS = new Set(['EVBAH', 'EVDAC']);
|
|
17
|
+
const FIRST_RECEIPTS = new Set(['EVBAH', 'EVDAC', 'EVDAV']);
|
|
18
18
|
/** A Parcelforce parcel: PB, its consignment number and the parcel's place in it. */
|
|
19
19
|
const PARCELFORCE_PARCEL = /^PB[A-Z]{2}\d{10}$/;
|
|
20
20
|
export function normalizeRoyalMailNumber(raw) {
|
|
@@ -160,9 +160,9 @@ export function parseRoyalMailTrackingResponse(payload, trackingNumber) {
|
|
|
160
160
|
// clocks. Preserve provider order unless every scan denotes an instant.
|
|
161
161
|
if (events.every(event => event.time)) {
|
|
162
162
|
events.sort((a, b) => Date.parse(b.time) - Date.parse(a.time));
|
|
163
|
-
// Mail a sender hands in at a parcel hub
|
|
164
|
-
// receives first, has no acceptance scan before that receipt,
|
|
165
|
-
// summary then calls "We've got it".
|
|
163
|
+
// Mail a sender hands in at a parcel hub or a mail centre, or a collection
|
|
164
|
+
// one of them receives first, has no acceptance scan before that receipt,
|
|
165
|
+
// which the summary then calls "We've got it".
|
|
166
166
|
const first = [...events].reverse().find(event => event.stage !== 'registered' && event.stage !== 'pending');
|
|
167
167
|
if (first?.stage === 'in_transit' && FIRST_RECEIPTS.has(first.provider_code ?? ''))
|
|
168
168
|
first.stage = 'accepted';
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
"stage": "in_transit",
|
|
142
142
|
"confirmedBy": "live",
|
|
143
143
|
"firstSeen": "2026-10-05",
|
|
144
|
-
"note": "
|
|
144
|
+
"note": "A mail centre or hub receipt. The first one is the acceptance when no scan accepted the item before it."
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
"code": "EVAIP",
|
|
@@ -327,7 +327,7 @@ export function trackingLanguageStage(description) {
|
|
|
327
327
|
return 'registered';
|
|
328
328
|
// The sender's order or data reached the carrier, not the parcel: "Order submitted, pending to
|
|
329
329
|
// receive", "Sender preparing item", "Shipping info sent to BRT".
|
|
330
|
-
if (/\border submitted(?:,| and)? pending (?:to )?rece(?:iv|ipt)|\bshipment data uploaded\b|^sender preparing item\b|^shipping info(?:rmation)? sent to (?!(?:the |your? )?(?:recipient|customer|consignee|addressee|buyer)\b)|\bwe have received your shipment information\b|\bhemos recibido la informacion de su envio\b|\bwe will pick up the (?:package|parcel) from the sender\b|\bpending shipping by (?:the )?(?:seller|sender|shipper|merchant)\b|\bshipment order created\b/.test(text))
|
|
330
|
+
if (/\border submitted(?:,| and)? pending (?:to )?rece(?:iv|ipt)|\bshipment data uploaded\b|^sender preparing item\b|^shipping info(?:rmation)? sent to (?!(?:the |your? )?(?:recipient|customer|consignee|addressee|buyer)\b)|\bwe have received your shipment information\b|\bhemos recibido la informacion de su envio\b|\bwe will pick up (?:the|your) (?:package|parcel) from the sender\b|\bpending shipping by (?:the )?(?:seller|sender|shipper|merchant)\b|\bshipment order created\b/.test(text))
|
|
331
331
|
return 'registered';
|
|
332
332
|
// The carrier has not had the parcel yet: "Shipment not yet received or
|
|
333
333
|
// processed". What else the scan reports still counts: "Arrived at hub; not
|
|
@@ -360,7 +360,7 @@ export function trackingLanguageStage(description) {
|
|
|
360
360
|
return 'in_transit';
|
|
361
361
|
if (CUSTOMS.test(text))
|
|
362
362
|
return 'customs';
|
|
363
|
-
if (/out for (?:physical )?delivery|\bout with (?:the |a |our |your )?(?:delivery )?(?:courier|driver)s?\b(?! for (?:pick ?up|collection|return))|being delivered|\bin delivery\b(?! (?:terminal|depot|cent(?:er|re)|office|facility|hub|station|base|area|point)s?\b)|(?:loading|loaded).*delivery vehicle|on (?:\w+ )?vehicle for delivery|\bon ?board for delivery\b|(?:courier|driver|delivery champion) has (?:the|your) (?:shipment|parcel|package|item)|en cours de livraison|en livraison|de la livraison de (?:son|votre) colis ce jour|charg(?:e|ement).*vehicule de livraison|in zustellung|zustellfahrzeug.*(?:geladen|verladen)|(?:beladen|verladung).*zustellfahrzeug|in consegna|caric(?:at|amento).*veicolo.*consegna/.test(text))
|
|
363
|
+
if (/out for (?:physical )?delivery|\bout with (?:the |a |our |your )?(?:delivery )?(?:courier|driver)s?\b(?! for (?:pick ?up|collection|return))|being delivered|\bin delivery\b(?! (?:terminal|depot|cent(?:er|re)|office|facility|hub|station|base|area|point)s?\b)|(?:loading|loaded).*delivery vehicle|on (?:\w+ )?vehicle for delivery|\bon ?board for delivery\b|(?:courier|driver|delivery champion) has (?:the|your) (?:shipment|parcel|package|item)|\bcourier will deliver (?:the|your) (?:parcel|package|shipment|item) (?:soon|today)\b|en cours de livraison|en livraison|de la livraison de (?:son|votre) colis ce jour|charg(?:e|ement).*vehicule de livraison|in zustellung|zustellfahrzeug.*(?:geladen|verladen)|(?:beladen|verladung).*zustellfahrzeug|in consegna|caric(?:at|amento).*veicolo.*consegna/.test(text))
|
|
364
364
|
return 'out_for_delivery';
|
|
365
365
|
// "Reparto" alone is the round, but not the "unidad de reparto" it leaves from;
|
|
366
366
|
// "distribuição" is the round, but not the "centro de distribuição".
|
|
@@ -420,7 +420,7 @@ export function trackingLanguageStage(description) {
|
|
|
420
420
|
if (/\bcross ?dock(?:ed|ing)?\b|\bready for outbound\b|\b(?:un)?bagg(?:ed|ing)\b|\bmaster (?:air ?way ?bill|awb)(?: (?:number|no))? (?:received|assigned|allocated)\b|\bhand ?over to (?:the |an )?(?:airline|air carrier)\b|^(?:(?:the |your )?(?:item|parcel|package|shipment) )?(?:has )?left (?:the|our) warehouse$|\b(?:flight|leg)\b[^.;]*\b(?:is taking off|took off|has taken off|landed)\b|\bflight (?:take ?off|landing)\b|^(?:initial|final) landing$|\bcargo tally in the supervised warehouse\b|\bprepared for (?:the )?last[- ]mile hand ?over\b/.test(text))
|
|
421
421
|
return 'in_transit';
|
|
422
422
|
// A linehaul is the trunk haul between hubs, whatever was handed over.
|
|
423
|
-
if (/transit|\bline ?haul\b|en route|on (?:its|the) way|\bfacility\b|airport|\bleaving\b|\bdispatched\b|^delay(?:ed)?$|received by (?:the )?(?:local )?(?:delivery|logistics) company|\btransfer to (?:the |a |an )?(?:local |destination )?(?:acting |delivery |logistics |courier )?(?:company|agent|carrier|partner)\b|received by postnl|notification.*sent to the recipient|delivery option requested|instruction de livraison recue|expedie (?:depuis|du|de)\b|acheminement|unterwegs|transport|trasport|arriv|depart|processed|processing completed|sorted|sorting|\btri\b|\btriee?s?\b|traitement|traite|sortier|bearbeitet|bearbeitung|elaborat|elaborazion|smistat|parcel cent(?:er|re)|delivery cent(?:er|re)|centre.*(?:colis|distribution)|paketzentrum|verteilzentrum|centro.*(?:pacchi|distribuzione)|depot|import scan|scan.*import|importscan|scansione.*import|delivery.*delayed|livraison.*(?:retard|report)|zustellung.*verzogert|consegna.*ritard|transferred|transfere|weitergeleitet|inoltrato|left.*(?:point|center)|quitte|verlassen|raggiunto|close bag|fermeture du sac|sack.*geschlossen|chiusura.*sacco|scanned into|scanne dans|eingescannt|scansionat|\b(?:un)?loaded\b|^(?:item|parcel|shipment) distributed$|charg.*vehicule de transport|transportfahrzeug.*geladen|caric.*veicolo.*trasporto/.test(text))
|
|
423
|
+
if (/transit|\bline ?haul\b|en route|on (?:its|the) way|\bfacility\b|airport|\bleaving\b|\bdispatched\b|^delay(?:ed)?$|received by (?:the )?(?:local )?(?:delivery|logistics) company|\btransfer to (?:the |a |an )?(?:local |destination )?(?:acting |delivery |logistics |courier )?(?:company|agent|carrier|partner)\b|received by (?:postnl|uniuni)\b|notification.*sent to the recipient|delivery option requested|instruction de livraison recue|expedie (?:depuis|du|de)\b|acheminement|unterwegs|transport|trasport|arriv|depart|processed|processing completed|sorted|sorting|\btri\b|\btriee?s?\b|traitement|traite|sortier|bearbeitet|bearbeitung|elaborat|elaborazion|smistat|parcel cent(?:er|re)|delivery cent(?:er|re)|centre.*(?:colis|distribution)|paketzentrum|verteilzentrum|centro.*(?:pacchi|distribuzione)|depot|import scan|scan.*import|importscan|scansione.*import|delivery.*delayed|livraison.*(?:retard|report)|zustellung.*verzogert|consegna.*ritard|transferred|transfere|weitergeleitet|inoltrato|left.*(?:point|center)|quitte|verlassen|raggiunto|close bag|fermeture du sac|sack.*geschlossen|chiusura.*sacco|scanned into|scanne dans|eingescannt|scansionat|\b(?:un)?loaded\b|^(?:item|parcel|shipment) distributed$|charg.*vehicule de transport|transportfahrzeug.*geladen|caric.*veicolo.*trasporto/.test(text))
|
|
424
424
|
return 'in_transit';
|
|
425
425
|
if (/^enviad[oa]$|\bclasificad[oa]s?\b|\bclasificacion\b|\ben ruta\b|\ben camino\b|\bllegad[oa]s? (?:a|al|en)\b|\bllegada (?:a|al|en|de)\b|\bha llegado\b|\bllego (?:a|al)\b|\bsalida (?:de|del|desde)\b|\b(?:ha )?salido (?:de|del)\b|\bsalio (?:de|del)\b|\ben destino\b|\b(?:agencia|delegacion|plataforma|oficina|franquicia) (?:de )?destino\b|\b(?:unidad|centro|oficina|delegacion|base|agencia|plataforma) de reparto\b|\bcentro (?:de )?(?:clasificacion|distribucion|tratamiento|logistico|operaciones|operativo)\b|\blectura\b|\bleid[oa]s?\b|\brecepcionad[oa]s?\b|\bprocesad[oa]s?\b|\bexpedid[oa]s?\b|\btriagem\b|\btriad[oa]s?\b|\bem tratamento\b|\btratad[oa]s?\b|\bcentro (?:de )?(?:distribuicao|tratamento|triagem|operacional)\b|\bchegad[ao] (?:a|ao|no|na|em)\b|\bchegou (?:a|ao|no|na|em)\b|\bsaida (?:do|da|de|dos|das)\b|\bsaiu (?:do|da|de|dos|das)\b|\bem rota\b|\ba caminho\b|\bencaminhad[oa]s?\b|\b(?:em )?transferencia\b|\btransferid[oa]s?\b|\bprocessad[oa]s?\b|\brecebid[oa] (?:no|na|em) (?:centro|armazem|unidade|plataforma)\b|\brecibid[oa] en (?:el |la |nuestr[oa] )?(?:almacen|centro|delegacion|plataforma|hub|agencia)\b/.test(text))
|
|
426
426
|
return 'in_transit';
|
package/dist/data/catalog.json
CHANGED
|
@@ -2023,7 +2023,7 @@
|
|
|
2023
2023
|
"linkRules": [],
|
|
2024
2024
|
"detectionRules": [
|
|
2025
2025
|
{
|
|
2026
|
-
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2026
|
+
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2027
2027
|
"confidence": "high",
|
|
2028
2028
|
"checksum": "s10"
|
|
2029
2029
|
}
|
|
@@ -8982,7 +8982,7 @@
|
|
|
8982
8982
|
],
|
|
8983
8983
|
"detectionRules": [
|
|
8984
8984
|
{
|
|
8985
|
-
"pattern": "^[CELR][A-Z]\\d{9}TW$",
|
|
8985
|
+
"pattern": "^(?:[CELR][A-Z]|UH)\\d{9}TW$",
|
|
8986
8986
|
"confidence": "high",
|
|
8987
8987
|
"checksum": "s10"
|
|
8988
8988
|
}
|
|
@@ -1332,7 +1332,7 @@ export declare const CARRIER_CATALOG: {
|
|
|
1332
1332
|
readonly trackingSiteName: "17TRACK";
|
|
1333
1333
|
readonly linkRules: readonly [];
|
|
1334
1334
|
readonly detectionRules: readonly [{
|
|
1335
|
-
readonly pattern: "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$";
|
|
1335
|
+
readonly pattern: "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$";
|
|
1336
1336
|
readonly confidence: "high";
|
|
1337
1337
|
readonly checksum: "s10";
|
|
1338
1338
|
}];
|
|
@@ -5894,7 +5894,7 @@ export declare const CARRIER_CATALOG: {
|
|
|
5894
5894
|
readonly params: readonly ["MAILNO"];
|
|
5895
5895
|
}];
|
|
5896
5896
|
readonly detectionRules: readonly [{
|
|
5897
|
-
readonly pattern: "^[CELR][A-Z]\\d{9}TW$";
|
|
5897
|
+
readonly pattern: "^(?:[CELR][A-Z]|UH)\\d{9}TW$";
|
|
5898
5898
|
readonly confidence: "high";
|
|
5899
5899
|
readonly checksum: "s10";
|
|
5900
5900
|
}];
|
|
@@ -2024,7 +2024,7 @@ export const CARRIER_CATALOG = {
|
|
|
2024
2024
|
"linkRules": [],
|
|
2025
2025
|
"detectionRules": [
|
|
2026
2026
|
{
|
|
2027
|
-
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?![CELR][A-Z]\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2027
|
+
"pattern": "^(?![CLR][A-Z]\\d{9}DE$)(?!(?:[CELR][A-Z]|UH)\\d{9}TW$)(?![CEL][A-Z]\\d{9}AU$)(?![CELR][A-Z]\\d{9}SK$)(?![CELR][A-Z]\\d{9}HR$)(?![CELR][A-Z]\\d{9}LV$)(?!AS\\d{9}US$)(?![CELR][A-Z]\\d{9}IT$)(?!(?:PZ|XR|XT|XU|XW|XY))[A-Z]{2}\\d{9}(?!CA$|CH$|FR$|IN$|NL$|GB$|IE$|BE$|PT$|NZ$|SG$|JP$|KR$|TH$|HK$|MY$|CN$|NO$|BR$|ES$|SE$|DK$|AT$|YP$|TS$|JF$|JB$|RV$|VF$|TY$|MI$|XX$|MH$|YW$|CS$|EN$|CL$)[A-Z]{2}$",
|
|
2028
2028
|
"confidence": "high",
|
|
2029
2029
|
"checksum": "s10"
|
|
2030
2030
|
}
|
|
@@ -8983,7 +8983,7 @@ export const CARRIER_CATALOG = {
|
|
|
8983
8983
|
],
|
|
8984
8984
|
"detectionRules": [
|
|
8985
8985
|
{
|
|
8986
|
-
"pattern": "^[CELR][A-Z]\\d{9}TW$",
|
|
8986
|
+
"pattern": "^(?:[CELR][A-Z]|UH)\\d{9}TW$",
|
|
8987
8987
|
"confidence": "high",
|
|
8988
8988
|
"checksum": "s10"
|
|
8989
8989
|
}
|
package/dist/server/openapi.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-parcel-scraper",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.598.0-main.2802",
|
|
4
4
|
"description": "Self-hosted parcel tracking: carrier detection, dedicated scrapers and optional universal providers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|