universal-parcel-scraper 0.331.0-main.1889 → 0.331.0-main.1890
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 +2 -1
- package/dist/browser/scraper.js +2 -1
- package/dist/carriers/dhlink/carrier.json +2 -1
- package/dist/data/catalog.json +2 -1
- package/dist/generated/catalog.d.ts +1 -1
- package/dist/generated/catalog.js +2 -1
- package/dist/providers/shared/hints.d.ts +3 -1
- package/dist/providers/shared/hints.js +26 -8
- package/package.json +1 -1
package/data/catalog.json
CHANGED
|
@@ -10242,7 +10242,8 @@
|
|
|
10242
10242
|
"DHLink",
|
|
10243
10243
|
"Dhlink",
|
|
10244
10244
|
"驼飞侠",
|
|
10245
|
-
"駝飛俠"
|
|
10245
|
+
"駝飛俠",
|
|
10246
|
+
"XZG"
|
|
10246
10247
|
],
|
|
10247
10248
|
"countries": [
|
|
10248
10249
|
"CN"
|
package/dist/browser/scraper.js
CHANGED
package/dist/data/catalog.json
CHANGED
|
@@ -10242,7 +10242,8 @@
|
|
|
10242
10242
|
"DHLink",
|
|
10243
10243
|
"Dhlink",
|
|
10244
10244
|
"驼飞侠",
|
|
10245
|
-
"駝飛俠"
|
|
10245
|
+
"駝飛俠",
|
|
10246
|
+
"XZG"
|
|
10246
10247
|
],
|
|
10247
10248
|
"countries": [
|
|
10248
10249
|
"CN"
|
|
@@ -6662,7 +6662,7 @@ export declare const CARRIER_CATALOG: {
|
|
|
6662
6662
|
readonly dhlink: {
|
|
6663
6663
|
readonly displayName: "DHLink";
|
|
6664
6664
|
readonly color: "#143167";
|
|
6665
|
-
readonly aliases: readonly ["DHLink", "Dhlink", "驼飞侠", "駝飛俠"];
|
|
6665
|
+
readonly aliases: readonly ["DHLink", "Dhlink", "驼飞侠", "駝飛俠", "XZG"];
|
|
6666
6666
|
readonly countries: readonly ["CN"];
|
|
6667
6667
|
readonly selectable: true;
|
|
6668
6668
|
readonly timezone: "Asia/Shanghai";
|
|
@@ -10243,7 +10243,8 @@ export const CARRIER_CATALOG = {
|
|
|
10243
10243
|
"DHLink",
|
|
10244
10244
|
"Dhlink",
|
|
10245
10245
|
"驼飞侠",
|
|
10246
|
-
"駝飛俠"
|
|
10246
|
+
"駝飛俠",
|
|
10247
|
+
"XZG"
|
|
10247
10248
|
],
|
|
10248
10249
|
"countries": [
|
|
10249
10250
|
"CN"
|
|
@@ -25,7 +25,9 @@ export declare const ADAPTER_CHECKED_RULES: ReadonlySet<string>;
|
|
|
25
25
|
* Evri International's tracker) names the partner whose rule claims it.
|
|
26
26
|
* Several names that all map to the catalog can be one journey's legs; see
|
|
27
27
|
* `journeyOwner`. Beside Cainiao, a bare brand names its network that
|
|
28
|
-
* delivers at home.
|
|
28
|
+
* delivers at home. A bare brand none of whose networks fits the number names
|
|
29
|
+
* a group, such as "DPD Group" beside BRT, its network in Italy: beside a
|
|
30
|
+
* carrier whose rule fits the number, it leaves that carrier's hint.
|
|
29
31
|
*/
|
|
30
32
|
export declare function universalCarrierHints(raw: unknown[], trackingNumber?: string): {
|
|
31
33
|
reported_carriers: string[];
|
|
@@ -63,50 +63,68 @@ const NAME_CHECKED_RULES = new Set(['fedex-1']);
|
|
|
63
63
|
* Evri International's tracker) names the partner whose rule claims it.
|
|
64
64
|
* Several names that all map to the catalog can be one journey's legs; see
|
|
65
65
|
* `journeyOwner`. Beside Cainiao, a bare brand names its network that
|
|
66
|
-
* delivers at home.
|
|
66
|
+
* delivers at home. A bare brand none of whose networks fits the number names
|
|
67
|
+
* a group, such as "DPD Group" beside BRT, its network in Italy: beside a
|
|
68
|
+
* carrier whose rule fits the number, it leaves that carrier's hint.
|
|
67
69
|
*/
|
|
68
70
|
export function universalCarrierHints(raw, trackingNumber) {
|
|
69
71
|
const names = [...new Set(raw.filter((value) => typeof value === 'string'
|
|
70
72
|
&& value.length <= 80 && /^[\p{L}\p{N} .&'()-]+$/u.test(value)).map((value) => value.trim()))].filter(Boolean).slice(0, 10);
|
|
71
73
|
const refused = new Set(trackingNumber ? checksumFailures(trackingNumber)
|
|
72
74
|
.filter(({ rule }) => ADAPTER_CHECKED_RULES.has(rule) || NAME_CHECKED_RULES.has(rule)).map(({ carrier }) => carrier) : []);
|
|
75
|
+
const fitting = trackingNumber ? detectCarrierMatch(trackingNumber).candidates : [];
|
|
73
76
|
const detected = new Set();
|
|
77
|
+
const inFull = new Set();
|
|
74
78
|
// Cainiao follows a parcel from abroad under its delivery carrier's number,
|
|
75
79
|
// so a brand named beside it delivers at home: Evri UK, not Evri
|
|
76
80
|
// International, which hands parcels to partners abroad.
|
|
77
81
|
const inbound = names.some((name) => followsPartnerNumbers(carrierIdFromName(name) ?? ''));
|
|
78
82
|
const leg = inbound ? (network) => !tracksPartnerNumbers(network) : undefined;
|
|
79
83
|
let unmapped = false;
|
|
84
|
+
let group = false;
|
|
80
85
|
for (const name of names) {
|
|
81
|
-
const
|
|
86
|
+
const own = carrierIdFromName(name);
|
|
87
|
+
const named = own ?? (trackingNumber ? brandCarrierForNumber(name, trackingNumber, leg) : undefined);
|
|
82
88
|
const carrier = named && trackingNumber ? partnerNumberOwner(named, trackingNumber) ?? named : named;
|
|
83
|
-
|
|
89
|
+
const networks = carrier || !trackingNumber ? [] : brandCarrierIds(name);
|
|
90
|
+
if (networks.length && !networks.some((id) => fitting.includes(id)))
|
|
91
|
+
group = true;
|
|
92
|
+
else if (!carrier)
|
|
84
93
|
unmapped = true;
|
|
85
|
-
else if (!refused.has(carrier))
|
|
94
|
+
else if (!refused.has(carrier)) {
|
|
86
95
|
detected.add(carrier);
|
|
96
|
+
if (own)
|
|
97
|
+
inFull.add(carrier);
|
|
98
|
+
}
|
|
87
99
|
}
|
|
88
100
|
// A name outside the catalog may be the number's owner, so it leaves no hint.
|
|
101
|
+
if (group && ![...detected].some((carrier) => fitting.includes(carrier)))
|
|
102
|
+
unmapped = true;
|
|
89
103
|
const discovered = unmapped ? undefined : detected.size === 1 ? [...detected][0]
|
|
90
|
-
: detected.size > 1 && trackingNumber ? journeyOwner([...detected], trackingNumber) : undefined;
|
|
104
|
+
: detected.size > 1 && trackingNumber ? journeyOwner([...detected], trackingNumber, inFull) : undefined;
|
|
91
105
|
return { reported_carriers: names, ...(discovered ? { discovered_carrier: discovered } : {}) };
|
|
92
106
|
}
|
|
93
107
|
/**
|
|
94
108
|
* A provider can name an origin and the carrier it hands the parcel to, such
|
|
95
109
|
* as DHLink and SwiftX. The number is the one carrier's whose rules fit it,
|
|
96
|
-
* or that a preferred rule backs among several
|
|
110
|
+
* or that a preferred rule backs among several, else the one named in full
|
|
111
|
+
* beside networks a bare brand left to the number's shape. When none fits, Cainiao, which
|
|
97
112
|
* follows a parcel under its delivery carrier's number, leaves the one carrier
|
|
98
113
|
* named beside it. Otherwise a carrier whose numbers all have a layout of their own
|
|
99
114
|
* (only high-confidence rules, SwiftX's SWX and eighteen digits) is named for
|
|
100
115
|
* its own leg, and the one carrier left is the hint.
|
|
101
116
|
*/
|
|
102
|
-
function journeyOwner(carriers, trackingNumber) {
|
|
117
|
+
function journeyOwner(carriers, trackingNumber, inFull) {
|
|
103
118
|
const { candidates, preferred } = detectCarrierMatch(trackingNumber);
|
|
104
119
|
const fitting = carriers.filter((carrier) => candidates.includes(carrier));
|
|
105
120
|
if (fitting.length === 1)
|
|
106
121
|
return fitting[0];
|
|
107
122
|
if (fitting.length > 1) {
|
|
108
123
|
const backed = fitting.filter((carrier) => preferred.includes(carrier));
|
|
109
|
-
|
|
124
|
+
if (backed.length === 1)
|
|
125
|
+
return backed[0];
|
|
126
|
+
const named = (backed.length ? backed : fitting).filter((carrier) => inFull.has(carrier));
|
|
127
|
+
return named.length === 1 && named.length < fitting.length ? named[0] : undefined;
|
|
110
128
|
}
|
|
111
129
|
const delivering = carriers.filter((carrier) => !followsPartnerNumbers(carrier));
|
|
112
130
|
if (delivering.length === 1 && delivering.length < carriers.length)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-parcel-scraper",
|
|
3
|
-
"version": "0.331.0-main.
|
|
3
|
+
"version": "0.331.0-main.1890",
|
|
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",
|