universal-parcel-scraper 0.993.1-main.5347 → 0.993.2-main.5350

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.
@@ -207,9 +207,12 @@ const WALL_CLOCKS = new Set(['usps', 'canadapost', 'gofoexpress', 'speedpak', 'e
207
207
  * USPS's own rows read "Shipping Label Created, USPS Awaiting Item". Its date
208
208
  * is the instant: read on its place's clock, a label came eight hours after
209
209
  * ParcelsApp first returned it, and Juxi Express's rows of this shape fall
210
- * between 17TRACK's instants of the same warehouse's steps as labeled.
210
+ * between 17TRACK's instants of the same warehouse's steps as labeled. Only a
211
+ * label or a shipping partner's step is such a row: USPS's own scans can come
212
+ * with their place after them too ("USPS picked up item, EXAMPLE CITY, KY
213
+ * 12345"), and USPS's own tracker dates them on their place's clock.
211
214
  */
212
- const USPS_PARTNER_ROW = /,[^,]+,\s*[A-Z]{2}\s+\d{5}(?:-\d{4})?$/;
215
+ const USPS_PARTNER_ROW = /^(?:shipping label created|[^,]*\bshipping partner\b[^,]*),[^,]+,\s*[A-Z]{2}\s+\d{5}(?:-\d{4})?$/i;
213
216
  const uspsPartnerRow = (name, status) => nameKey(name) === 'usps' && USPS_PARTNER_ROW.test(status.trim());
214
217
  // Known clocks that are the destination or origin country's (`knownClock`).
215
218
  const DESTINATION = 'destination';
@@ -16,7 +16,7 @@ import { runSteps } from '../../core/runner/index.js';
16
16
  import { countryTimeZone, firstOccurrence } from '../../core/time/index.js';
17
17
  import { isRecord } from '../../core/types.js';
18
18
  import { trackingPlace } from '../../places/trackingLocation.js';
19
- import { chinaPostEnglish, chinaPostLabelPlace } from '../../carriers/china-post/status.js';
19
+ import { chinaPostDestinationScan, chinaPostEnglish, chinaPostLabelPlace } from '../../carriers/china-post/status.js';
20
20
  import { agencyIntake, cttSiteZone, isCttExpressAgency } from '../../carriers/ctt/clock.js';
21
21
  import { correosOriginZone } from '../../carriers/correos-spain/clock.js';
22
22
  import { daiPostRelayZone } from '../../carriers/dai-post/clock.js';
@@ -553,6 +553,10 @@ export function parse17TrackResponse(payload, trackingNumber, postcode = null) {
553
553
  ? nzPostAbroad(provider.events, number, nzPostDestination(shipment, tracking.providers)) : new Map();
554
554
  const origin = reported.key === CHINA_POST ? originZone(number) : reported.key === JAPAN_POST ? japanPostOriginZone(number) : null;
555
555
  const outward = reported.key === JAPAN_POST ? OUTWARD_SCAN : ORIGIN_EXCHANGE;
556
+ // China Post's copies of the destination post's own scans keep that post's wall clock, as China Post's adapter
557
+ // reads them, and 17TRACK labels them with China's offset: Correos's arrival at its exchange office at 09:25
558
+ // Madrid time showed in China Post's leg at 09:25 +08:00, seven hours before Correos's own row of it.
559
+ const inbound = reported.key === CHINA_POST ? countryTimeZone(recipientCountry(shipment)) : null;
556
560
  const salvador = reported.key === CORREO_EL_SALVADOR;
557
561
  const sender = salvador && isValidS10TrackingNumber(number) ? countryTimeZone(number.slice(-2)) : null;
558
562
  const bound = reported.key === SWISS_POST ? recipientCountry(shipment) : null;
@@ -581,6 +585,7 @@ export function parse17TrackResponse(payload, trackingNumber, postcode = null) {
581
585
  if (undatedScan(raw))
582
586
  undated++;
583
587
  const exchange = origin !== null && outward.test(text(raw.description).trim());
588
+ const arrived = inbound !== null && chinaPostDestinationScan(text(raw.description));
584
589
  const own = !salvador ? null : OUTBOUND.test(text(raw.description)) ? sender : 'UTC';
585
590
  // The destination post's scan Swiss Post relays, its wall clock under Swiss Post's offset, or Huiyi Logistics' row in China under "+00:00".
586
591
  const relayed = bound ? swissPostDestinationZone(text(raw.description), text(raw.location), bound)
@@ -597,15 +602,15 @@ export function parse17TrackResponse(payload, trackingNumber, postcode = null) {
597
602
  const site = !ctt ? null : cttSiteZone(text(raw.location), countries)
598
603
  ?? (!text(raw.location) && agencyIntake(wallMillis(raw), agencyScans) ? 'Europe/Madrid' : null);
599
604
  // A facility's clock, CTT's, A1's UTC, NZ Post's, Poland Post's, FIC's partner's, Correos de El Salvador's, Correos de Chile's, Shiprocket's, DAI Post's, Quick Rabbit's or an origin post's, on which 17TRACK puts one offset for the whole parcel.
600
- const read = facility || site || relaysFacilityClock(name) || utc || nz || polish || handed || exchange || own || chile || shiprocket || daiPost || quickRabbit
601
- || sent !== undefined;
605
+ const read = facility || site || relaysFacilityClock(name) || utc || nz || polish || handed || exchange || arrived || own || chile || shiprocket || daiPost
606
+ || quickRabbit || sent !== undefined;
602
607
  // Any other row 17TRACK labelled with its zone's offset on the day it looks, not on the scan's.
603
608
  const season = relayed || hywl || read || poland ? null : seasonZone(raw, labelled, now);
604
609
  const wall = relayed || hywl ? rawClock(raw) : read || season ? facilityWall(raw) : null;
605
610
  // A label its mailer wrote on UTC, as USPS's adapter reads it.
606
611
  const scanned = facility && wall ? uspsRowZone(wall, facility, text(raw.description), now.toMillis()) : facility;
607
612
  const zone = !wall ? null : season ?? (hywl ? relayed : relayed ?? scanned ?? site ?? own ?? (sent !== undefined ? sent : abroad.has(index) ? abroad.get(index) ?? null
608
- : exchange ? origin : utc ? 'UTC' : polish ? polish : handed ? handed
613
+ : exchange ? origin : arrived ? inbound : utc ? 'UTC' : polish ? polish : handed ? handed
609
614
  : nz ? 'Pacific/Auckland' : quickRabbit ? 'Europe/Madrid' : chile ? facilityZone(text(raw.location)) ?? 'America/Santiago'
610
615
  : shiprocket ? (placedInIndia(text(raw.location)) ? 'Asia/Kolkata' : null)
611
616
  : daiPost ? daiPostRelayZone(text(raw.description), text(raw.location)) : facilityZone(text(raw.location))));
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.1.0",
3
3
  "info": {
4
4
  "title": "Universal Parcel Scraper",
5
- "version": "0.993.1-main.5347"
5
+ "version": "0.993.2-main.5350"
6
6
  },
7
7
  "paths": {
8
8
  "/health": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-parcel-scraper",
3
- "version": "0.993.1-main.5347",
3
+ "version": "0.993.2-main.5350",
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",