universal-parcel-scraper 0.734.2-main.3759 → 0.735.2-main.3769
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/data/catalog.json +21 -1
- package/data/detection-golden.json +51 -0
- package/dist/browser/scraper.js +41 -15
- package/dist/carriers/fedex/adapter.d.ts +2 -2
- package/dist/carriers/fedex/adapter.js +55 -5
- package/dist/carriers/fedex/identity.js +5 -1
- package/dist/carriers/foxpost/carrier.json +6 -0
- package/dist/carriers/foxpost/numbers.json +20 -0
- package/dist/carriers/foxpost/parser.d.ts +1 -1
- package/dist/carriers/foxpost/parser.js +6 -5
- package/dist/carriers/magyar-posta/carrier.json +12 -0
- package/dist/carriers/magyar-posta/numbers.json +44 -0
- package/dist/carriers/z-leading/carrier.json +7 -1
- package/dist/carriers/z-leading/numbers.json +17 -1
- package/dist/core/catalog/hints.js +3 -2
- package/dist/data/catalog.json +21 -1
- package/dist/generated/catalog.d.ts +16 -1
- package/dist/generated/catalog.js +24 -4
- package/dist/server/openapi.json +1 -1
- package/package.json +1 -1
package/data/catalog.json
CHANGED
|
@@ -14902,6 +14902,11 @@
|
|
|
14902
14902
|
{
|
|
14903
14903
|
"pattern": "^CLFOX\\d{15}$",
|
|
14904
14904
|
"confidence": "high"
|
|
14905
|
+
},
|
|
14906
|
+
{
|
|
14907
|
+
"pattern": "^66639\\d{5,15}$",
|
|
14908
|
+
"confidence": "low",
|
|
14909
|
+
"preferred": true
|
|
14905
14910
|
}
|
|
14906
14911
|
]
|
|
14907
14912
|
},
|
|
@@ -20625,6 +20630,16 @@
|
|
|
20625
20630
|
"confidence": "low",
|
|
20626
20631
|
"checksum": "magyar-posta",
|
|
20627
20632
|
"preferred": true
|
|
20633
|
+
},
|
|
20634
|
+
{
|
|
20635
|
+
"pattern": "^RL\\d{14}$",
|
|
20636
|
+
"confidence": "low",
|
|
20637
|
+
"preferred": true
|
|
20638
|
+
},
|
|
20639
|
+
{
|
|
20640
|
+
"pattern": "^JJH[A-Z0-9]{17}$",
|
|
20641
|
+
"confidence": "low",
|
|
20642
|
+
"preferred": true
|
|
20628
20643
|
}
|
|
20629
20644
|
]
|
|
20630
20645
|
},
|
|
@@ -32531,7 +32546,12 @@
|
|
|
32531
32546
|
},
|
|
32532
32547
|
"canaryUrl": "https://t.17track.net/",
|
|
32533
32548
|
"linkRules": [],
|
|
32534
|
-
"detectionRules": [
|
|
32549
|
+
"detectionRules": [
|
|
32550
|
+
{
|
|
32551
|
+
"pattern": "^ZL[A-Z]{2}\\d{9}$",
|
|
32552
|
+
"confidence": "low"
|
|
32553
|
+
}
|
|
32554
|
+
]
|
|
32535
32555
|
},
|
|
32536
32556
|
"zajil": {
|
|
32537
32557
|
"displayName": "Zajil Express",
|
|
@@ -50473,6 +50473,27 @@
|
|
|
50473
50473
|
"heppner"
|
|
50474
50474
|
]
|
|
50475
50475
|
},
|
|
50476
|
+
{
|
|
50477
|
+
"input": "6663900000001",
|
|
50478
|
+
"carrier": "unknown",
|
|
50479
|
+
"confidence": "low",
|
|
50480
|
+
"candidates": [
|
|
50481
|
+
"foxpost",
|
|
50482
|
+
"la-poste",
|
|
50483
|
+
"correos-chile",
|
|
50484
|
+
"delhivery",
|
|
50485
|
+
"yunda",
|
|
50486
|
+
"korea-post"
|
|
50487
|
+
],
|
|
50488
|
+
"preferred": [
|
|
50489
|
+
"foxpost"
|
|
50490
|
+
],
|
|
50491
|
+
"asked": [
|
|
50492
|
+
"foxpost",
|
|
50493
|
+
"la-poste",
|
|
50494
|
+
"delhivery"
|
|
50495
|
+
]
|
|
50496
|
+
},
|
|
50476
50497
|
{
|
|
50477
50498
|
"input": "6679804342",
|
|
50478
50499
|
"carrier": "unknown",
|
|
@@ -78103,6 +78124,17 @@
|
|
|
78103
78124
|
"posti"
|
|
78104
78125
|
]
|
|
78105
78126
|
},
|
|
78127
|
+
{
|
|
78128
|
+
"input": "JJH30AAAAAPL00000001",
|
|
78129
|
+
"carrier": "unknown",
|
|
78130
|
+
"confidence": "low",
|
|
78131
|
+
"candidates": [
|
|
78132
|
+
"magyar-posta"
|
|
78133
|
+
],
|
|
78134
|
+
"preferred": [
|
|
78135
|
+
"magyar-posta"
|
|
78136
|
+
]
|
|
78137
|
+
},
|
|
78106
78138
|
{
|
|
78107
78139
|
"input": "JJITA8UW1A2B345678",
|
|
78108
78140
|
"carrier": "poste-italiane",
|
|
@@ -87140,6 +87172,17 @@
|
|
|
87140
87172
|
"chronopost"
|
|
87141
87173
|
]
|
|
87142
87174
|
},
|
|
87175
|
+
{
|
|
87176
|
+
"input": "RL15050014358643",
|
|
87177
|
+
"carrier": "unknown",
|
|
87178
|
+
"confidence": "low",
|
|
87179
|
+
"candidates": [
|
|
87180
|
+
"magyar-posta"
|
|
87181
|
+
],
|
|
87182
|
+
"preferred": [
|
|
87183
|
+
"magyar-posta"
|
|
87184
|
+
]
|
|
87185
|
+
},
|
|
87143
87186
|
{
|
|
87144
87187
|
"input": "RL330279383MD",
|
|
87145
87188
|
"carrier": "intl-post",
|
|
@@ -94754,6 +94797,14 @@
|
|
|
94754
94797
|
"tnt-it"
|
|
94755
94798
|
]
|
|
94756
94799
|
},
|
|
94800
|
+
{
|
|
94801
|
+
"input": "ZLXX000000017",
|
|
94802
|
+
"carrier": "unknown",
|
|
94803
|
+
"confidence": "low",
|
|
94804
|
+
"candidates": [
|
|
94805
|
+
"z-leading"
|
|
94806
|
+
]
|
|
94807
|
+
},
|
|
94757
94808
|
{
|
|
94758
94809
|
"input": "ZND170922989053",
|
|
94759
94810
|
"carrier": "unknown",
|
package/dist/browser/scraper.js
CHANGED
|
@@ -11556,6 +11556,10 @@ var Ze = {
|
|
|
11556
11556
|
detectionRules: [{
|
|
11557
11557
|
pattern: "^CLFOX\\d{15}$",
|
|
11558
11558
|
confidence: "high"
|
|
11559
|
+
}, {
|
|
11560
|
+
pattern: "^66639\\d{5,15}$",
|
|
11561
|
+
confidence: "low",
|
|
11562
|
+
preferred: !0
|
|
11559
11563
|
}]
|
|
11560
11564
|
},
|
|
11561
11565
|
"franch-express": {
|
|
@@ -15788,17 +15792,30 @@ var Ze = {
|
|
|
15788
15792
|
pathPattern: "^/nyomkovetes/nyitooldal/?$",
|
|
15789
15793
|
params: ["searchvalue"]
|
|
15790
15794
|
}],
|
|
15791
|
-
detectionRules: [
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
|
|
15795
|
+
detectionRules: [
|
|
15796
|
+
{
|
|
15797
|
+
pattern: "^[A-Z]{2}\\d{9}HU$",
|
|
15798
|
+
confidence: "low",
|
|
15799
|
+
checksum: "s10",
|
|
15800
|
+
preferred: !0
|
|
15801
|
+
},
|
|
15802
|
+
{
|
|
15803
|
+
pattern: "^P[A-Z][0-9A-Z]{3}\\d{8}$",
|
|
15804
|
+
confidence: "low",
|
|
15805
|
+
checksum: "magyar-posta",
|
|
15806
|
+
preferred: !0
|
|
15807
|
+
},
|
|
15808
|
+
{
|
|
15809
|
+
pattern: "^RL\\d{14}$",
|
|
15810
|
+
confidence: "low",
|
|
15811
|
+
preferred: !0
|
|
15812
|
+
},
|
|
15813
|
+
{
|
|
15814
|
+
pattern: "^JJH[A-Z0-9]{17}$",
|
|
15815
|
+
confidence: "low",
|
|
15816
|
+
preferred: !0
|
|
15817
|
+
}
|
|
15818
|
+
]
|
|
15802
15819
|
},
|
|
15803
15820
|
mailamericas: {
|
|
15804
15821
|
displayName: "MailAmericas",
|
|
@@ -24568,7 +24585,10 @@ var Ze = {
|
|
|
24568
24585
|
},
|
|
24569
24586
|
canaryUrl: "https://t.17track.net/",
|
|
24570
24587
|
linkRules: [],
|
|
24571
|
-
detectionRules: [
|
|
24588
|
+
detectionRules: [{
|
|
24589
|
+
pattern: "^ZL[A-Z]{2}\\d{9}$",
|
|
24590
|
+
confidence: "low"
|
|
24591
|
+
}]
|
|
24572
24592
|
},
|
|
24573
24593
|
zajil: {
|
|
24574
24594
|
displayName: "Zajil Express",
|
|
@@ -25446,7 +25466,7 @@ var Ze = {
|
|
|
25446
25466
|
followmont: [],
|
|
25447
25467
|
"forward-air": [],
|
|
25448
25468
|
"forza-delivery": ["forza-delivery-1"],
|
|
25449
|
-
foxpost: ["foxpost-1"],
|
|
25469
|
+
foxpost: ["foxpost-1", "foxpost-home-delivery"],
|
|
25450
25470
|
"franch-express": [],
|
|
25451
25471
|
fukuyama: [],
|
|
25452
25472
|
gaash: [],
|
|
@@ -25608,7 +25628,12 @@ var Ze = {
|
|
|
25608
25628
|
"m-one": ["m-one-s10"],
|
|
25609
25629
|
"madhur-courier": [],
|
|
25610
25630
|
"maersk-ecommerce": ["maersk-ecommerce-1"],
|
|
25611
|
-
"magyar-posta": [
|
|
25631
|
+
"magyar-posta": [
|
|
25632
|
+
"magyar-posta-s10",
|
|
25633
|
+
"magyar-posta-domestic",
|
|
25634
|
+
"magyar-posta-letter",
|
|
25635
|
+
"magyar-posta-europe-standard"
|
|
25636
|
+
],
|
|
25612
25637
|
mailamericas: [
|
|
25613
25638
|
"mailamericas-ml",
|
|
25614
25639
|
"mailamericas-mmxqp",
|
|
@@ -25939,7 +25964,7 @@ var Ze = {
|
|
|
25939
25964
|
"yurtici-kargo": [],
|
|
25940
25965
|
ywe: ["ywe-1"],
|
|
25941
25966
|
yypost: ["yypost-1"],
|
|
25942
|
-
"z-leading": [],
|
|
25967
|
+
"z-leading": ["z-leading-1"],
|
|
25943
25968
|
zajil: [],
|
|
25944
25969
|
zeleris: ["zeleris-1"],
|
|
25945
25970
|
zheldor: [],
|
|
@@ -31286,6 +31311,7 @@ var Rl = /* @__PURE__ */ new Map([
|
|
|
31286
31311
|
["DE", "dhl"],
|
|
31287
31312
|
["DK", "postnord"],
|
|
31288
31313
|
["DZ", "algerie-poste"],
|
|
31314
|
+
["EE", "omniva"],
|
|
31289
31315
|
["EG", "egypt-post"],
|
|
31290
31316
|
["ES", "correos-spain"],
|
|
31291
31317
|
["FI", "posti"],
|
|
@@ -6,13 +6,13 @@ import { type FedExApiCredentials } from './api.js';
|
|
|
6
6
|
export declare function normalizeFedExTrackingNumber(raw: string): string;
|
|
7
7
|
export declare function fedexTrackingUrl(trackingNumber: string): string;
|
|
8
8
|
/** The structured answer of the tracking page's own API call. */
|
|
9
|
-
export declare function parseFedExTrackingResponse(payload: unknown, trackingNumber: string): CarrierResult;
|
|
9
|
+
export declare function parseFedExTrackingResponse(payload: unknown, trackingNumber: string, readAt?: number): CarrierResult;
|
|
10
10
|
/**
|
|
11
11
|
* The official Track API's answer (`POST /track/v1/trackingnumbers`). It reads
|
|
12
12
|
* the scans, the latest status, the delivery dates and the hold location; the
|
|
13
13
|
* recipient, shipper, signatory, package and service blocks are never read.
|
|
14
14
|
*/
|
|
15
|
-
export declare function parseFedExApiResponse(payload: unknown, trackingNumber: string): CarrierResult;
|
|
15
|
+
export declare function parseFedExApiResponse(payload: unknown, trackingNumber: string, readAt?: number): CarrierResult;
|
|
16
16
|
/**
|
|
17
17
|
* The page the browser rendered, read only to tell a bot challenge from an
|
|
18
18
|
* inconclusive load. The page renders its "can't find that tracking number"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { load } from 'cheerio';
|
|
2
|
+
import { DateTime } from 'luxon';
|
|
2
3
|
import { recognizeFromBrowserLookup } from '../../core/adapter/index.js';
|
|
3
4
|
import { fillPartialAnswer } from '../../core/result/partial.js';
|
|
4
5
|
import { fedexBarcodeTrackingNumber, fedexGroundEconomyUspsNumber } from '../../core/detection/fedex.js';
|
|
@@ -6,7 +7,7 @@ import { uspsPackageIdentifier } from '../../core/detection/usps.js';
|
|
|
6
7
|
import { ChallengeError, InputRequiredError, InvalidInputError, RateLimitedError, SchemaError, TransportError, UpstreamHttpError, } from '../../core/errors/index.js';
|
|
7
8
|
import { runSteps } from '../../core/runner/index.js';
|
|
8
9
|
import { NOOP_RECORDER } from '../../core/telemetry/index.js';
|
|
9
|
-
import { calendarDay, explicitOffsetTime } from '../../core/time/index.js';
|
|
10
|
+
import { calendarDay, canadaProvinceTimeZone, countryTimeZone, explicitOffsetTime, firstOccurrence, usStateTimeZone, } from '../../core/time/index.js';
|
|
10
11
|
import { clean, cleanScalar, TRAWL_TRANSPORT_ALLOWANCE_MS } from '../../core/transport/index.js';
|
|
11
12
|
import { isRecord } from '../../core/types.js';
|
|
12
13
|
import { FedExApiClient, fedexApiCredentials } from './api.js';
|
|
@@ -85,6 +86,55 @@ function scanClock(scan) {
|
|
|
85
86
|
? calendarDay(Number(day[1]), Number(day[2]), Number(day[3])) : null;
|
|
86
87
|
return local ? { local_time: local } : {};
|
|
87
88
|
}
|
|
89
|
+
// US states and Canadian provinces with places on more than one clock, and the
|
|
90
|
+
// countries whose islands keep another clock than the mainland zone they are given.
|
|
91
|
+
const SEVERAL_CLOCKS = new Set(['AK', 'FL', 'ID', 'IN', 'KS', 'KY', 'MI', 'ND', 'NE', 'NV', 'OR', 'SD', 'TN', 'TX',
|
|
92
|
+
'BC', 'NL', 'NU', 'ON', 'QC', 'ES', 'PT']);
|
|
93
|
+
/** The zone of a place that keeps one clock: its country's, or its US state's or Canadian province's. */
|
|
94
|
+
function placeZone(country, region) {
|
|
95
|
+
if (country === 'US')
|
|
96
|
+
return SEVERAL_CLOCKS.has(region) ? null : usStateTimeZone(region);
|
|
97
|
+
if (country === 'CA')
|
|
98
|
+
return SEVERAL_CLOCKS.has(region) ? null : canadaProvinceTimeZone(region);
|
|
99
|
+
return SEVERAL_CLOCKS.has(country) ? null : countryTimeZone(country);
|
|
100
|
+
}
|
|
101
|
+
/** The page names a US or Canadian scan's state ("MEMPHIS, TN") and any other scan's country ("BOLOGNA IT"). */
|
|
102
|
+
function pageZone(location) {
|
|
103
|
+
const [, comma, code] = /(,?) ([A-Z]{2})$/.exec(location) ?? [];
|
|
104
|
+
if (!code)
|
|
105
|
+
return null;
|
|
106
|
+
if (comma && usStateTimeZone(code))
|
|
107
|
+
return placeZone('US', code);
|
|
108
|
+
if (comma && canadaProvinceTimeZone(code))
|
|
109
|
+
return placeZone('CA', code);
|
|
110
|
+
return placeZone(code, '');
|
|
111
|
+
}
|
|
112
|
+
function apiZone(value) {
|
|
113
|
+
if (!isRecord(value))
|
|
114
|
+
return null;
|
|
115
|
+
return placeZone(cleanScalar(value.countryCode).toUpperCase(), cleanScalar(value.stateOrProvinceCode).toUpperCase());
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* FedEx labels a scan it records after a clock change with the offset its
|
|
119
|
+
* place has kept since, even when the scan came before: a hub's departure the
|
|
120
|
+
* evening before October's change came as +01:00 among scans it had recorded
|
|
121
|
+
* in time as +02:00. A label that is the place's offset at `readAt` but not at
|
|
122
|
+
* the scan's wall clock is put back on the place's clock. A wall clock the
|
|
123
|
+
* place repeats or skips keeps its label.
|
|
124
|
+
*/
|
|
125
|
+
function placeClock(clock, zone, readAt) {
|
|
126
|
+
const shown = clock.time && zone ? DateTime.fromISO(clock.time, { setZone: true }) : null;
|
|
127
|
+
if (!zone || !shown?.isValid || DateTime.fromMillis(readAt, { zone }).offset !== shown.offset)
|
|
128
|
+
return clock;
|
|
129
|
+
const { year, month, day, hour, minute, second } = shown;
|
|
130
|
+
const own = firstOccurrence(DateTime.fromObject({ year, month, day, hour, minute, second }, { zone }));
|
|
131
|
+
if (!own.isValid || own.hour !== hour || own.minute !== minute)
|
|
132
|
+
return clock;
|
|
133
|
+
if (own.getPossibleOffsets().some((possible) => possible.offset === shown.offset))
|
|
134
|
+
return clock;
|
|
135
|
+
const time = own.toISO({ suppressMilliseconds: true });
|
|
136
|
+
return time ? { ...clock, time } : clock;
|
|
137
|
+
}
|
|
88
138
|
/**
|
|
89
139
|
* Newest first. A scan with a time sorts by its instant, since each carries
|
|
90
140
|
* its own offset, and one without a clock comes last. A scan dated by its day
|
|
@@ -259,7 +309,7 @@ function shipmentResult(shipment, number) {
|
|
|
259
309
|
};
|
|
260
310
|
}
|
|
261
311
|
/** The structured answer of the tracking page's own API call. */
|
|
262
|
-
export function parseFedExTrackingResponse(payload, trackingNumber) {
|
|
312
|
+
export function parseFedExTrackingResponse(payload, trackingNumber, readAt = Date.now()) {
|
|
263
313
|
const number = normalizeFedExTrackingNumber(trackingNumber);
|
|
264
314
|
if (!isRecord(payload) || !isRecord(payload.output)) {
|
|
265
315
|
throw new SchemaError('FedEx', 'FedEx returned an invalid tracking response');
|
|
@@ -303,7 +353,7 @@ export function parseFedExTrackingResponse(payload, trackingNumber) {
|
|
|
303
353
|
description: scanDescription(clean(raw.status), clean(raw.scanDetails)),
|
|
304
354
|
wording: `${clean(raw.status)} ${clean(raw.scanDetails)}`,
|
|
305
355
|
code: cleanScalar(raw.statusCD).toLocaleUpperCase('en-US'),
|
|
306
|
-
clock: scanClock(raw),
|
|
356
|
+
clock: placeClock(scanClock(raw), pageZone(clean(raw.scanLocation)), readAt),
|
|
307
357
|
location: clean(raw.scanLocation),
|
|
308
358
|
})),
|
|
309
359
|
statusText: keyStatus,
|
|
@@ -329,7 +379,7 @@ function apiDate(result, ...types) {
|
|
|
329
379
|
* the scans, the latest status, the delivery dates and the hold location; the
|
|
330
380
|
* recipient, shipper, signatory, package and service blocks are never read.
|
|
331
381
|
*/
|
|
332
|
-
export function parseFedExApiResponse(payload, trackingNumber) {
|
|
382
|
+
export function parseFedExApiResponse(payload, trackingNumber, readAt = Date.now()) {
|
|
333
383
|
const number = normalizeFedExTrackingNumber(trackingNumber);
|
|
334
384
|
const complete = isRecord(payload) && isRecord(payload.output) && Array.isArray(payload.output.completeTrackResults)
|
|
335
385
|
? payload.output.completeTrackResults.filter(isRecord) : null;
|
|
@@ -369,7 +419,7 @@ export function parseFedExApiResponse(payload, trackingNumber) {
|
|
|
369
419
|
description: scanDescription(clean(raw.eventDescription), clean(raw.exceptionDescription)),
|
|
370
420
|
wording: `${clean(raw.eventDescription)} ${clean(raw.exceptionDescription)}`,
|
|
371
421
|
code: cleanScalar(raw.eventType).toLocaleUpperCase('en-US'),
|
|
372
|
-
clock: apiClock(raw.date),
|
|
422
|
+
clock: placeClock(apiClock(raw.date), apiZone(raw.scanLocation), readAt),
|
|
373
423
|
location: apiPlace(raw.scanLocation),
|
|
374
424
|
})),
|
|
375
425
|
statusText,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// The official API and the tracking page's own reply can word or place one
|
|
2
2
|
// scan differently. A scan read from one takes over the row the other stored
|
|
3
|
-
// at its instant when both read it as the same step.
|
|
3
|
+
// at its instant when both read it as the same step. FedEx labels a scan it
|
|
4
|
+
// records after a clock change with the offset its place took then, which an
|
|
5
|
+
// earlier release stored, so a scan read on its place's own clock takes over
|
|
6
|
+
// the row that shows its wall clock under the other offset.
|
|
4
7
|
export const sameInstantIdentityPolicy = {
|
|
5
8
|
sourceCarrierId: 'fedex', storedSources: ['fedex'], requireProviderCode: false,
|
|
6
9
|
matches: (incoming, stored) => incoming.stage === stored.stage,
|
|
10
|
+
matchWallClock: true,
|
|
7
11
|
};
|
|
@@ -228,6 +228,26 @@
|
|
|
228
228
|
"confidence": "high"
|
|
229
229
|
},
|
|
230
230
|
"note": "Looked up on Foxpost's own tracker, as an archived address shows; the capture was not opened."
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"number": "6663900000001",
|
|
234
|
+
"role": "shipment",
|
|
235
|
+
"evidence": "synthetic",
|
|
236
|
+
"derivedFrom": "official_shape",
|
|
237
|
+
"shapeConfirmed": "2026-10-25",
|
|
238
|
+
"expect": {
|
|
239
|
+
"carrier": "unknown",
|
|
240
|
+
"confidence": "low",
|
|
241
|
+
"candidates": [
|
|
242
|
+
"foxpost",
|
|
243
|
+
"la-poste",
|
|
244
|
+
"correos-chile",
|
|
245
|
+
"delhivery",
|
|
246
|
+
"yunda",
|
|
247
|
+
"korea-post"
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
"note": "Made-up number with the prefix Foxpost's tracking page and help give its home deliveries. No source gives their length; Foxpost's API caps a parcel's barcode at twenty characters."
|
|
231
251
|
}
|
|
232
252
|
]
|
|
233
253
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CarrierResult } from '../../core/result/index.js';
|
|
2
2
|
export declare const PROVIDER = "Foxpost";
|
|
3
|
-
/** A CLFOX parcel ID, a Z number
|
|
3
|
+
/** A CLFOX parcel ID, a Z number, a ten-digit number starting 66 or a home delivery's 66639 number, as Foxpost's tracker takes them. */
|
|
4
4
|
export declare function normalizeFoxpostNumber(raw: string): string;
|
|
5
5
|
/**
|
|
6
6
|
* The tracker's reply for one parcel: its scans and the locker it waits at.
|
|
@@ -9,9 +9,10 @@ import { firstOccurrence } from '../../core/time/index.js';
|
|
|
9
9
|
import { clean } from '../../core/transport/index.js';
|
|
10
10
|
import { foxpostScanStage } from './status.js';
|
|
11
11
|
export const PROVIDER = 'Foxpost';
|
|
12
|
-
// A Foxpost parcel ID, a Packeta number the tracker also answers for,
|
|
13
|
-
// ten-digit IDs starting 66 it issues as well
|
|
14
|
-
|
|
12
|
+
// A Foxpost parcel ID, a Packeta number the tracker also answers for, the
|
|
13
|
+
// ten-digit IDs starting 66 it issues as well, and its home deliveries' numbers
|
|
14
|
+
// starting 66639, of up to the twenty characters its API allows a barcode.
|
|
15
|
+
const NUMBER = /^(?:CLFOX\d{15}|Z\d{10}|66\d{8}|66639\d{5,15})$/;
|
|
15
16
|
// The page's answer for a number it does not know.
|
|
16
17
|
const ABSENT = /^A megadott csomag azonosító nem található a rendszerünkben\b/;
|
|
17
18
|
const CLOCK = /^(\d{4})\.(\d{2})\.(\d{2}) (\d{2}):(\d{2})$/;
|
|
@@ -20,11 +21,11 @@ const POINT_PAGE = /^\/~\/[A-Za-z0-9_-]{1,40}$/;
|
|
|
20
21
|
const ZONE = 'Europe/Budapest';
|
|
21
22
|
const MAX_ROWS = 200;
|
|
22
23
|
const MAX_EVENTS = 100;
|
|
23
|
-
/** A CLFOX parcel ID, a Z number
|
|
24
|
+
/** A CLFOX parcel ID, a Z number, a ten-digit number starting 66 or a home delivery's 66639 number, as Foxpost's tracker takes them. */
|
|
24
25
|
export function normalizeFoxpostNumber(raw) {
|
|
25
26
|
const number = normalizeTrackingNumber(raw);
|
|
26
27
|
if (!NUMBER.test(number)) {
|
|
27
|
-
throw new InvalidInputError(PROVIDER, 'Foxpost tracks CLFOX parcel IDs, Z numbers
|
|
28
|
+
throw new InvalidInputError(PROVIDER, 'Foxpost tracks CLFOX parcel IDs, Z numbers, ten-digit numbers starting 66 and home deliveries\' numbers starting 66639');
|
|
28
29
|
}
|
|
29
30
|
return number;
|
|
30
31
|
}
|
|
@@ -106,6 +106,18 @@
|
|
|
106
106
|
"confidence": "low",
|
|
107
107
|
"preferred": true,
|
|
108
108
|
"checksum": "magyar-posta"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"id": "magyar-posta-letter",
|
|
112
|
+
"pattern": "^RL\\d{14}$",
|
|
113
|
+
"confidence": "low",
|
|
114
|
+
"preferred": true
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "magyar-posta-europe-standard",
|
|
118
|
+
"pattern": "^JJH[A-Z0-9]{17}$",
|
|
119
|
+
"confidence": "low",
|
|
120
|
+
"preferred": true
|
|
109
121
|
}
|
|
110
122
|
]
|
|
111
123
|
}
|
|
@@ -269,6 +269,50 @@
|
|
|
269
269
|
]
|
|
270
270
|
},
|
|
271
271
|
"note": "Magyar Posta's tracking API guide lists it in an example reply; it is not described as a live shipment."
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"number": "RL15050014358643",
|
|
275
|
+
"role": "shipment",
|
|
276
|
+
"evidence": "public_shipment_report",
|
|
277
|
+
"source": {
|
|
278
|
+
"url": "https://web.archive.org/web/20220727091109/https://www.posta.hu/nyomkovetes/nyitooldal?searchvalue=RL15050014358643",
|
|
279
|
+
"date": "2022-07-27",
|
|
280
|
+
"dateKind": "capture",
|
|
281
|
+
"access": "full_page"
|
|
282
|
+
},
|
|
283
|
+
"context": {
|
|
284
|
+
"service": "domestic registered letter",
|
|
285
|
+
"assessment": "candidate"
|
|
286
|
+
},
|
|
287
|
+
"expect": {
|
|
288
|
+
"carrier": "unknown",
|
|
289
|
+
"confidence": "low",
|
|
290
|
+
"candidates": [
|
|
291
|
+
"magyar-posta"
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
"note": "Looked up on Magyar Posta's tracker, as an archived address shows; the capture holds only the search form. The tracker names the RL series as its domestic letters, sixteen characters long."
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
"number": "JJH30AAAAAPL00000001",
|
|
298
|
+
"role": "shipment",
|
|
299
|
+
"evidence": "official_documentation_example",
|
|
300
|
+
"source": {
|
|
301
|
+
"url": "https://www.posta.hu/ikrnyomkovproxy/",
|
|
302
|
+
"access": "full_page"
|
|
303
|
+
},
|
|
304
|
+
"context": {
|
|
305
|
+
"service": "MPL Europe Standard",
|
|
306
|
+
"assessment": "candidate"
|
|
307
|
+
},
|
|
308
|
+
"expect": {
|
|
309
|
+
"carrier": "unknown",
|
|
310
|
+
"confidence": "low",
|
|
311
|
+
"candidates": [
|
|
312
|
+
"magyar-posta"
|
|
313
|
+
]
|
|
314
|
+
},
|
|
315
|
+
"note": "Magyar Posta's tracker gives it as the example of an MPL Europe Standard (DHL) parcel number; it is not described as a live shipment."
|
|
272
316
|
}
|
|
273
317
|
]
|
|
274
318
|
}
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"carrier": "z-leading",
|
|
3
3
|
"gap": "No public page shows a whole Z-Leading tracking number.",
|
|
4
|
-
"records": [
|
|
4
|
+
"records": [
|
|
5
|
+
{
|
|
6
|
+
"number": "ZLXX000000017",
|
|
7
|
+
"role": "shipment",
|
|
8
|
+
"evidence": "synthetic",
|
|
9
|
+
"derivedFrom": "donated_real",
|
|
10
|
+
"shapeConfirmed": "2026-10-25",
|
|
11
|
+
"expect": {
|
|
12
|
+
"carrier": "unknown",
|
|
13
|
+
"confidence": "low",
|
|
14
|
+
"candidates": [
|
|
15
|
+
"z-leading"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"note": "Made-up number in the shape of a parcel the app tracked, which two universal providers filed under Zhongling."
|
|
19
|
+
}
|
|
20
|
+
]
|
|
5
21
|
}
|
|
@@ -59,13 +59,14 @@ const CATALOG_NAMES = new Set([
|
|
|
59
59
|
// from France, and dates its own scans on Taiwan time. Pošta Srbije, Pošta
|
|
60
60
|
// Slovenije, Cyprus Post, MaltaPost, POST Luxembourg and Magyar Posta follow mail
|
|
61
61
|
// from abroad under the sending post's number; Magyar Posta's lookup opens a
|
|
62
|
-
// browser.
|
|
62
|
+
// browser. Omniva's tracker carries the scans in Estonia of mail from abroad,
|
|
63
|
+
// on UTC clocks. The host also checks adapter availability and required inputs before
|
|
63
64
|
// making a request.
|
|
64
65
|
const NATIONAL_POSTS = new Map([
|
|
65
66
|
['AM', 'haypost'], ['AR', 'correo-argentino'], ['AT', 'austrian-post'], ['AU', 'australia-post'], ['BD', 'bangladesh-post'],
|
|
66
67
|
['BE', 'bpost'], ['BG', 'bulgarian-posts'], ['BR', 'correios-br'], ['BY', 'belpost'], ['CA', 'canada-post'],
|
|
67
68
|
['CH', 'swiss-post'], ['CU', 'correos-cuba'], ['CY', 'cyprus-post'], ['CZ', 'ceska-posta'], ['DE', 'dhl'], ['DK', 'postnord'], ['DZ', 'algerie-poste'],
|
|
68
|
-
['EG', 'egypt-post'], ['ES', 'correos-spain'], ['FI', 'posti'], ['FO', 'posta-faroe'], ['FR', 'la-poste'],
|
|
69
|
+
['EE', 'omniva'], ['EG', 'egypt-post'], ['ES', 'correos-spain'], ['FI', 'posti'], ['FO', 'posta-faroe'], ['FR', 'la-poste'],
|
|
69
70
|
['GB', 'royal-mail'], ['GR', 'elta'], ['HR', 'hrvatska-posta'], ['HU', 'magyar-posta'], ['IE', 'an-post'], ['IS', 'posturinn'],
|
|
70
71
|
['IT', 'poste-italiane'], ['JO', 'jordan-post'], ['JP', 'japan-post'], ['KE', 'posta-kenya'], ['LT', 'lietuvos-pastas'],
|
|
71
72
|
['LU', 'post-luxembourg'], ['LV', 'latvijas-pasts'], ['MA', 'barid-al-maghrib'], ['MK', 'posta-north-macedonia'], ['MT', 'maltapost'],
|
package/dist/data/catalog.json
CHANGED
|
@@ -14902,6 +14902,11 @@
|
|
|
14902
14902
|
{
|
|
14903
14903
|
"pattern": "^CLFOX\\d{15}$",
|
|
14904
14904
|
"confidence": "high"
|
|
14905
|
+
},
|
|
14906
|
+
{
|
|
14907
|
+
"pattern": "^66639\\d{5,15}$",
|
|
14908
|
+
"confidence": "low",
|
|
14909
|
+
"preferred": true
|
|
14905
14910
|
}
|
|
14906
14911
|
]
|
|
14907
14912
|
},
|
|
@@ -20625,6 +20630,16 @@
|
|
|
20625
20630
|
"confidence": "low",
|
|
20626
20631
|
"checksum": "magyar-posta",
|
|
20627
20632
|
"preferred": true
|
|
20633
|
+
},
|
|
20634
|
+
{
|
|
20635
|
+
"pattern": "^RL\\d{14}$",
|
|
20636
|
+
"confidence": "low",
|
|
20637
|
+
"preferred": true
|
|
20638
|
+
},
|
|
20639
|
+
{
|
|
20640
|
+
"pattern": "^JJH[A-Z0-9]{17}$",
|
|
20641
|
+
"confidence": "low",
|
|
20642
|
+
"preferred": true
|
|
20628
20643
|
}
|
|
20629
20644
|
]
|
|
20630
20645
|
},
|
|
@@ -32531,7 +32546,12 @@
|
|
|
32531
32546
|
},
|
|
32532
32547
|
"canaryUrl": "https://t.17track.net/",
|
|
32533
32548
|
"linkRules": [],
|
|
32534
|
-
"detectionRules": [
|
|
32549
|
+
"detectionRules": [
|
|
32550
|
+
{
|
|
32551
|
+
"pattern": "^ZL[A-Z]{2}\\d{9}$",
|
|
32552
|
+
"confidence": "low"
|
|
32553
|
+
}
|
|
32554
|
+
]
|
|
32535
32555
|
},
|
|
32536
32556
|
"zajil": {
|
|
32537
32557
|
"displayName": "Zajil Express",
|
|
@@ -9664,6 +9664,10 @@ export declare const CARRIER_CATALOG: {
|
|
|
9664
9664
|
readonly detectionRules: readonly [{
|
|
9665
9665
|
readonly pattern: "^CLFOX\\d{15}$";
|
|
9666
9666
|
readonly confidence: "high";
|
|
9667
|
+
}, {
|
|
9668
|
+
readonly pattern: "^66639\\d{5,15}$";
|
|
9669
|
+
readonly confidence: "low";
|
|
9670
|
+
readonly preferred: true;
|
|
9667
9671
|
}];
|
|
9668
9672
|
};
|
|
9669
9673
|
readonly "franch-express": {
|
|
@@ -13288,6 +13292,14 @@ export declare const CARRIER_CATALOG: {
|
|
|
13288
13292
|
readonly confidence: "low";
|
|
13289
13293
|
readonly checksum: "magyar-posta";
|
|
13290
13294
|
readonly preferred: true;
|
|
13295
|
+
}, {
|
|
13296
|
+
readonly pattern: "^RL\\d{14}$";
|
|
13297
|
+
readonly confidence: "low";
|
|
13298
|
+
readonly preferred: true;
|
|
13299
|
+
}, {
|
|
13300
|
+
readonly pattern: "^JJH[A-Z0-9]{17}$";
|
|
13301
|
+
readonly confidence: "low";
|
|
13302
|
+
readonly preferred: true;
|
|
13291
13303
|
}];
|
|
13292
13304
|
};
|
|
13293
13305
|
readonly mailamericas: {
|
|
@@ -20790,7 +20802,10 @@ export declare const CARRIER_CATALOG: {
|
|
|
20790
20802
|
};
|
|
20791
20803
|
readonly canaryUrl: "https://t.17track.net/";
|
|
20792
20804
|
readonly linkRules: readonly [];
|
|
20793
|
-
readonly detectionRules: readonly [
|
|
20805
|
+
readonly detectionRules: readonly [{
|
|
20806
|
+
readonly pattern: "^ZL[A-Z]{2}\\d{9}$";
|
|
20807
|
+
readonly confidence: "low";
|
|
20808
|
+
}];
|
|
20794
20809
|
};
|
|
20795
20810
|
readonly zajil: {
|
|
20796
20811
|
readonly displayName: "Zajil Express";
|
|
@@ -14903,6 +14903,11 @@ export const CARRIER_CATALOG = {
|
|
|
14903
14903
|
{
|
|
14904
14904
|
"pattern": "^CLFOX\\d{15}$",
|
|
14905
14905
|
"confidence": "high"
|
|
14906
|
+
},
|
|
14907
|
+
{
|
|
14908
|
+
"pattern": "^66639\\d{5,15}$",
|
|
14909
|
+
"confidence": "low",
|
|
14910
|
+
"preferred": true
|
|
14906
14911
|
}
|
|
14907
14912
|
]
|
|
14908
14913
|
},
|
|
@@ -20626,6 +20631,16 @@ export const CARRIER_CATALOG = {
|
|
|
20626
20631
|
"confidence": "low",
|
|
20627
20632
|
"checksum": "magyar-posta",
|
|
20628
20633
|
"preferred": true
|
|
20634
|
+
},
|
|
20635
|
+
{
|
|
20636
|
+
"pattern": "^RL\\d{14}$",
|
|
20637
|
+
"confidence": "low",
|
|
20638
|
+
"preferred": true
|
|
20639
|
+
},
|
|
20640
|
+
{
|
|
20641
|
+
"pattern": "^JJH[A-Z0-9]{17}$",
|
|
20642
|
+
"confidence": "low",
|
|
20643
|
+
"preferred": true
|
|
20629
20644
|
}
|
|
20630
20645
|
]
|
|
20631
20646
|
},
|
|
@@ -32532,7 +32547,12 @@ export const CARRIER_CATALOG = {
|
|
|
32532
32547
|
},
|
|
32533
32548
|
"canaryUrl": "https://t.17track.net/",
|
|
32534
32549
|
"linkRules": [],
|
|
32535
|
-
"detectionRules": [
|
|
32550
|
+
"detectionRules": [
|
|
32551
|
+
{
|
|
32552
|
+
"pattern": "^ZL[A-Z]{2}\\d{9}$",
|
|
32553
|
+
"confidence": "low"
|
|
32554
|
+
}
|
|
32555
|
+
]
|
|
32536
32556
|
},
|
|
32537
32557
|
"zajil": {
|
|
32538
32558
|
"displayName": "Zajil Express",
|
|
@@ -33919,7 +33939,7 @@ export const DETECTION_RULE_IDS = {
|
|
|
33919
33939
|
"followmont": [],
|
|
33920
33940
|
"forward-air": [],
|
|
33921
33941
|
"forza-delivery": ["forza-delivery-1"],
|
|
33922
|
-
"foxpost": ["foxpost-1"],
|
|
33942
|
+
"foxpost": ["foxpost-1", "foxpost-home-delivery"],
|
|
33923
33943
|
"franch-express": [],
|
|
33924
33944
|
"fukuyama": [],
|
|
33925
33945
|
"gaash": [],
|
|
@@ -34068,7 +34088,7 @@ export const DETECTION_RULE_IDS = {
|
|
|
34068
34088
|
"m-one": ["m-one-s10"],
|
|
34069
34089
|
"madhur-courier": [],
|
|
34070
34090
|
"maersk-ecommerce": ["maersk-ecommerce-1"],
|
|
34071
|
-
"magyar-posta": ["magyar-posta-s10", "magyar-posta-domestic"],
|
|
34091
|
+
"magyar-posta": ["magyar-posta-s10", "magyar-posta-domestic", "magyar-posta-letter", "magyar-posta-europe-standard"],
|
|
34072
34092
|
"mailamericas": ["mailamericas-ml", "mailamericas-mmxqp", "mailamericas-domc", "mailamericas-s10"],
|
|
34073
34093
|
"mailplus-au": ["mailplus-au-1"],
|
|
34074
34094
|
"mainfreight": ["mainfreight-1"],
|
|
@@ -34369,7 +34389,7 @@ export const DETECTION_RULE_IDS = {
|
|
|
34369
34389
|
"yurtici-kargo": [],
|
|
34370
34390
|
"ywe": ["ywe-1"],
|
|
34371
34391
|
"yypost": ["yypost-1"],
|
|
34372
|
-
"z-leading": [],
|
|
34392
|
+
"z-leading": ["z-leading-1"],
|
|
34373
34393
|
"zajil": [],
|
|
34374
34394
|
"zeleris": ["zeleris-1"],
|
|
34375
34395
|
"zheldor": [],
|
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.735.2-main.3769",
|
|
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",
|