universal-parcel-scraper 0.93.0-main.987 → 0.95.0-main.992

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.
Files changed (39) hide show
  1. package/README.md +2 -2
  2. package/data/catalog.json +25 -5
  3. package/data/coverage-summary.json +1 -1
  4. package/data/detection-golden.json +61 -18
  5. package/dist/browser/scraper.js +26 -7
  6. package/dist/carriers/dao/adapter.d.ts +16 -0
  7. package/dist/carriers/dao/adapter.js +70 -0
  8. package/dist/carriers/dao/carrier.json +66 -8
  9. package/dist/carriers/dao/numbers.json +17 -7
  10. package/dist/carriers/dao/parser.d.ts +27 -0
  11. package/dist/carriers/dao/parser.js +141 -0
  12. package/dist/carriers/dao/status.d.ts +10 -0
  13. package/dist/carriers/dao/status.js +46 -0
  14. package/dist/carriers/dao/statuses.json +168 -1
  15. package/dist/carriers/slovak-parcel-service/adapter.d.ts +14 -0
  16. package/dist/carriers/slovak-parcel-service/adapter.js +78 -0
  17. package/dist/carriers/slovak-parcel-service/carrier.json +48 -7
  18. package/dist/carriers/slovak-parcel-service/numbers.json +12 -12
  19. package/dist/carriers/slovak-parcel-service/parser.d.ts +36 -0
  20. package/dist/carriers/slovak-parcel-service/parser.js +218 -0
  21. package/dist/carriers/slovak-parcel-service/status.d.ts +7 -0
  22. package/dist/carriers/slovak-parcel-service/status.js +16 -0
  23. package/dist/carriers/slovak-parcel-service/statuses.json +15 -1
  24. package/dist/carriers/slovenska-posta/adapter.d.ts +15 -0
  25. package/dist/carriers/slovenska-posta/adapter.js +65 -0
  26. package/dist/carriers/slovenska-posta/carrier.json +70 -8
  27. package/dist/carriers/slovenska-posta/parser.d.ts +12 -0
  28. package/dist/carriers/slovenska-posta/parser.js +246 -0
  29. package/dist/carriers/slovenska-posta/status.d.ts +17 -0
  30. package/dist/carriers/slovenska-posta/status.js +240 -0
  31. package/dist/carriers/slovenska-posta/statuses.json +151 -1
  32. package/dist/core/catalog/statusMaps.js +9 -6
  33. package/dist/data/catalog.json +25 -5
  34. package/dist/generated/catalog.d.ts +21 -5
  35. package/dist/generated/catalog.js +27 -7
  36. package/dist/generated/recognition.js +3 -0
  37. package/dist/generated/registry.js +9 -3
  38. package/dist/server/openapi.json +1 -1
  39. package/package.json +1 -1
package/README.md CHANGED
@@ -13,7 +13,7 @@ The engine behind [Peek](https://peektracker.com) ([GitHub](https://github.com/p
13
13
  [![License: Apache-2.0](https://img.shields.io/badge/core-Apache--2.0-blue.svg)](LICENSE)
14
14
 
15
15
  <!-- GENERATED:summary -->
16
- **3,500+ carriers** through **151 dedicated adapters** and **5 universal fallbacks**
16
+ **3,500+ carriers** through **154 dedicated adapters** and **5 universal fallbacks**
17
17
 
18
18
  <sub>208 catalog entries · 66 countries represented</sub>
19
19
  <!-- /GENERATED:summary -->
@@ -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 4,117 such statuses, each filed under one stage.
158
+ The carrier folders record 4,298 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
@@ -5249,7 +5249,9 @@
5249
5249
  "timezone": "Europe/Copenhagen",
5250
5250
  "tracking": {
5251
5251
  "mode": "automatic",
5252
- "adapter": "universal"
5252
+ "adapter": "dao",
5253
+ "recognitionRank": 850,
5254
+ "localClocks": true
5253
5255
  },
5254
5256
  "canaryUrl": "https://dao.as/find-din-pakke/",
5255
5257
  "trackingUrlTemplate": "https://dao.as/find-din-pakke/#q={trackingNumber}",
@@ -5276,7 +5278,14 @@
5276
5278
  ]
5277
5279
  }
5278
5280
  ],
5279
- "detectionRules": []
5281
+ "detectionRules": [
5282
+ {
5283
+ "pattern": "^000(?:5712696|5715127)\\d{10}$",
5284
+ "confidence": "low",
5285
+ "checksum": "sscc",
5286
+ "preferred": true
5287
+ }
5288
+ ]
5280
5289
  },
5281
5290
  "day-ross": {
5282
5291
  "displayName": "Day & Ross",
@@ -7916,7 +7925,9 @@
7916
7925
  "timezone": "Europe/Bratislava",
7917
7926
  "tracking": {
7918
7927
  "mode": "automatic",
7919
- "adapter": "universal"
7928
+ "adapter": "slovak-parcel-service",
7929
+ "recognitionRank": 830,
7930
+ "localClocks": true
7920
7931
  },
7921
7932
  "canaryUrl": "https://www.sps-sro.sk/moja-zasielka/",
7922
7933
  "trackingUrlTemplate": "https://www.sps-sro.sk/moja-zasielka/?shipment_id={trackingNumber}",
@@ -7953,7 +7964,9 @@
7953
7964
  "timezone": "Europe/Bratislava",
7954
7965
  "tracking": {
7955
7966
  "mode": "automatic",
7956
- "adapter": "universal"
7967
+ "adapter": "slovenska-posta",
7968
+ "recognitionRank": 840,
7969
+ "localClocks": true
7957
7970
  },
7958
7971
  "canaryUrl": "https://www.posta.sk/sledovanie-zasielok",
7959
7972
  "trackingUrlTemplate": "https://www.posta.sk/sledovanie-zasielok#parcel={trackingNumber}",
@@ -7982,7 +7995,14 @@
7982
7995
  ]
7983
7996
  }
7984
7997
  ],
7985
- "detectionRules": []
7998
+ "detectionRules": [
7999
+ {
8000
+ "pattern": "^[A-Z]{2}\\d{9}SK$",
8001
+ "confidence": "low",
8002
+ "checksum": "s10",
8003
+ "preferred": true
8004
+ }
8005
+ ]
7986
8006
  },
7987
8007
  "speedpak": {
7988
8008
  "displayName": "SpeedPAK",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "catalog": 208,
3
- "activeAdapters": 151,
3
+ "activeAdapters": 154,
4
4
  "countries": 66,
5
5
  "referenceCarriers": 100,
6
6
  "comparison": {
@@ -162,14 +162,17 @@
162
162
  "confidence": "low",
163
163
  "candidates": [
164
164
  "postnord",
165
+ "dao",
165
166
  "swiss-post-cargo",
166
167
  "usps",
167
168
  "nz-post"
168
169
  ],
169
170
  "preferred": [
170
- "postnord"
171
+ "postnord",
172
+ "dao"
171
173
  ],
172
174
  "asked": [
175
+ "dao",
173
176
  "postnord",
174
177
  "swiss-post-cargo",
175
178
  "nz-post"
@@ -181,14 +184,17 @@
181
184
  "confidence": "low",
182
185
  "candidates": [
183
186
  "postnord",
187
+ "dao",
184
188
  "swiss-post-cargo",
185
189
  "usps",
186
190
  "nz-post"
187
191
  ],
188
192
  "preferred": [
189
- "postnord"
193
+ "postnord",
194
+ "dao"
190
195
  ],
191
196
  "asked": [
197
+ "dao",
192
198
  "postnord",
193
199
  "swiss-post-cargo",
194
200
  "nz-post"
@@ -200,14 +206,17 @@
200
206
  "confidence": "low",
201
207
  "candidates": [
202
208
  "postnord",
209
+ "dao",
203
210
  "swiss-post-cargo",
204
211
  "usps",
205
212
  "nz-post"
206
213
  ],
207
214
  "preferred": [
208
- "postnord"
215
+ "postnord",
216
+ "dao"
209
217
  ],
210
218
  "asked": [
219
+ "dao",
211
220
  "postnord",
212
221
  "swiss-post-cargo",
213
222
  "nz-post"
@@ -219,14 +228,17 @@
219
228
  "confidence": "low",
220
229
  "candidates": [
221
230
  "postnord",
231
+ "dao",
222
232
  "swiss-post-cargo",
223
233
  "usps",
224
234
  "nz-post"
225
235
  ],
226
236
  "preferred": [
227
- "postnord"
237
+ "postnord",
238
+ "dao"
228
239
  ],
229
240
  "asked": [
241
+ "dao",
230
242
  "postnord",
231
243
  "swiss-post-cargo",
232
244
  "nz-post"
@@ -238,14 +250,17 @@
238
250
  "confidence": "low",
239
251
  "candidates": [
240
252
  "postnord",
253
+ "dao",
241
254
  "swiss-post-cargo",
242
255
  "usps",
243
256
  "nz-post"
244
257
  ],
245
258
  "preferred": [
246
- "postnord"
259
+ "postnord",
260
+ "dao"
247
261
  ],
248
262
  "asked": [
263
+ "dao",
249
264
  "postnord",
250
265
  "swiss-post-cargo",
251
266
  "nz-post"
@@ -257,14 +272,17 @@
257
272
  "confidence": "low",
258
273
  "candidates": [
259
274
  "postnord",
275
+ "dao",
260
276
  "swiss-post-cargo",
261
277
  "usps",
262
278
  "nz-post"
263
279
  ],
264
280
  "preferred": [
265
- "postnord"
281
+ "postnord",
282
+ "dao"
266
283
  ],
267
284
  "asked": [
285
+ "dao",
268
286
  "postnord",
269
287
  "swiss-post-cargo",
270
288
  "nz-post"
@@ -276,14 +294,17 @@
276
294
  "confidence": "low",
277
295
  "candidates": [
278
296
  "postnord",
297
+ "dao",
279
298
  "swiss-post-cargo",
280
299
  "usps",
281
300
  "nz-post"
282
301
  ],
283
302
  "preferred": [
284
- "postnord"
303
+ "postnord",
304
+ "dao"
285
305
  ],
286
306
  "asked": [
307
+ "dao",
287
308
  "postnord",
288
309
  "swiss-post-cargo",
289
310
  "nz-post"
@@ -295,14 +316,17 @@
295
316
  "confidence": "low",
296
317
  "candidates": [
297
318
  "postnord",
319
+ "dao",
298
320
  "swiss-post-cargo",
299
321
  "usps",
300
322
  "nz-post"
301
323
  ],
302
324
  "preferred": [
303
- "postnord"
325
+ "postnord",
326
+ "dao"
304
327
  ],
305
328
  "asked": [
329
+ "dao",
306
330
  "postnord",
307
331
  "swiss-post-cargo",
308
332
  "nz-post"
@@ -314,14 +338,17 @@
314
338
  "confidence": "low",
315
339
  "candidates": [
316
340
  "postnord",
341
+ "dao",
317
342
  "swiss-post-cargo",
318
343
  "usps",
319
344
  "nz-post"
320
345
  ],
321
346
  "preferred": [
322
- "postnord"
347
+ "postnord",
348
+ "dao"
323
349
  ],
324
350
  "asked": [
351
+ "dao",
325
352
  "postnord",
326
353
  "swiss-post-cargo",
327
354
  "nz-post"
@@ -333,14 +360,17 @@
333
360
  "confidence": "low",
334
361
  "candidates": [
335
362
  "postnord",
363
+ "dao",
336
364
  "swiss-post-cargo",
337
365
  "usps",
338
366
  "nz-post"
339
367
  ],
340
368
  "preferred": [
341
- "postnord"
369
+ "postnord",
370
+ "dao"
342
371
  ],
343
372
  "asked": [
373
+ "dao",
344
374
  "postnord",
345
375
  "swiss-post-cargo",
346
376
  "nz-post"
@@ -19948,10 +19978,10 @@
19948
19978
  ],
19949
19979
  "asked": [
19950
19980
  "hermes-de",
19981
+ "slovak-parcel-service",
19951
19982
  "dpd",
19952
19983
  "dpd-de",
19953
- "seur",
19954
- "brt"
19984
+ "seur"
19955
19985
  ]
19956
19986
  },
19957
19987
  {
@@ -19989,11 +20019,11 @@
19989
20019
  "slovak-parcel-service"
19990
20020
  ],
19991
20021
  "asked": [
20022
+ "slovak-parcel-service",
19992
20023
  "dpd",
19993
20024
  "dpd-de",
19994
20025
  "seur",
19995
- "brt",
19996
- "relais-colis"
20026
+ "brt"
19997
20027
  ]
19998
20028
  },
19999
20029
  {
@@ -20015,10 +20045,10 @@
20015
20045
  ],
20016
20046
  "asked": [
20017
20047
  "hermes-de",
20048
+ "slovak-parcel-service",
20018
20049
  "dpd",
20019
20050
  "dpd-de",
20020
- "seur",
20021
- "brt"
20051
+ "seur"
20022
20052
  ]
20023
20053
  },
20024
20054
  {
@@ -20038,11 +20068,11 @@
20038
20068
  "slovak-parcel-service"
20039
20069
  ],
20040
20070
  "asked": [
20071
+ "slovak-parcel-service",
20041
20072
  "dpd",
20042
20073
  "dpd-de",
20043
20074
  "seur",
20044
- "brt",
20045
- "relais-colis"
20075
+ "brt"
20046
20076
  ]
20047
20077
  },
20048
20078
  {
@@ -25176,6 +25206,7 @@
25176
25206
  "intl-post"
25177
25207
  ],
25178
25208
  "asked": [
25209
+ "slovenska-posta",
25179
25210
  "chronopost"
25180
25211
  ]
25181
25212
  },
@@ -25390,6 +25421,7 @@
25390
25421
  "intl-post"
25391
25422
  ],
25392
25423
  "asked": [
25424
+ "slovenska-posta",
25393
25425
  "chronopost"
25394
25426
  ]
25395
25427
  },
@@ -26769,6 +26801,7 @@
26769
26801
  "intl-post"
26770
26802
  ],
26771
26803
  "asked": [
26804
+ "slovenska-posta",
26772
26805
  "chronopost"
26773
26806
  ]
26774
26807
  },
@@ -26884,6 +26917,7 @@
26884
26917
  "intl-post"
26885
26918
  ],
26886
26919
  "asked": [
26920
+ "slovenska-posta",
26887
26921
  "chronopost"
26888
26922
  ]
26889
26923
  },
@@ -26986,6 +27020,7 @@
26986
27020
  "intl-post"
26987
27021
  ],
26988
27022
  "asked": [
27023
+ "slovenska-posta",
26989
27024
  "chronopost"
26990
27025
  ]
26991
27026
  },
@@ -27521,6 +27556,7 @@
27521
27556
  "intl-post"
27522
27557
  ],
27523
27558
  "asked": [
27559
+ "slovenska-posta",
27524
27560
  "chronopost"
27525
27561
  ]
27526
27562
  },
@@ -27532,6 +27568,7 @@
27532
27568
  "intl-post"
27533
27569
  ],
27534
27570
  "asked": [
27571
+ "slovenska-posta",
27535
27572
  "chronopost"
27536
27573
  ]
27537
27574
  },
@@ -27638,6 +27675,7 @@
27638
27675
  "intl-post"
27639
27676
  ],
27640
27677
  "asked": [
27678
+ "slovenska-posta",
27641
27679
  "chronopost"
27642
27680
  ]
27643
27681
  },
@@ -30811,6 +30849,7 @@
30811
30849
  "intl-post"
30812
30850
  ],
30813
30851
  "asked": [
30852
+ "slovenska-posta",
30814
30853
  "chronopost"
30815
30854
  ]
30816
30855
  },
@@ -30822,6 +30861,7 @@
30822
30861
  "intl-post"
30823
30862
  ],
30824
30863
  "asked": [
30864
+ "slovenska-posta",
30825
30865
  "chronopost"
30826
30866
  ]
30827
30867
  },
@@ -33590,6 +33630,7 @@
33590
33630
  "intl-post"
33591
33631
  ],
33592
33632
  "asked": [
33633
+ "slovenska-posta",
33593
33634
  "chronopost"
33594
33635
  ]
33595
33636
  },
@@ -33645,6 +33686,7 @@
33645
33686
  "intl-post"
33646
33687
  ],
33647
33688
  "asked": [
33689
+ "slovenska-posta",
33648
33690
  "chronopost"
33649
33691
  ]
33650
33692
  },
@@ -33975,6 +34017,7 @@
33975
34017
  "intl-post"
33976
34018
  ],
33977
34019
  "asked": [
34020
+ "slovenska-posta",
33978
34021
  "chronopost"
33979
34022
  ]
33980
34023
  },
@@ -4274,7 +4274,9 @@ var be = {
4274
4274
  timezone: "Europe/Copenhagen",
4275
4275
  tracking: {
4276
4276
  mode: "automatic",
4277
- adapter: "universal"
4277
+ adapter: "dao",
4278
+ recognitionRank: 850,
4279
+ localClocks: !0
4278
4280
  },
4279
4281
  canaryUrl: "https://dao.as/find-din-pakke/",
4280
4282
  trackingUrlTemplate: "https://dao.as/find-din-pakke/#q={trackingNumber}",
@@ -4289,7 +4291,12 @@ var be = {
4289
4291
  pathPattern: "^/(?:en/private/track-your-parcel/?|dao-app/?)?$",
4290
4292
  params: ["stregkode"]
4291
4293
  }],
4292
- detectionRules: []
4294
+ detectionRules: [{
4295
+ pattern: "^000(?:5712696|5715127)\\d{10}$",
4296
+ confidence: "low",
4297
+ checksum: "sscc",
4298
+ preferred: !0
4299
+ }]
4293
4300
  },
4294
4301
  "day-ross": {
4295
4302
  displayName: "Day & Ross",
@@ -6274,7 +6281,9 @@ var be = {
6274
6281
  timezone: "Europe/Bratislava",
6275
6282
  tracking: {
6276
6283
  mode: "automatic",
6277
- adapter: "universal"
6284
+ adapter: "slovak-parcel-service",
6285
+ recognitionRank: 830,
6286
+ localClocks: !0
6278
6287
  },
6279
6288
  canaryUrl: "https://www.sps-sro.sk/moja-zasielka/",
6280
6289
  trackingUrlTemplate: "https://www.sps-sro.sk/moja-zasielka/?shipment_id={trackingNumber}",
@@ -6298,7 +6307,9 @@ var be = {
6298
6307
  timezone: "Europe/Bratislava",
6299
6308
  tracking: {
6300
6309
  mode: "automatic",
6301
- adapter: "universal"
6310
+ adapter: "slovenska-posta",
6311
+ recognitionRank: 840,
6312
+ localClocks: !0
6302
6313
  },
6303
6314
  canaryUrl: "https://www.posta.sk/sledovanie-zasielok",
6304
6315
  trackingUrlTemplate: "https://www.posta.sk/sledovanie-zasielok#parcel={trackingNumber}",
@@ -6319,7 +6330,12 @@ var be = {
6319
6330
  params: ["q"]
6320
6331
  }
6321
6332
  ],
6322
- detectionRules: []
6333
+ detectionRules: [{
6334
+ pattern: "^[A-Z]{2}\\d{9}SK$",
6335
+ confidence: "low",
6336
+ checksum: "s10",
6337
+ preferred: !0
6338
+ }]
6323
6339
  },
6324
6340
  speedpak: {
6325
6341
  displayName: "SpeedPAK",
@@ -7084,7 +7100,7 @@ var be = {
7084
7100
  cne: ["cne-1"],
7085
7101
  "correos-de-mexico": [],
7086
7102
  "cyprus-post": [],
7087
- dao: [],
7103
+ dao: ["dao-1"],
7088
7104
  "day-ross": ["day-ross-1"],
7089
7105
  "dhl-ecommerce-es": ["dhl-ecommerce-es-1", "dhl-ecommerce-es-2"],
7090
7106
  "dhl-ecommerce-nl": [
@@ -7184,7 +7200,7 @@ var be = {
7184
7200
  saia: [],
7185
7201
  sameday: ["sameday-1"],
7186
7202
  "slovak-parcel-service": ["slovak-parcel-service-1"],
7187
- "slovenska-posta": [],
7203
+ "slovenska-posta": ["slovenska-posta-s10"],
7188
7204
  speedpak: ["speedpak-1"],
7189
7205
  speedy: [],
7190
7206
  "spx-ph": [
@@ -11912,6 +11928,7 @@ var bc = {
11912
11928
  "colis-prive": 300,
11913
11929
  "correos-express": 360,
11914
11930
  "ctt-express": 350,
11931
+ dao: 850,
11915
11932
  delhivery: 160,
11916
11933
  "dhl-ecommerce": 230,
11917
11934
  "dhl-ecommerce-es": 190,
@@ -11965,6 +11982,8 @@ var bc = {
11965
11982
  "relais-colis": 250,
11966
11983
  sameday: 530,
11967
11984
  seur: 430,
11985
+ "slovak-parcel-service": 830,
11986
+ "slovenska-posta": 840,
11968
11987
  speedy: 540,
11969
11988
  sto: 100,
11970
11989
  "swiss-post-cargo": 110,
@@ -0,0 +1,16 @@
1
+ import { type AdapterFactory, type TrackingContext } from '../../core/adapter/index.js';
2
+ import type { CarrierResult } from '../../core/result/index.js';
3
+ import { type StepRecorder } from '../../core/telemetry/index.js';
4
+ export declare const DAO_ENDPOINT = "https://dao.as/wp-json/dao-wp/v1/track-parcel";
5
+ /** The service's address for one number, with English wording. */
6
+ export declare function daoTrackingUrl(raw: string): string;
7
+ export declare class DaoTracker {
8
+ private readonly options;
9
+ constructor(options?: {
10
+ fetcher?: typeof fetch;
11
+ recorder?: StepRecorder;
12
+ userAgent?: string;
13
+ });
14
+ fetch(raw: string, context?: TrackingContext): Promise<CarrierResult>;
15
+ }
16
+ export declare const adapter: AdapterFactory;
@@ -0,0 +1,70 @@
1
+ import { accepted, recognizeFromLookup } from '../../core/adapter/index.js';
2
+ import { ChallengeError, IndeterminateError, SchemaError, TransportError, UpstreamHttpError } from '../../core/errors/index.js';
3
+ import { runSteps } from '../../core/runner/index.js';
4
+ import { firstAttemptMs, networkRetryStep } from '../../core/runner/networkRetry.js';
5
+ import { NOOP_RECORDER } from '../../core/telemetry/index.js';
6
+ import { decodeText, fetchBounded, parseJsonBytes, userAgentOf } from '../../core/transport/index.js';
7
+ import { DAO_MAX_BYTES, normalizeDaoNumber, parseDao, PROVIDER } from './parser.js';
8
+ // The service dao.as/find-din-pakke asks, without a key, nonce or cookie.
9
+ export const DAO_ENDPOINT = 'https://dao.as/wp-json/dao-wp/v1/track-parcel';
10
+ // A WordPress or edge block page instead of the service's JSON.
11
+ const BLOCKED = /<title>\s*(?:Just a moment|Attention Required|Access denied|403 Forbidden)|cf-chl-|cf-turnstile|captcha/i;
12
+ /** The service's address for one number, with English wording. */
13
+ export function daoTrackingUrl(raw) {
14
+ return `${DAO_ENDPOINT}?${new URLSearchParams({ barcode: normalizeDaoNumber(raw).number, lang: 'EN' })}`;
15
+ }
16
+ export class DaoTracker {
17
+ options;
18
+ constructor(options = {}) {
19
+ this.options = options;
20
+ }
21
+ async fetch(raw, context = {}) {
22
+ const url = daoTrackingUrl(raw);
23
+ const read = async (signal, timeoutMs) => {
24
+ let bytes;
25
+ let status;
26
+ try {
27
+ // The page sends its WordPress nonce, which the service does not need
28
+ // without a session cookie.
29
+ ({ bytes, response: { status } } = await fetchBounded(url, { signal,
30
+ headers: { Accept: 'application/json', 'User-Agent': userAgentOf(this.options.userAgent) } }, { provider: PROVIDER, timeoutMs: Math.max(1, Math.floor(timeoutMs)), maxBytes: DAO_MAX_BYTES, fetcher: this.options.fetcher,
31
+ allowHttpStatuses: [400] }));
32
+ }
33
+ catch (error) {
34
+ // An unknown number is {"found":false}; a missing route is not a missing parcel.
35
+ if (error instanceof UpstreamHttpError && [404, 410].includes(error.status)) {
36
+ throw new TransportError(PROVIDER, 'DAO tracking service is unavailable', { cause: error });
37
+ }
38
+ throw error;
39
+ }
40
+ let payload;
41
+ try {
42
+ payload = parseJsonBytes(bytes, PROVIDER);
43
+ }
44
+ catch (cause) {
45
+ if (BLOCKED.test(decodeText(bytes.subarray(0, 64_000))))
46
+ throw new ChallengeError(PROVIDER, 'DAO answered with a block page', { cause });
47
+ throw new SchemaError(PROVIDER, 'DAO returned invalid tracking JSON', { cause });
48
+ }
49
+ // The service names a request it cannot read, such as one without a number.
50
+ if (status === 400)
51
+ throw new IndeterminateError(PROVIDER, 'DAO rejected the tracking request');
52
+ return parseDao(payload, raw);
53
+ };
54
+ // A request that fails to reach DAO, or hangs, gets one more try: the
55
+ // first gets half of the budget, so the retry fits in the rest.
56
+ return runSteps({ carrier: 'dao', budgetMs: context.budgetMs ?? 15_000, signal: context.signal,
57
+ recorder: this.options.recorder ?? NOOP_RECORDER }, [
58
+ { id: 'direct', run: ({ signal, remainingMs }) => read(signal, firstAttemptMs(remainingMs)) },
59
+ networkRetryStep(({ signal, remainingMs }) => read(signal, remainingMs)),
60
+ ]);
61
+ }
62
+ }
63
+ export const adapter = (environment) => {
64
+ const tracker = new DaoTracker({ fetcher: environment.fetcher, recorder: environment.recorder, userAgent: environment.userAgent });
65
+ return {
66
+ id: 'dao', recordsSteps: true, steps: ['direct', 'retry'],
67
+ track: (input, context) => tracker.fetch(input.number, context),
68
+ recognize: (number, context) => recognizeFromLookup(() => tracker.fetch(number, context), () => accepted(() => normalizeDaoNumber(number))),
69
+ };
70
+ };