universal-parcel-scraper 0.764.1-main.4049 → 0.764.2-main.4053
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/dist/browser/scraper.js +1 -1
- package/dist/carriers/chronopost/status.js +2 -0
- package/dist/carriers/chronopost/statuses.json +9 -0
- package/dist/carriers/correos-spain/adapter.js +14 -14
- package/dist/carriers/correos-spain/clock.d.ts +6 -0
- package/dist/carriers/correos-spain/clock.js +24 -0
- package/dist/carriers/correos-spain/identity.js +3 -2
- package/dist/carriers/dhlink/status.js +11 -2
- package/dist/carriers/dhlink/statuses.json +7 -0
- package/dist/carriers/helthjem/parser.js +5 -4
- package/dist/carriers/helthjem/status.js +6 -3
- package/dist/carriers/helthjem/statuses.json +1 -1
- package/dist/core/result/index.js +3 -0
- package/dist/server/openapi.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ the command line's `track --source ParcelsApp` does the same.
|
|
|
161
161
|
<!-- GENERATED:stages -->
|
|
162
162
|
<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">
|
|
163
163
|
|
|
164
|
-
The carrier folders record 16,
|
|
164
|
+
The carrier folders record 16,891 such statuses, each filed under one stage.
|
|
165
165
|
<!-- /GENERATED:stages -->
|
|
166
166
|
|
|
167
167
|
Wording nobody recorded yet goes through a classifier that reads seven European languages.
|
package/dist/browser/scraper.js
CHANGED
|
@@ -31136,7 +31136,7 @@ function Ic(e) {
|
|
|
31136
31136
|
if (n != null && typeof n != "string") throw TypeError("The carrier adapter returned an invalid tracking event");
|
|
31137
31137
|
}
|
|
31138
31138
|
let t = { ...e };
|
|
31139
|
-
if (t.point !== void 0) {
|
|
31139
|
+
if (typeof t.location == "string" && !t.location.trim() && delete t.location, t.point !== void 0) {
|
|
31140
31140
|
let e = Xn(t.point) ? Nc(t.point.latitude, t.point.longitude) : null;
|
|
31141
31141
|
e ? t.point = e : delete t.point;
|
|
31142
31142
|
}
|
|
@@ -41,6 +41,8 @@ const OBSERVED = [
|
|
|
41
41
|
['TA', 'Colis en cours de livraison par le livreur', 'out_for_delivery'],
|
|
42
42
|
['RB', 'Colis en cours de livraison au point de retrait', 'in_transit'],
|
|
43
43
|
['AB', 'Colis mis à disposition au point de retrait', 'ready_for_pickup'],
|
|
44
|
+
// The courier left the parcel at another pickup point than the one planned, where it waits.
|
|
45
|
+
['AB', 'Colis mis à disposition dans un point de retrait différent de celui prévu', 'ready_for_pickup'],
|
|
44
46
|
// The same arrival at the pickup point, also written under SD and under MD.
|
|
45
47
|
['SD', 'Colis mis à disposition au point de retrait', 'ready_for_pickup'],
|
|
46
48
|
['MD', 'Colis mis à disposition au point de retrait', 'ready_for_pickup'],
|
|
@@ -312,6 +312,15 @@
|
|
|
312
312
|
"wording": "Colis mis à disposition au point de retrait",
|
|
313
313
|
"language": "fr"
|
|
314
314
|
},
|
|
315
|
+
{
|
|
316
|
+
"code": "AB",
|
|
317
|
+
"stage": "ready_for_pickup",
|
|
318
|
+
"confirmedBy": "live",
|
|
319
|
+
"firstSeen": "2026-10-27",
|
|
320
|
+
"note": "Chronopost trackSkybillV2; code mapping requires matching wording. The parcel waits at another pickup point than the one planned.",
|
|
321
|
+
"wording": "Colis mis à disposition dans un point de retrait différent de celui prévu",
|
|
322
|
+
"language": "fr"
|
|
323
|
+
},
|
|
315
324
|
{
|
|
316
325
|
"code": "SD",
|
|
317
326
|
"stage": "ready_for_pickup",
|
|
@@ -6,7 +6,7 @@ import { zonedTime } from '../../core/time/index.js';
|
|
|
6
6
|
import { clean, cleanScalar, fetchBounded, parseJsonBytes, UpstreamHttpError, userAgentOf } from '../../core/transport/index.js';
|
|
7
7
|
import { isRecord } from '../../core/types.js';
|
|
8
8
|
import { isCorreosExpressCode } from '../correos-express/status.js';
|
|
9
|
-
import { CORREOS_HOME_ZONE, correosOriginZone } from './clock.js';
|
|
9
|
+
import { CORREOS_HOME_ZONE, correosOriginZone, correosUnitZone } from './clock.js';
|
|
10
10
|
import { classifyCorreosSpainStatus, correosSpainEnglishSummary, NOTICE_CODES } from './status.js';
|
|
11
11
|
// Protocol provenance:
|
|
12
12
|
// - Prior art (structure + vocabulary, verified independently below, MIT):
|
|
@@ -41,12 +41,11 @@ const STAMP_FORMAT = 'dd/MM/yyyy HH:mm:ss';
|
|
|
41
41
|
/**
|
|
42
42
|
* When a scan happened. Correos splits it into fecEvento (DD/MM/YYYY) and
|
|
43
43
|
* horEvento (HH:MM:SS, midnight when absent), a wall clock, read in Spanish
|
|
44
|
-
* time:
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* the scans, on Madrid's reading for a wall clock.
|
|
44
|
+
* time: Europe/Madrid. A Canary Islands delivery unit's scans, and an origin
|
|
45
|
+
* post's scans on an item from abroad, have their own wall clock (clock.ts):
|
|
46
|
+
* they are read in `origin`, that zone, or kept as a wall clock when `origin`
|
|
47
|
+
* is null, as the post's country keeps several. `timestamp` orders the scans,
|
|
48
|
+
* on Madrid's reading for a wall clock.
|
|
50
49
|
*/
|
|
51
50
|
function parsedTime(dateValue, timeValue, origin) {
|
|
52
51
|
const date = clean(dateValue, 16);
|
|
@@ -154,14 +153,17 @@ function parseTracking(payload, trackingNumber, expeditionCode) {
|
|
|
154
153
|
}
|
|
155
154
|
const parsed = [];
|
|
156
155
|
const seen = new Set();
|
|
157
|
-
const
|
|
158
|
-
|
|
156
|
+
const rows = (Array.isArray(rawEvents) ? rawEvents : []).filter(isRecord).slice(0, 500);
|
|
157
|
+
const codes = rows.map((rawEvent) => clean(rawEvent.codEvento, 32).toLocaleUpperCase('en-US')).filter(Boolean);
|
|
158
|
+
// codired is the unit holding the parcel, whose address the office locator gives.
|
|
159
|
+
const officeCode = cleanScalar(envelope.codired, 16);
|
|
160
|
+
const unitZone = correosUnitZone(officeCode, codes);
|
|
161
|
+
rows.forEach((rawEvent, index) => {
|
|
159
162
|
const code = clean(rawEvent.codEvento, 32).toLocaleUpperCase('en-US');
|
|
160
|
-
if (code)
|
|
161
|
-
codes.push(code);
|
|
162
163
|
// desTextoResumen is worded in the language codIdioma names.
|
|
163
164
|
const description = clean(rawEvent.desTextoResumen, 500) || correosSpainEnglishSummary(code) || code;
|
|
164
|
-
const
|
|
165
|
+
const origin = correosOriginZone(requested, { code });
|
|
166
|
+
const time = parsedTime(rawEvent.fecEvento, rawEvent.horEvento, origin === undefined ? unitZone(code) : origin);
|
|
165
167
|
if (!time || !description)
|
|
166
168
|
return;
|
|
167
169
|
const identity = `${time.time ?? time.local_time}\u0000${description}\u0000${code}`;
|
|
@@ -207,7 +209,6 @@ function parseTracking(payload, trackingNumber, expeditionCode) {
|
|
|
207
209
|
// the envelope. The office is only a pickup signal when the parcel is
|
|
208
210
|
// actually awaiting collection; weight/dims are operational parcel data.
|
|
209
211
|
const office = clean(envelope.nom_codired, 300) || null;
|
|
210
|
-
const officeCode = cleanScalar(envelope.codired, 16);
|
|
211
212
|
const grams = Number(envelope.peso);
|
|
212
213
|
const weightKg = Number.isFinite(grams) && grams > 0 ? Math.round((grams / 1000) * 1000) / 1000 : null;
|
|
213
214
|
const dims = [envelope.largo, envelope.ancho, envelope.alto].map((value) => Number(value));
|
|
@@ -222,7 +223,6 @@ function parseTracking(payload, trackingNumber, expeditionCode) {
|
|
|
222
223
|
...(weightKg != null ? { weight_kg: weightKg } : {}),
|
|
223
224
|
...(dimensionsText ? { dimensions_text: dimensionsText } : {}),
|
|
224
225
|
};
|
|
225
|
-
// codired is the unit holding the parcel, whose address the office locator gives.
|
|
226
226
|
const waiting = latest?.event.stage === 'ready_for_pickup' && office;
|
|
227
227
|
const pickupExtras = waiting ? { pickup_point: office } : {};
|
|
228
228
|
const pickupOffice = waiting && /^\d{1,16}$/.test(officeCode) ? officeCode : '';
|
|
@@ -12,3 +12,9 @@ export declare function correosOriginZone(number: string, scan: {
|
|
|
12
12
|
} | {
|
|
13
13
|
wording: string;
|
|
14
14
|
}): string | null | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* The clock of the delivery unit's scans when the unit holding the parcel is
|
|
17
|
+
* on the Canary Islands, which stamp their own wall clock; undefined for any
|
|
18
|
+
* other unit or scan, on Madrid's clock.
|
|
19
|
+
*/
|
|
20
|
+
export declare function correosUnitZone(unit: string, codes: readonly string[]): (code: string) => string | undefined;
|
|
@@ -35,3 +35,27 @@ export function correosOriginZone(number, scan) {
|
|
|
35
35
|
const country = origin ? foreignOrigin(number) : null;
|
|
36
36
|
return country ? countryTimeZone(country) : undefined;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* A unit code (`codired`) opens with its province's two digits, as the office
|
|
40
|
+
* locator lists them: 35 (Las Palmas) and 38 (Santa Cruz de Tenerife) are the
|
|
41
|
+
* Canary Islands, an hour behind Madrid.
|
|
42
|
+
*/
|
|
43
|
+
const CANARY_UNIT = /^3[58]\d{5}$/;
|
|
44
|
+
/**
|
|
45
|
+
* The delivery unit's scans: its registration of the parcel (G), the rounds,
|
|
46
|
+
* attempts and holds (H, not the collection from a sender's address,
|
|
47
|
+
* HI10002V), the end of a hold (L0), its hold for a return (O13) and the
|
|
48
|
+
* delivery.
|
|
49
|
+
*/
|
|
50
|
+
const DELIVERY_UNIT_CODE = /^(?:[GH]\d|L0|O13|I01H210V$|I010000V$)/;
|
|
51
|
+
/** Handed back to the sender, whose unit the envelope may name from then on. */
|
|
52
|
+
const BACK_TO_SENDER = new Set(['I020000V', 'I01H230V']);
|
|
53
|
+
/**
|
|
54
|
+
* The clock of the delivery unit's scans when the unit holding the parcel is
|
|
55
|
+
* on the Canary Islands, which stamp their own wall clock; undefined for any
|
|
56
|
+
* other unit or scan, on Madrid's clock.
|
|
57
|
+
*/
|
|
58
|
+
export function correosUnitZone(unit, codes) {
|
|
59
|
+
const canary = CANARY_UNIT.test(unit) && !codes.some((code) => BACK_TO_SENDER.has(code));
|
|
60
|
+
return (code) => canary && DELIVERY_UNIT_CODE.test(code) ? 'Atlantic/Canary' : undefined;
|
|
61
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// Scans stored while the localizador answered in Spanish take its English
|
|
2
2
|
// wording in place: at one instant, the event code names the same scan. An
|
|
3
|
-
// origin post's scans on an item from abroad
|
|
4
|
-
//
|
|
3
|
+
// origin post's scans on an item from abroad, and a Canary Islands delivery
|
|
4
|
+
// unit's, kept the Madrid reading until October 2026 and now show their own
|
|
5
|
+
// clock, unless the origin's country keeps several.
|
|
5
6
|
export const sameInstantIdentityPolicy = {
|
|
6
7
|
sourceCarrierId: 'correos-spain', storedSources: ['correos-spain'], requireProviderCode: true, relabelledFrom: 'Europe/Madrid',
|
|
7
8
|
};
|
|
@@ -48,6 +48,10 @@ const WORDINGS = new Map([
|
|
|
48
48
|
['package received & scanned at warehouse', 'accepted'],
|
|
49
49
|
['package received and scanned at warehouse', 'accepted'],
|
|
50
50
|
['parcel handed over to carrier,waiting for transportation', 'accepted'],
|
|
51
|
+
// A line's collection point and its domestic warehouse, before export.
|
|
52
|
+
['the goods arrive at the receiving point', 'accepted'],
|
|
53
|
+
["package received & scanned at carrier's domestic warehouse.", 'accepted'],
|
|
54
|
+
["package depart carrier's domestic warehouse.", 'in_transit'],
|
|
51
55
|
// China Post's receipt (中国邮政 已收取邮件).
|
|
52
56
|
['package received', 'accepted'],
|
|
53
57
|
['the package has sent from the warehouse', 'in_transit'],
|
|
@@ -115,12 +119,17 @@ const PATTERNS = [
|
|
|
115
119
|
[/^离开【[^】]*】处理中心$/, 'in_transit'],
|
|
116
120
|
[/^送交出口海关$/, 'customs'],
|
|
117
121
|
// A line's own rows in Chinese, most with its English after them: the collection point and the
|
|
118
|
-
// operation centre, the warehouse's intake and customs' release before the flight,
|
|
119
|
-
//
|
|
122
|
+
// operation centre, the warehouse's intake and customs' release before the flight, the flight,
|
|
123
|
+
// import clearance once the dispatch is unpacked, then the destination warehouse and the
|
|
124
|
+
// hand-over to the local carrier.
|
|
120
125
|
[/^到达收货点$/, 'accepted'],
|
|
121
126
|
[/^货物离开操作中心$/, 'in_transit'],
|
|
122
127
|
[/^进仓时间[::]/, 'in_transit'],
|
|
123
128
|
[/^通关放行[;;]/, 'in_transit'],
|
|
129
|
+
[/^航班起飞[,,]/, 'in_transit'],
|
|
130
|
+
[/^航班已落地[;;]/, 'in_transit'],
|
|
131
|
+
[/^拆板清关中[;;]/, 'customs'],
|
|
132
|
+
[/^清关完成[,,]交仓中/, 'in_transit'],
|
|
124
133
|
[/^货物已交仓[,,]/, 'in_transit'],
|
|
125
134
|
[/^包裹交接给本地物流商处理/, 'in_transit'],
|
|
126
135
|
[/安排投递$/, 'out_for_delivery'],
|
|
@@ -68,6 +68,13 @@
|
|
|
68
68
|
{"wording": "货物已交仓,留意扫描; Pay attention to scanning", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "After import clearance, handed to the destination warehouse."},
|
|
69
69
|
{"wording": "包裹交接给本地物流商处理,Received by local delivery company", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "Handed over to the local carrier."},
|
|
70
70
|
{"wording": "预计配载航班时间:10-23;Estimated loading flight time:10-23", "unmapped": true, "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The flight the parcel is booked on, as another line words it, any date: no scan, so the adapter drops the row."},
|
|
71
|
+
{"wording": "THE GOODS ARRIVE AT THE RECEIVING POINT", "stage": "accepted", "language": "en", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The goods reached a line's collection point, beside 到达收货点."},
|
|
72
|
+
{"wording": "Package received & scanned at carrier's domestic warehouse.", "stage": "accepted", "language": "en", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The line's domestic warehouse took the parcel in."},
|
|
73
|
+
{"wording": "Package depart carrier's domestic warehouse.", "stage": "in_transit", "language": "en", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The parcel left the line's domestic warehouse."},
|
|
74
|
+
{"wording": "航班起飞,预计落地时间:10-25 Flight departure, estimated landing time:10-25", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The flight took off, with the day it lands; any day."},
|
|
75
|
+
{"wording": "航班已落地;The flight has Arrived", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "The flight landed."},
|
|
76
|
+
{"wording": "拆板清关中;Dismantle the board and clear the gate", "stage": "customs", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "Import clearance once the dispatch is unpacked from its pallet."},
|
|
77
|
+
{"wording": "清关完成,交仓中;Customs clearance completed,In transit", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-27", "note": "Import clearance done; on the way to the destination warehouse."},
|
|
71
78
|
{"wording": "预计配载航班1月2日,Expected flight on January 2nd", "unmapped": true, "language": "zh", "confirmedBy": "live", "firstSeen": "2026-10-25", "note": "The flight the parcel is booked on, in Chinese and English, any date, written before the flight: no scan, so the adapter drops the row."},
|
|
72
79
|
{"wording": "到达寄达地", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "note": "Arrived in the destination country."},
|
|
73
80
|
{"wording": "目的港已提货 Delivery has been made at the destination port", "stage": "in_transit", "language": "zh", "confirmedBy": "live", "note": "Collected at the destination port after import clearance, before the destination's own scans; the English says a delivery, which it is not."},
|
|
@@ -141,16 +141,17 @@ export function parseHelthjem(payload, rawNumber) {
|
|
|
141
141
|
const events = scans.map(scan => scan.event);
|
|
142
142
|
const newest = events[0];
|
|
143
143
|
// The page headlines the parcel's state; the newest scan stands in without
|
|
144
|
-
// one, and
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
// one, and the newest scan in that state for it, since its event code can
|
|
145
|
+
// say more than the state.
|
|
146
|
+
const own = state ? scans.find(scan => scan.state === state)?.event.stage : undefined;
|
|
147
|
+
const stateStage = !state ? undefined : own ?? helthjemStage(state);
|
|
147
148
|
if (!newest && !state)
|
|
148
149
|
throw new IndeterminateError(PROVIDER, 'Helthjem returned a parcel without a state or scans');
|
|
149
150
|
const stage = stateStage ?? newest?.stage;
|
|
150
151
|
const delivered = stage === 'delivered' ? deliveredAt(events) : undefined;
|
|
151
152
|
// The night a booking names, while no scan but a terminal's has followed it.
|
|
152
153
|
const booking = scans.find(scan => scan.state !== 'IN_TRANSIT')?.event;
|
|
153
|
-
const night = booking && stage === '
|
|
154
|
+
const night = booking && stage === 'in_transit' ? bookedNight(booking) : null;
|
|
154
155
|
// The point a parcel waits at, or was collected from, by its name alone.
|
|
155
156
|
const point = state === 'READY_FOR_PICKUP' || state === 'PICKED_UP'
|
|
156
157
|
? (isRecord(parcel.servicePoint) ? clean(parcel.servicePoint.name, 160) : '') : '';
|
|
@@ -7,8 +7,8 @@ const STATES = new Map([
|
|
|
7
7
|
// The shop announced the parcel; Helthjem does not have it yet.
|
|
8
8
|
['REGISTERED', { stage: 'registered', label: 'Pakken er registrert' }],
|
|
9
9
|
['IN_TRANSIT', { stage: 'in_transit', label: 'På vei til mottaker' }],
|
|
10
|
-
//
|
|
11
|
-
//
|
|
10
|
+
// On the round. A booking on the coming night's round and a night missed
|
|
11
|
+
// are filed here too; their event codes tell them apart.
|
|
12
12
|
['DELIVERING', { stage: 'out_for_delivery', label: 'Leveres' }],
|
|
13
13
|
['DELIVERED', { stage: 'delivered', label: 'Levert' }],
|
|
14
14
|
// A home delivery sent on to a pickup point instead.
|
|
@@ -26,8 +26,11 @@ const STATES = new Map([
|
|
|
26
26
|
]);
|
|
27
27
|
/** Scans whose event code says more than their state. */
|
|
28
28
|
const EVENTS = new Map([
|
|
29
|
+
// "Planlagt levering natt til 24. oktober!": the parcel is booked on the
|
|
30
|
+
// coming night's round, announced the day before. No courier has it yet.
|
|
31
|
+
['DELIVERING/113', 'in_transit'],
|
|
29
32
|
// "Budet fikk ikke med seg pakken din ut i natt": the night's courier did
|
|
30
|
-
// not take the parcel out, so it waits for a later round.
|
|
33
|
+
// not take the parcel out, so it waits for a later round.
|
|
31
34
|
['DELIVERING/057', 'in_transit'],
|
|
32
35
|
]);
|
|
33
36
|
/** The state is a word of capitals and underscores. */
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
{ "code": "REGISTERED/001", "wording": "Nettbutikken har meldt at en pakke er på vei!", "language": "nb", "stage": "registered", "confirmedBy": "live", "note": "The shop announced the parcel; Helthjem does not have it yet." },
|
|
5
5
|
{ "code": "IN_TRANSIT/002", "wording": "Vi har mottatt pakken din, og gjør den klar for veien videre.", "language": "nb", "stage": "in_transit", "confirmedBy": "live", "note": "Received at a Helthjem terminal, which the scan names." },
|
|
6
6
|
{ "code": "IN_TRANSIT/003", "wording": "Pakken er under transport.", "language": "nb", "stage": "in_transit", "confirmedBy": "live", "note": "A terminal or sorter scan. The page hides the rows of its sorter, which it names VestbySorter; the adapter keeps them." },
|
|
7
|
-
{ "code": "DELIVERING/113", "wording": "Planlagt levering natt til 8. oktober!", "language": "nb", "stage": "
|
|
7
|
+
{ "code": "DELIVERING/113", "wording": "Planlagt levering natt til 8. oktober!", "language": "nb", "stage": "in_transit", "confirmedBy": "live", "note": "Booked on the coming night's round, the day before it: no courier has the parcel yet. The wording names that night's date, which the adapter reads as the expected delivery day. Helthjem files the scan as delivering; its code overrides that state, for the parcel too while it is the newest scan in that state." },
|
|
8
8
|
{ "code": "DELIVERING/057", "wording": "Budet fikk ikke med seg pakken din ut i natt.", "language": "nb", "stage": "in_transit", "confirmedBy": "live", "firstSeen": "2026-10-25", "note": "The night's courier did not take the parcel out, so it waits for a later round. Helthjem files the scan as delivering; its code overrides that state, for the parcel too while it is the newest scan." },
|
|
9
9
|
{ "code": "DELIVERED/013", "wording": "Pakken er levert på dørmatten din!", "language": "nb", "stage": "delivered", "confirmedBy": "live", "note": "Left at the door." },
|
|
10
10
|
{ "code": "DELIVERED/013", "wording": "Pakken er levert i postkassen din!", "language": "nb", "stage": "delivered", "confirmedBy": "live", "note": "Left in the letterbox." },
|
|
@@ -150,6 +150,9 @@ export function normalizeCarrierResult(value) {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
const event = { ...rawEvent };
|
|
153
|
+
// A blank place is no place.
|
|
154
|
+
if (typeof event.location === 'string' && !event.location.trim())
|
|
155
|
+
delete event.location;
|
|
153
156
|
if (event.point !== undefined) {
|
|
154
157
|
const point = isRecord(event.point) ? eventPoint(event.point.latitude, event.point.longitude) : null;
|
|
155
158
|
if (point)
|
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.764.
|
|
3
|
+
"version": "0.764.2-main.4053",
|
|
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",
|