gscdump 0.26.10 → 0.27.0

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.
@@ -0,0 +1,2929 @@
1
+ import { ofetch } from "ofetch";
2
+ const MS_PER_DAY = 864e5;
3
+ function toIsoDate(d) {
4
+ return d.toISOString().slice(0, 10);
5
+ }
6
+ function addDays(dateStr, n) {
7
+ return toIsoDate(new Date(Date.parse(`${dateStr}T00:00:00Z`) + n * MS_PER_DAY));
8
+ }
9
+ function ok(value) {
10
+ return {
11
+ ok: true,
12
+ value
13
+ };
14
+ }
15
+ function err(error) {
16
+ return {
17
+ ok: false,
18
+ error
19
+ };
20
+ }
21
+ function unwrapResult(result, toError) {
22
+ if (result.ok) return result.value;
23
+ throw toError(result.error);
24
+ }
25
+ var countries_default = [
26
+ {
27
+ "name": "Afghanistan",
28
+ "alpha-2": "AF",
29
+ "alpha-3": "AFG",
30
+ "country-code": "004"
31
+ },
32
+ {
33
+ "name": "Åland Islands",
34
+ "alpha-2": "AX",
35
+ "alpha-3": "ALA",
36
+ "country-code": "248"
37
+ },
38
+ {
39
+ "name": "Albania",
40
+ "alpha-2": "AL",
41
+ "alpha-3": "ALB",
42
+ "country-code": "008"
43
+ },
44
+ {
45
+ "name": "Algeria",
46
+ "alpha-2": "DZ",
47
+ "alpha-3": "DZA",
48
+ "country-code": "012"
49
+ },
50
+ {
51
+ "name": "American Samoa",
52
+ "alpha-2": "AS",
53
+ "alpha-3": "ASM",
54
+ "country-code": "016"
55
+ },
56
+ {
57
+ "name": "Andorra",
58
+ "alpha-2": "AD",
59
+ "alpha-3": "AND",
60
+ "country-code": "020"
61
+ },
62
+ {
63
+ "name": "Angola",
64
+ "alpha-2": "AO",
65
+ "alpha-3": "AGO",
66
+ "country-code": "024"
67
+ },
68
+ {
69
+ "name": "Anguilla",
70
+ "alpha-2": "AI",
71
+ "alpha-3": "AIA",
72
+ "country-code": "660"
73
+ },
74
+ {
75
+ "name": "Antarctica",
76
+ "alpha-2": "AQ",
77
+ "alpha-3": "ATA",
78
+ "country-code": "010"
79
+ },
80
+ {
81
+ "name": "Antigua and Barbuda",
82
+ "alpha-2": "AG",
83
+ "alpha-3": "ATG",
84
+ "country-code": "028"
85
+ },
86
+ {
87
+ "name": "Argentina",
88
+ "alpha-2": "AR",
89
+ "alpha-3": "ARG",
90
+ "country-code": "032"
91
+ },
92
+ {
93
+ "name": "Armenia",
94
+ "alpha-2": "AM",
95
+ "alpha-3": "ARM",
96
+ "country-code": "051"
97
+ },
98
+ {
99
+ "name": "Aruba",
100
+ "alpha-2": "AW",
101
+ "alpha-3": "ABW",
102
+ "country-code": "533"
103
+ },
104
+ {
105
+ "name": "Australia",
106
+ "alpha-2": "AU",
107
+ "alpha-3": "AUS",
108
+ "country-code": "036"
109
+ },
110
+ {
111
+ "name": "Austria",
112
+ "alpha-2": "AT",
113
+ "alpha-3": "AUT",
114
+ "country-code": "040"
115
+ },
116
+ {
117
+ "name": "Azerbaijan",
118
+ "alpha-2": "AZ",
119
+ "alpha-3": "AZE",
120
+ "country-code": "031"
121
+ },
122
+ {
123
+ "name": "Bahamas",
124
+ "alpha-2": "BS",
125
+ "alpha-3": "BHS",
126
+ "country-code": "044"
127
+ },
128
+ {
129
+ "name": "Bahrain",
130
+ "alpha-2": "BH",
131
+ "alpha-3": "BHR",
132
+ "country-code": "048"
133
+ },
134
+ {
135
+ "name": "Bangladesh",
136
+ "alpha-2": "BD",
137
+ "alpha-3": "BGD",
138
+ "country-code": "050"
139
+ },
140
+ {
141
+ "name": "Barbados",
142
+ "alpha-2": "BB",
143
+ "alpha-3": "BRB",
144
+ "country-code": "052"
145
+ },
146
+ {
147
+ "name": "Belarus",
148
+ "alpha-2": "BY",
149
+ "alpha-3": "BLR",
150
+ "country-code": "112"
151
+ },
152
+ {
153
+ "name": "Belgium",
154
+ "alpha-2": "BE",
155
+ "alpha-3": "BEL",
156
+ "country-code": "056"
157
+ },
158
+ {
159
+ "name": "Belize",
160
+ "alpha-2": "BZ",
161
+ "alpha-3": "BLZ",
162
+ "country-code": "084"
163
+ },
164
+ {
165
+ "name": "Benin",
166
+ "alpha-2": "BJ",
167
+ "alpha-3": "BEN",
168
+ "country-code": "204"
169
+ },
170
+ {
171
+ "name": "Bermuda",
172
+ "alpha-2": "BM",
173
+ "alpha-3": "BMU",
174
+ "country-code": "060"
175
+ },
176
+ {
177
+ "name": "Bhutan",
178
+ "alpha-2": "BT",
179
+ "alpha-3": "BTN",
180
+ "country-code": "064"
181
+ },
182
+ {
183
+ "name": "Bolivia (Plurinational State of)",
184
+ "alpha-2": "BO",
185
+ "alpha-3": "BOL",
186
+ "country-code": "068"
187
+ },
188
+ {
189
+ "name": "Bonaire, Sint Eustatius and Saba",
190
+ "alpha-2": "BQ",
191
+ "alpha-3": "BES",
192
+ "country-code": "535"
193
+ },
194
+ {
195
+ "name": "Bosnia and Herzegovina",
196
+ "alpha-2": "BA",
197
+ "alpha-3": "BIH",
198
+ "country-code": "070"
199
+ },
200
+ {
201
+ "name": "Botswana",
202
+ "alpha-2": "BW",
203
+ "alpha-3": "BWA",
204
+ "country-code": "072"
205
+ },
206
+ {
207
+ "name": "Bouvet Island",
208
+ "alpha-2": "BV",
209
+ "alpha-3": "BVT",
210
+ "country-code": "074"
211
+ },
212
+ {
213
+ "name": "Brazil",
214
+ "alpha-2": "BR",
215
+ "alpha-3": "BRA",
216
+ "country-code": "076"
217
+ },
218
+ {
219
+ "name": "British Indian Ocean Territory",
220
+ "alpha-2": "IO",
221
+ "alpha-3": "IOT",
222
+ "country-code": "086"
223
+ },
224
+ {
225
+ "name": "Brunei Darussalam",
226
+ "alpha-2": "BN",
227
+ "alpha-3": "BRN",
228
+ "country-code": "096"
229
+ },
230
+ {
231
+ "name": "Bulgaria",
232
+ "alpha-2": "BG",
233
+ "alpha-3": "BGR",
234
+ "country-code": "100"
235
+ },
236
+ {
237
+ "name": "Burkina Faso",
238
+ "alpha-2": "BF",
239
+ "alpha-3": "BFA",
240
+ "country-code": "854"
241
+ },
242
+ {
243
+ "name": "Burundi",
244
+ "alpha-2": "BI",
245
+ "alpha-3": "BDI",
246
+ "country-code": "108"
247
+ },
248
+ {
249
+ "name": "Cabo Verde",
250
+ "alpha-2": "CV",
251
+ "alpha-3": "CPV",
252
+ "country-code": "132"
253
+ },
254
+ {
255
+ "name": "Cambodia",
256
+ "alpha-2": "KH",
257
+ "alpha-3": "KHM",
258
+ "country-code": "116"
259
+ },
260
+ {
261
+ "name": "Cameroon",
262
+ "alpha-2": "CM",
263
+ "alpha-3": "CMR",
264
+ "country-code": "120"
265
+ },
266
+ {
267
+ "name": "Canada",
268
+ "alpha-2": "CA",
269
+ "alpha-3": "CAN",
270
+ "country-code": "124"
271
+ },
272
+ {
273
+ "name": "Cayman Islands",
274
+ "alpha-2": "KY",
275
+ "alpha-3": "CYM",
276
+ "country-code": "136"
277
+ },
278
+ {
279
+ "name": "Central African Republic",
280
+ "alpha-2": "CF",
281
+ "alpha-3": "CAF",
282
+ "country-code": "140"
283
+ },
284
+ {
285
+ "name": "Chad",
286
+ "alpha-2": "TD",
287
+ "alpha-3": "TCD",
288
+ "country-code": "148"
289
+ },
290
+ {
291
+ "name": "Chile",
292
+ "alpha-2": "CL",
293
+ "alpha-3": "CHL",
294
+ "country-code": "152"
295
+ },
296
+ {
297
+ "name": "China",
298
+ "alpha-2": "CN",
299
+ "alpha-3": "CHN",
300
+ "country-code": "156"
301
+ },
302
+ {
303
+ "name": "Christmas Island",
304
+ "alpha-2": "CX",
305
+ "alpha-3": "CXR",
306
+ "country-code": "162"
307
+ },
308
+ {
309
+ "name": "Cocos (Keeling) Islands",
310
+ "alpha-2": "CC",
311
+ "alpha-3": "CCK",
312
+ "country-code": "166"
313
+ },
314
+ {
315
+ "name": "Colombia",
316
+ "alpha-2": "CO",
317
+ "alpha-3": "COL",
318
+ "country-code": "170"
319
+ },
320
+ {
321
+ "name": "Comoros",
322
+ "alpha-2": "KM",
323
+ "alpha-3": "COM",
324
+ "country-code": "174"
325
+ },
326
+ {
327
+ "name": "Congo",
328
+ "alpha-2": "CG",
329
+ "alpha-3": "COG",
330
+ "country-code": "178"
331
+ },
332
+ {
333
+ "name": "Congo, Democratic Republic of the",
334
+ "alpha-2": "CD",
335
+ "alpha-3": "COD",
336
+ "country-code": "180"
337
+ },
338
+ {
339
+ "name": "Cook Islands",
340
+ "alpha-2": "CK",
341
+ "alpha-3": "COK",
342
+ "country-code": "184"
343
+ },
344
+ {
345
+ "name": "Costa Rica",
346
+ "alpha-2": "CR",
347
+ "alpha-3": "CRI",
348
+ "country-code": "188"
349
+ },
350
+ {
351
+ "name": "Côte d'Ivoire",
352
+ "alpha-2": "CI",
353
+ "alpha-3": "CIV",
354
+ "country-code": "384"
355
+ },
356
+ {
357
+ "name": "Croatia",
358
+ "alpha-2": "HR",
359
+ "alpha-3": "HRV",
360
+ "country-code": "191"
361
+ },
362
+ {
363
+ "name": "Cuba",
364
+ "alpha-2": "CU",
365
+ "alpha-3": "CUB",
366
+ "country-code": "192"
367
+ },
368
+ {
369
+ "name": "Curaçao",
370
+ "alpha-2": "CW",
371
+ "alpha-3": "CUW",
372
+ "country-code": "531"
373
+ },
374
+ {
375
+ "name": "Cyprus",
376
+ "alpha-2": "CY",
377
+ "alpha-3": "CYP",
378
+ "country-code": "196"
379
+ },
380
+ {
381
+ "name": "Czechia",
382
+ "alpha-2": "CZ",
383
+ "alpha-3": "CZE",
384
+ "country-code": "203"
385
+ },
386
+ {
387
+ "name": "Denmark",
388
+ "alpha-2": "DK",
389
+ "alpha-3": "DNK",
390
+ "country-code": "208"
391
+ },
392
+ {
393
+ "name": "Djibouti",
394
+ "alpha-2": "DJ",
395
+ "alpha-3": "DJI",
396
+ "country-code": "262"
397
+ },
398
+ {
399
+ "name": "Dominica",
400
+ "alpha-2": "DM",
401
+ "alpha-3": "DMA",
402
+ "country-code": "212"
403
+ },
404
+ {
405
+ "name": "Dominican Republic",
406
+ "alpha-2": "DO",
407
+ "alpha-3": "DOM",
408
+ "country-code": "214"
409
+ },
410
+ {
411
+ "name": "Ecuador",
412
+ "alpha-2": "EC",
413
+ "alpha-3": "ECU",
414
+ "country-code": "218"
415
+ },
416
+ {
417
+ "name": "Egypt",
418
+ "alpha-2": "EG",
419
+ "alpha-3": "EGY",
420
+ "country-code": "818"
421
+ },
422
+ {
423
+ "name": "El Salvador",
424
+ "alpha-2": "SV",
425
+ "alpha-3": "SLV",
426
+ "country-code": "222"
427
+ },
428
+ {
429
+ "name": "Equatorial Guinea",
430
+ "alpha-2": "GQ",
431
+ "alpha-3": "GNQ",
432
+ "country-code": "226"
433
+ },
434
+ {
435
+ "name": "Eritrea",
436
+ "alpha-2": "ER",
437
+ "alpha-3": "ERI",
438
+ "country-code": "232"
439
+ },
440
+ {
441
+ "name": "Estonia",
442
+ "alpha-2": "EE",
443
+ "alpha-3": "EST",
444
+ "country-code": "233"
445
+ },
446
+ {
447
+ "name": "Eswatini",
448
+ "alpha-2": "SZ",
449
+ "alpha-3": "SWZ",
450
+ "country-code": "748"
451
+ },
452
+ {
453
+ "name": "Ethiopia",
454
+ "alpha-2": "ET",
455
+ "alpha-3": "ETH",
456
+ "country-code": "231"
457
+ },
458
+ {
459
+ "name": "Falkland Islands (Malvinas)",
460
+ "alpha-2": "FK",
461
+ "alpha-3": "FLK",
462
+ "country-code": "238"
463
+ },
464
+ {
465
+ "name": "Faroe Islands",
466
+ "alpha-2": "FO",
467
+ "alpha-3": "FRO",
468
+ "country-code": "234"
469
+ },
470
+ {
471
+ "name": "Fiji",
472
+ "alpha-2": "FJ",
473
+ "alpha-3": "FJI",
474
+ "country-code": "242"
475
+ },
476
+ {
477
+ "name": "Finland",
478
+ "alpha-2": "FI",
479
+ "alpha-3": "FIN",
480
+ "country-code": "246"
481
+ },
482
+ {
483
+ "name": "France",
484
+ "alpha-2": "FR",
485
+ "alpha-3": "FRA",
486
+ "country-code": "250"
487
+ },
488
+ {
489
+ "name": "French Guiana",
490
+ "alpha-2": "GF",
491
+ "alpha-3": "GUF",
492
+ "country-code": "254"
493
+ },
494
+ {
495
+ "name": "French Polynesia",
496
+ "alpha-2": "PF",
497
+ "alpha-3": "PYF",
498
+ "country-code": "258"
499
+ },
500
+ {
501
+ "name": "French Southern Territories",
502
+ "alpha-2": "TF",
503
+ "alpha-3": "ATF",
504
+ "country-code": "260"
505
+ },
506
+ {
507
+ "name": "Gabon",
508
+ "alpha-2": "GA",
509
+ "alpha-3": "GAB",
510
+ "country-code": "266"
511
+ },
512
+ {
513
+ "name": "Gambia",
514
+ "alpha-2": "GM",
515
+ "alpha-3": "GMB",
516
+ "country-code": "270"
517
+ },
518
+ {
519
+ "name": "Georgia",
520
+ "alpha-2": "GE",
521
+ "alpha-3": "GEO",
522
+ "country-code": "268"
523
+ },
524
+ {
525
+ "name": "Germany",
526
+ "alpha-2": "DE",
527
+ "alpha-3": "DEU",
528
+ "country-code": "276"
529
+ },
530
+ {
531
+ "name": "Ghana",
532
+ "alpha-2": "GH",
533
+ "alpha-3": "GHA",
534
+ "country-code": "288"
535
+ },
536
+ {
537
+ "name": "Gibraltar",
538
+ "alpha-2": "GI",
539
+ "alpha-3": "GIB",
540
+ "country-code": "292"
541
+ },
542
+ {
543
+ "name": "Greece",
544
+ "alpha-2": "GR",
545
+ "alpha-3": "GRC",
546
+ "country-code": "300"
547
+ },
548
+ {
549
+ "name": "Greenland",
550
+ "alpha-2": "GL",
551
+ "alpha-3": "GRL",
552
+ "country-code": "304"
553
+ },
554
+ {
555
+ "name": "Grenada",
556
+ "alpha-2": "GD",
557
+ "alpha-3": "GRD",
558
+ "country-code": "308"
559
+ },
560
+ {
561
+ "name": "Guadeloupe",
562
+ "alpha-2": "GP",
563
+ "alpha-3": "GLP",
564
+ "country-code": "312"
565
+ },
566
+ {
567
+ "name": "Guam",
568
+ "alpha-2": "GU",
569
+ "alpha-3": "GUM",
570
+ "country-code": "316"
571
+ },
572
+ {
573
+ "name": "Guatemala",
574
+ "alpha-2": "GT",
575
+ "alpha-3": "GTM",
576
+ "country-code": "320"
577
+ },
578
+ {
579
+ "name": "Guernsey",
580
+ "alpha-2": "GG",
581
+ "alpha-3": "GGY",
582
+ "country-code": "831"
583
+ },
584
+ {
585
+ "name": "Guinea",
586
+ "alpha-2": "GN",
587
+ "alpha-3": "GIN",
588
+ "country-code": "324"
589
+ },
590
+ {
591
+ "name": "Guinea-Bissau",
592
+ "alpha-2": "GW",
593
+ "alpha-3": "GNB",
594
+ "country-code": "624"
595
+ },
596
+ {
597
+ "name": "Guyana",
598
+ "alpha-2": "GY",
599
+ "alpha-3": "GUY",
600
+ "country-code": "328"
601
+ },
602
+ {
603
+ "name": "Haiti",
604
+ "alpha-2": "HT",
605
+ "alpha-3": "HTI",
606
+ "country-code": "332"
607
+ },
608
+ {
609
+ "name": "Heard Island and McDonald Islands",
610
+ "alpha-2": "HM",
611
+ "alpha-3": "HMD",
612
+ "country-code": "334"
613
+ },
614
+ {
615
+ "name": "Holy See",
616
+ "alpha-2": "VA",
617
+ "alpha-3": "VAT",
618
+ "country-code": "336"
619
+ },
620
+ {
621
+ "name": "Honduras",
622
+ "alpha-2": "HN",
623
+ "alpha-3": "HND",
624
+ "country-code": "340"
625
+ },
626
+ {
627
+ "name": "Hong Kong",
628
+ "alpha-2": "HK",
629
+ "alpha-3": "HKG",
630
+ "country-code": "344"
631
+ },
632
+ {
633
+ "name": "Hungary",
634
+ "alpha-2": "HU",
635
+ "alpha-3": "HUN",
636
+ "country-code": "348"
637
+ },
638
+ {
639
+ "name": "Iceland",
640
+ "alpha-2": "IS",
641
+ "alpha-3": "ISL",
642
+ "country-code": "352"
643
+ },
644
+ {
645
+ "name": "India",
646
+ "alpha-2": "IN",
647
+ "alpha-3": "IND",
648
+ "country-code": "356"
649
+ },
650
+ {
651
+ "name": "Indonesia",
652
+ "alpha-2": "ID",
653
+ "alpha-3": "IDN",
654
+ "country-code": "360"
655
+ },
656
+ {
657
+ "name": "Iran (Islamic Republic of)",
658
+ "alpha-2": "IR",
659
+ "alpha-3": "IRN",
660
+ "country-code": "364"
661
+ },
662
+ {
663
+ "name": "Iraq",
664
+ "alpha-2": "IQ",
665
+ "alpha-3": "IRQ",
666
+ "country-code": "368"
667
+ },
668
+ {
669
+ "name": "Ireland",
670
+ "alpha-2": "IE",
671
+ "alpha-3": "IRL",
672
+ "country-code": "372"
673
+ },
674
+ {
675
+ "name": "Isle of Man",
676
+ "alpha-2": "IM",
677
+ "alpha-3": "IMN",
678
+ "country-code": "833"
679
+ },
680
+ {
681
+ "name": "Israel",
682
+ "alpha-2": "IL",
683
+ "alpha-3": "ISR",
684
+ "country-code": "376"
685
+ },
686
+ {
687
+ "name": "Italy",
688
+ "alpha-2": "IT",
689
+ "alpha-3": "ITA",
690
+ "country-code": "380"
691
+ },
692
+ {
693
+ "name": "Jamaica",
694
+ "alpha-2": "JM",
695
+ "alpha-3": "JAM",
696
+ "country-code": "388"
697
+ },
698
+ {
699
+ "name": "Japan",
700
+ "alpha-2": "JP",
701
+ "alpha-3": "JPN",
702
+ "country-code": "392"
703
+ },
704
+ {
705
+ "name": "Jersey",
706
+ "alpha-2": "JE",
707
+ "alpha-3": "JEY",
708
+ "country-code": "832"
709
+ },
710
+ {
711
+ "name": "Jordan",
712
+ "alpha-2": "JO",
713
+ "alpha-3": "JOR",
714
+ "country-code": "400"
715
+ },
716
+ {
717
+ "name": "Kazakhstan",
718
+ "alpha-2": "KZ",
719
+ "alpha-3": "KAZ",
720
+ "country-code": "398"
721
+ },
722
+ {
723
+ "name": "Kenya",
724
+ "alpha-2": "KE",
725
+ "alpha-3": "KEN",
726
+ "country-code": "404"
727
+ },
728
+ {
729
+ "name": "Kiribati",
730
+ "alpha-2": "KI",
731
+ "alpha-3": "KIR",
732
+ "country-code": "296"
733
+ },
734
+ {
735
+ "name": "Korea (Democratic People's Republic of)",
736
+ "alpha-2": "KP",
737
+ "alpha-3": "PRK",
738
+ "country-code": "408"
739
+ },
740
+ {
741
+ "name": "Korea, Republic of",
742
+ "alpha-2": "KR",
743
+ "alpha-3": "KOR",
744
+ "country-code": "410"
745
+ },
746
+ {
747
+ "name": "Kuwait",
748
+ "alpha-2": "KW",
749
+ "alpha-3": "KWT",
750
+ "country-code": "414"
751
+ },
752
+ {
753
+ "name": "Kyrgyzstan",
754
+ "alpha-2": "KG",
755
+ "alpha-3": "KGZ",
756
+ "country-code": "417"
757
+ },
758
+ {
759
+ "name": "Lao People's Democratic Republic",
760
+ "alpha-2": "LA",
761
+ "alpha-3": "LAO",
762
+ "country-code": "418"
763
+ },
764
+ {
765
+ "name": "Latvia",
766
+ "alpha-2": "LV",
767
+ "alpha-3": "LVA",
768
+ "country-code": "428"
769
+ },
770
+ {
771
+ "name": "Lebanon",
772
+ "alpha-2": "LB",
773
+ "alpha-3": "LBN",
774
+ "country-code": "422"
775
+ },
776
+ {
777
+ "name": "Lesotho",
778
+ "alpha-2": "LS",
779
+ "alpha-3": "LSO",
780
+ "country-code": "426"
781
+ },
782
+ {
783
+ "name": "Liberia",
784
+ "alpha-2": "LR",
785
+ "alpha-3": "LBR",
786
+ "country-code": "430"
787
+ },
788
+ {
789
+ "name": "Libya",
790
+ "alpha-2": "LY",
791
+ "alpha-3": "LBY",
792
+ "country-code": "434"
793
+ },
794
+ {
795
+ "name": "Liechtenstein",
796
+ "alpha-2": "LI",
797
+ "alpha-3": "LIE",
798
+ "country-code": "438"
799
+ },
800
+ {
801
+ "name": "Lithuania",
802
+ "alpha-2": "LT",
803
+ "alpha-3": "LTU",
804
+ "country-code": "440"
805
+ },
806
+ {
807
+ "name": "Luxembourg",
808
+ "alpha-2": "LU",
809
+ "alpha-3": "LUX",
810
+ "country-code": "442"
811
+ },
812
+ {
813
+ "name": "Macao",
814
+ "alpha-2": "MO",
815
+ "alpha-3": "MAC",
816
+ "country-code": "446"
817
+ },
818
+ {
819
+ "name": "Madagascar",
820
+ "alpha-2": "MG",
821
+ "alpha-3": "MDG",
822
+ "country-code": "450"
823
+ },
824
+ {
825
+ "name": "Malawi",
826
+ "alpha-2": "MW",
827
+ "alpha-3": "MWI",
828
+ "country-code": "454"
829
+ },
830
+ {
831
+ "name": "Malaysia",
832
+ "alpha-2": "MY",
833
+ "alpha-3": "MYS",
834
+ "country-code": "458"
835
+ },
836
+ {
837
+ "name": "Maldives",
838
+ "alpha-2": "MV",
839
+ "alpha-3": "MDV",
840
+ "country-code": "462"
841
+ },
842
+ {
843
+ "name": "Mali",
844
+ "alpha-2": "ML",
845
+ "alpha-3": "MLI",
846
+ "country-code": "466"
847
+ },
848
+ {
849
+ "name": "Malta",
850
+ "alpha-2": "MT",
851
+ "alpha-3": "MLT",
852
+ "country-code": "470"
853
+ },
854
+ {
855
+ "name": "Marshall Islands",
856
+ "alpha-2": "MH",
857
+ "alpha-3": "MHL",
858
+ "country-code": "584"
859
+ },
860
+ {
861
+ "name": "Martinique",
862
+ "alpha-2": "MQ",
863
+ "alpha-3": "MTQ",
864
+ "country-code": "474"
865
+ },
866
+ {
867
+ "name": "Mauritania",
868
+ "alpha-2": "MR",
869
+ "alpha-3": "MRT",
870
+ "country-code": "478"
871
+ },
872
+ {
873
+ "name": "Mauritius",
874
+ "alpha-2": "MU",
875
+ "alpha-3": "MUS",
876
+ "country-code": "480"
877
+ },
878
+ {
879
+ "name": "Mayotte",
880
+ "alpha-2": "YT",
881
+ "alpha-3": "MYT",
882
+ "country-code": "175"
883
+ },
884
+ {
885
+ "name": "Mexico",
886
+ "alpha-2": "MX",
887
+ "alpha-3": "MEX",
888
+ "country-code": "484"
889
+ },
890
+ {
891
+ "name": "Micronesia (Federated States of)",
892
+ "alpha-2": "FM",
893
+ "alpha-3": "FSM",
894
+ "country-code": "583"
895
+ },
896
+ {
897
+ "name": "Moldova, Republic of",
898
+ "alpha-2": "MD",
899
+ "alpha-3": "MDA",
900
+ "country-code": "498"
901
+ },
902
+ {
903
+ "name": "Monaco",
904
+ "alpha-2": "MC",
905
+ "alpha-3": "MCO",
906
+ "country-code": "492"
907
+ },
908
+ {
909
+ "name": "Mongolia",
910
+ "alpha-2": "MN",
911
+ "alpha-3": "MNG",
912
+ "country-code": "496"
913
+ },
914
+ {
915
+ "name": "Montenegro",
916
+ "alpha-2": "ME",
917
+ "alpha-3": "MNE",
918
+ "country-code": "499"
919
+ },
920
+ {
921
+ "name": "Montserrat",
922
+ "alpha-2": "MS",
923
+ "alpha-3": "MSR",
924
+ "country-code": "500"
925
+ },
926
+ {
927
+ "name": "Morocco",
928
+ "alpha-2": "MA",
929
+ "alpha-3": "MAR",
930
+ "country-code": "504"
931
+ },
932
+ {
933
+ "name": "Mozambique",
934
+ "alpha-2": "MZ",
935
+ "alpha-3": "MOZ",
936
+ "country-code": "508"
937
+ },
938
+ {
939
+ "name": "Myanmar",
940
+ "alpha-2": "MM",
941
+ "alpha-3": "MMR",
942
+ "country-code": "104"
943
+ },
944
+ {
945
+ "name": "Namibia",
946
+ "alpha-2": "NA",
947
+ "alpha-3": "NAM",
948
+ "country-code": "516"
949
+ },
950
+ {
951
+ "name": "Nauru",
952
+ "alpha-2": "NR",
953
+ "alpha-3": "NRU",
954
+ "country-code": "520"
955
+ },
956
+ {
957
+ "name": "Nepal",
958
+ "alpha-2": "NP",
959
+ "alpha-3": "NPL",
960
+ "country-code": "524"
961
+ },
962
+ {
963
+ "name": "Netherlands",
964
+ "alpha-2": "NL",
965
+ "alpha-3": "NLD",
966
+ "country-code": "528"
967
+ },
968
+ {
969
+ "name": "New Caledonia",
970
+ "alpha-2": "NC",
971
+ "alpha-3": "NCL",
972
+ "country-code": "540"
973
+ },
974
+ {
975
+ "name": "New Zealand",
976
+ "alpha-2": "NZ",
977
+ "alpha-3": "NZL",
978
+ "country-code": "554"
979
+ },
980
+ {
981
+ "name": "Nicaragua",
982
+ "alpha-2": "NI",
983
+ "alpha-3": "NIC",
984
+ "country-code": "558"
985
+ },
986
+ {
987
+ "name": "Niger",
988
+ "alpha-2": "NE",
989
+ "alpha-3": "NER",
990
+ "country-code": "562"
991
+ },
992
+ {
993
+ "name": "Nigeria",
994
+ "alpha-2": "NG",
995
+ "alpha-3": "NGA",
996
+ "country-code": "566"
997
+ },
998
+ {
999
+ "name": "Niue",
1000
+ "alpha-2": "NU",
1001
+ "alpha-3": "NIU",
1002
+ "country-code": "570"
1003
+ },
1004
+ {
1005
+ "name": "Norfolk Island",
1006
+ "alpha-2": "NF",
1007
+ "alpha-3": "NFK",
1008
+ "country-code": "574"
1009
+ },
1010
+ {
1011
+ "name": "North Macedonia",
1012
+ "alpha-2": "MK",
1013
+ "alpha-3": "MKD",
1014
+ "country-code": "807"
1015
+ },
1016
+ {
1017
+ "name": "Northern Mariana Islands",
1018
+ "alpha-2": "MP",
1019
+ "alpha-3": "MNP",
1020
+ "country-code": "580"
1021
+ },
1022
+ {
1023
+ "name": "Norway",
1024
+ "alpha-2": "NO",
1025
+ "alpha-3": "NOR",
1026
+ "country-code": "578"
1027
+ },
1028
+ {
1029
+ "name": "Oman",
1030
+ "alpha-2": "OM",
1031
+ "alpha-3": "OMN",
1032
+ "country-code": "512"
1033
+ },
1034
+ {
1035
+ "name": "Pakistan",
1036
+ "alpha-2": "PK",
1037
+ "alpha-3": "PAK",
1038
+ "country-code": "586"
1039
+ },
1040
+ {
1041
+ "name": "Palau",
1042
+ "alpha-2": "PW",
1043
+ "alpha-3": "PLW",
1044
+ "country-code": "585"
1045
+ },
1046
+ {
1047
+ "name": "Palestine, State of",
1048
+ "alpha-2": "PS",
1049
+ "alpha-3": "PSE",
1050
+ "country-code": "275"
1051
+ },
1052
+ {
1053
+ "name": "Panama",
1054
+ "alpha-2": "PA",
1055
+ "alpha-3": "PAN",
1056
+ "country-code": "591"
1057
+ },
1058
+ {
1059
+ "name": "Papua New Guinea",
1060
+ "alpha-2": "PG",
1061
+ "alpha-3": "PNG",
1062
+ "country-code": "598"
1063
+ },
1064
+ {
1065
+ "name": "Paraguay",
1066
+ "alpha-2": "PY",
1067
+ "alpha-3": "PRY",
1068
+ "country-code": "600"
1069
+ },
1070
+ {
1071
+ "name": "Peru",
1072
+ "alpha-2": "PE",
1073
+ "alpha-3": "PER",
1074
+ "country-code": "604"
1075
+ },
1076
+ {
1077
+ "name": "Philippines",
1078
+ "alpha-2": "PH",
1079
+ "alpha-3": "PHL",
1080
+ "country-code": "608"
1081
+ },
1082
+ {
1083
+ "name": "Pitcairn",
1084
+ "alpha-2": "PN",
1085
+ "alpha-3": "PCN",
1086
+ "country-code": "612"
1087
+ },
1088
+ {
1089
+ "name": "Poland",
1090
+ "alpha-2": "PL",
1091
+ "alpha-3": "POL",
1092
+ "country-code": "616"
1093
+ },
1094
+ {
1095
+ "name": "Portugal",
1096
+ "alpha-2": "PT",
1097
+ "alpha-3": "PRT",
1098
+ "country-code": "620"
1099
+ },
1100
+ {
1101
+ "name": "Puerto Rico",
1102
+ "alpha-2": "PR",
1103
+ "alpha-3": "PRI",
1104
+ "country-code": "630"
1105
+ },
1106
+ {
1107
+ "name": "Qatar",
1108
+ "alpha-2": "QA",
1109
+ "alpha-3": "QAT",
1110
+ "country-code": "634"
1111
+ },
1112
+ {
1113
+ "name": "Réunion",
1114
+ "alpha-2": "RE",
1115
+ "alpha-3": "REU",
1116
+ "country-code": "638"
1117
+ },
1118
+ {
1119
+ "name": "Romania",
1120
+ "alpha-2": "RO",
1121
+ "alpha-3": "ROU",
1122
+ "country-code": "642"
1123
+ },
1124
+ {
1125
+ "name": "Russian Federation",
1126
+ "alpha-2": "RU",
1127
+ "alpha-3": "RUS",
1128
+ "country-code": "643"
1129
+ },
1130
+ {
1131
+ "name": "Rwanda",
1132
+ "alpha-2": "RW",
1133
+ "alpha-3": "RWA",
1134
+ "country-code": "646"
1135
+ },
1136
+ {
1137
+ "name": "Saint Barthélemy",
1138
+ "alpha-2": "BL",
1139
+ "alpha-3": "BLM",
1140
+ "country-code": "652"
1141
+ },
1142
+ {
1143
+ "name": "Saint Helena, Ascension and Tristan da Cunha",
1144
+ "alpha-2": "SH",
1145
+ "alpha-3": "SHN",
1146
+ "country-code": "654"
1147
+ },
1148
+ {
1149
+ "name": "Saint Kitts and Nevis",
1150
+ "alpha-2": "KN",
1151
+ "alpha-3": "KNA",
1152
+ "country-code": "659"
1153
+ },
1154
+ {
1155
+ "name": "Saint Lucia",
1156
+ "alpha-2": "LC",
1157
+ "alpha-3": "LCA",
1158
+ "country-code": "662"
1159
+ },
1160
+ {
1161
+ "name": "Saint Martin (French part)",
1162
+ "alpha-2": "MF",
1163
+ "alpha-3": "MAF",
1164
+ "country-code": "663"
1165
+ },
1166
+ {
1167
+ "name": "Saint Pierre and Miquelon",
1168
+ "alpha-2": "PM",
1169
+ "alpha-3": "SPM",
1170
+ "country-code": "666"
1171
+ },
1172
+ {
1173
+ "name": "Saint Vincent and the Grenadines",
1174
+ "alpha-2": "VC",
1175
+ "alpha-3": "VCT",
1176
+ "country-code": "670"
1177
+ },
1178
+ {
1179
+ "name": "Samoa",
1180
+ "alpha-2": "WS",
1181
+ "alpha-3": "WSM",
1182
+ "country-code": "882"
1183
+ },
1184
+ {
1185
+ "name": "San Marino",
1186
+ "alpha-2": "SM",
1187
+ "alpha-3": "SMR",
1188
+ "country-code": "674"
1189
+ },
1190
+ {
1191
+ "name": "Sao Tome and Principe",
1192
+ "alpha-2": "ST",
1193
+ "alpha-3": "STP",
1194
+ "country-code": "678"
1195
+ },
1196
+ {
1197
+ "name": "Saudi Arabia",
1198
+ "alpha-2": "SA",
1199
+ "alpha-3": "SAU",
1200
+ "country-code": "682"
1201
+ },
1202
+ {
1203
+ "name": "Senegal",
1204
+ "alpha-2": "SN",
1205
+ "alpha-3": "SEN",
1206
+ "country-code": "686"
1207
+ },
1208
+ {
1209
+ "name": "Serbia",
1210
+ "alpha-2": "RS",
1211
+ "alpha-3": "SRB",
1212
+ "country-code": "688"
1213
+ },
1214
+ {
1215
+ "name": "Seychelles",
1216
+ "alpha-2": "SC",
1217
+ "alpha-3": "SYC",
1218
+ "country-code": "690"
1219
+ },
1220
+ {
1221
+ "name": "Sierra Leone",
1222
+ "alpha-2": "SL",
1223
+ "alpha-3": "SLE",
1224
+ "country-code": "694"
1225
+ },
1226
+ {
1227
+ "name": "Singapore",
1228
+ "alpha-2": "SG",
1229
+ "alpha-3": "SGP",
1230
+ "country-code": "702"
1231
+ },
1232
+ {
1233
+ "name": "Sint Maarten (Dutch part)",
1234
+ "alpha-2": "SX",
1235
+ "alpha-3": "SXM",
1236
+ "country-code": "534"
1237
+ },
1238
+ {
1239
+ "name": "Slovakia",
1240
+ "alpha-2": "SK",
1241
+ "alpha-3": "SVK",
1242
+ "country-code": "703"
1243
+ },
1244
+ {
1245
+ "name": "Slovenia",
1246
+ "alpha-2": "SI",
1247
+ "alpha-3": "SVN",
1248
+ "country-code": "705"
1249
+ },
1250
+ {
1251
+ "name": "Solomon Islands",
1252
+ "alpha-2": "SB",
1253
+ "alpha-3": "SLB",
1254
+ "country-code": "090"
1255
+ },
1256
+ {
1257
+ "name": "Somalia",
1258
+ "alpha-2": "SO",
1259
+ "alpha-3": "SOM",
1260
+ "country-code": "706"
1261
+ },
1262
+ {
1263
+ "name": "South Africa",
1264
+ "alpha-2": "ZA",
1265
+ "alpha-3": "ZAF",
1266
+ "country-code": "710"
1267
+ },
1268
+ {
1269
+ "name": "South Georgia and the South Sandwich Islands",
1270
+ "alpha-2": "GS",
1271
+ "alpha-3": "SGS",
1272
+ "country-code": "239"
1273
+ },
1274
+ {
1275
+ "name": "South Sudan",
1276
+ "alpha-2": "SS",
1277
+ "alpha-3": "SSD",
1278
+ "country-code": "728"
1279
+ },
1280
+ {
1281
+ "name": "Spain",
1282
+ "alpha-2": "ES",
1283
+ "alpha-3": "ESP",
1284
+ "country-code": "724"
1285
+ },
1286
+ {
1287
+ "name": "Sri Lanka",
1288
+ "alpha-2": "LK",
1289
+ "alpha-3": "LKA",
1290
+ "country-code": "144"
1291
+ },
1292
+ {
1293
+ "name": "Sudan",
1294
+ "alpha-2": "SD",
1295
+ "alpha-3": "SDN",
1296
+ "country-code": "729"
1297
+ },
1298
+ {
1299
+ "name": "Suriname",
1300
+ "alpha-2": "SR",
1301
+ "alpha-3": "SUR",
1302
+ "country-code": "740"
1303
+ },
1304
+ {
1305
+ "name": "Svalbard and Jan Mayen",
1306
+ "alpha-2": "SJ",
1307
+ "alpha-3": "SJM",
1308
+ "country-code": "744"
1309
+ },
1310
+ {
1311
+ "name": "Sweden",
1312
+ "alpha-2": "SE",
1313
+ "alpha-3": "SWE",
1314
+ "country-code": "752"
1315
+ },
1316
+ {
1317
+ "name": "Switzerland",
1318
+ "alpha-2": "CH",
1319
+ "alpha-3": "CHE",
1320
+ "country-code": "756"
1321
+ },
1322
+ {
1323
+ "name": "Syrian Arab Republic",
1324
+ "alpha-2": "SY",
1325
+ "alpha-3": "SYR",
1326
+ "country-code": "760"
1327
+ },
1328
+ {
1329
+ "name": "Taiwan",
1330
+ "alpha-2": "TW",
1331
+ "alpha-3": "TWN",
1332
+ "country-code": "158"
1333
+ },
1334
+ {
1335
+ "name": "Tajikistan",
1336
+ "alpha-2": "TJ",
1337
+ "alpha-3": "TJK",
1338
+ "country-code": "762"
1339
+ },
1340
+ {
1341
+ "name": "Tanzania, United Republic of",
1342
+ "alpha-2": "TZ",
1343
+ "alpha-3": "TZA",
1344
+ "country-code": "834"
1345
+ },
1346
+ {
1347
+ "name": "Thailand",
1348
+ "alpha-2": "TH",
1349
+ "alpha-3": "THA",
1350
+ "country-code": "764"
1351
+ },
1352
+ {
1353
+ "name": "Timor-Leste",
1354
+ "alpha-2": "TL",
1355
+ "alpha-3": "TLS",
1356
+ "country-code": "626"
1357
+ },
1358
+ {
1359
+ "name": "Togo",
1360
+ "alpha-2": "TG",
1361
+ "alpha-3": "TGO",
1362
+ "country-code": "768"
1363
+ },
1364
+ {
1365
+ "name": "Tokelau",
1366
+ "alpha-2": "TK",
1367
+ "alpha-3": "TKL",
1368
+ "country-code": "772"
1369
+ },
1370
+ {
1371
+ "name": "Tonga",
1372
+ "alpha-2": "TO",
1373
+ "alpha-3": "TON",
1374
+ "country-code": "776"
1375
+ },
1376
+ {
1377
+ "name": "Trinidad and Tobago",
1378
+ "alpha-2": "TT",
1379
+ "alpha-3": "TTO",
1380
+ "country-code": "780"
1381
+ },
1382
+ {
1383
+ "name": "Tunisia",
1384
+ "alpha-2": "TN",
1385
+ "alpha-3": "TUN",
1386
+ "country-code": "788"
1387
+ },
1388
+ {
1389
+ "name": "Turkey",
1390
+ "alpha-2": "TR",
1391
+ "alpha-3": "TUR",
1392
+ "country-code": "792"
1393
+ },
1394
+ {
1395
+ "name": "Turkmenistan",
1396
+ "alpha-2": "TM",
1397
+ "alpha-3": "TKM",
1398
+ "country-code": "795"
1399
+ },
1400
+ {
1401
+ "name": "Turks and Caicos Islands",
1402
+ "alpha-2": "TC",
1403
+ "alpha-3": "TCA",
1404
+ "country-code": "796"
1405
+ },
1406
+ {
1407
+ "name": "Tuvalu",
1408
+ "alpha-2": "TV",
1409
+ "alpha-3": "TUV",
1410
+ "country-code": "798"
1411
+ },
1412
+ {
1413
+ "name": "Uganda",
1414
+ "alpha-2": "UG",
1415
+ "alpha-3": "UGA",
1416
+ "country-code": "800"
1417
+ },
1418
+ {
1419
+ "name": "Ukraine",
1420
+ "alpha-2": "UA",
1421
+ "alpha-3": "UKR",
1422
+ "country-code": "804"
1423
+ },
1424
+ {
1425
+ "name": "United Arab Emirates",
1426
+ "alpha-2": "AE",
1427
+ "alpha-3": "ARE",
1428
+ "country-code": "784"
1429
+ },
1430
+ {
1431
+ "name": "United Kingdom",
1432
+ "alpha-2": "GB",
1433
+ "alpha-3": "GBR",
1434
+ "country-code": "826"
1435
+ },
1436
+ {
1437
+ "name": "America",
1438
+ "alpha-2": "US",
1439
+ "alpha-3": "USA",
1440
+ "country-code": "840"
1441
+ },
1442
+ {
1443
+ "name": "United States Minor Outlying Islands",
1444
+ "alpha-2": "UM",
1445
+ "alpha-3": "UMI",
1446
+ "country-code": "581"
1447
+ },
1448
+ {
1449
+ "name": "Uruguay",
1450
+ "alpha-2": "UY",
1451
+ "alpha-3": "URY",
1452
+ "country-code": "858"
1453
+ },
1454
+ {
1455
+ "name": "Uzbekistan",
1456
+ "alpha-2": "UZ",
1457
+ "alpha-3": "UZB",
1458
+ "country-code": "860"
1459
+ },
1460
+ {
1461
+ "name": "Vanuatu",
1462
+ "alpha-2": "VU",
1463
+ "alpha-3": "VUT",
1464
+ "country-code": "548"
1465
+ },
1466
+ {
1467
+ "name": "Venezuela (Bolivarian Republic of)",
1468
+ "alpha-2": "VE",
1469
+ "alpha-3": "VEN",
1470
+ "country-code": "862"
1471
+ },
1472
+ {
1473
+ "name": "Vietnam",
1474
+ "alpha-2": "VN",
1475
+ "alpha-3": "VNM",
1476
+ "country-code": "704"
1477
+ },
1478
+ {
1479
+ "name": "Virgin Islands (British)",
1480
+ "alpha-2": "VG",
1481
+ "alpha-3": "VGB",
1482
+ "country-code": "092"
1483
+ },
1484
+ {
1485
+ "name": "Virgin Islands (U.S.)",
1486
+ "alpha-2": "VI",
1487
+ "alpha-3": "VIR",
1488
+ "country-code": "850"
1489
+ },
1490
+ {
1491
+ "name": "Wallis and Futuna",
1492
+ "alpha-2": "WF",
1493
+ "alpha-3": "WLF",
1494
+ "country-code": "876"
1495
+ },
1496
+ {
1497
+ "name": "Western Sahara",
1498
+ "alpha-2": "EH",
1499
+ "alpha-3": "ESH",
1500
+ "country-code": "732"
1501
+ },
1502
+ {
1503
+ "name": "Yemen",
1504
+ "alpha-2": "YE",
1505
+ "alpha-3": "YEM",
1506
+ "country-code": "887"
1507
+ },
1508
+ {
1509
+ "name": "Zambia",
1510
+ "alpha-2": "ZM",
1511
+ "alpha-3": "ZMB",
1512
+ "country-code": "894"
1513
+ },
1514
+ {
1515
+ "name": "Zimbabwe",
1516
+ "alpha-2": "ZW",
1517
+ "alpha-3": "ZWE",
1518
+ "country-code": "716"
1519
+ }
1520
+ ];
1521
+ const SearchTypes = {
1522
+ WEB: "web",
1523
+ IMAGE: "image",
1524
+ VIDEO: "video",
1525
+ NEWS: "news",
1526
+ DISCOVER: "discover",
1527
+ GOOGLE_NEWS: "googleNews"
1528
+ };
1529
+ Object.fromEntries(countries_default.map((c) => [c["alpha-3"], c["alpha-3"].toLowerCase()]));
1530
+ const TIME_AXIS_DIMENSIONS = new Set(["date", "hour"]);
1531
+ const queryErrors = {
1532
+ missingDateRange() {
1533
+ return {
1534
+ kind: "missing-date-range",
1535
+ message: "Date range required: use .where(between(date, start, end)) or .where(and(gte(date, start), lte(date, end)))"
1536
+ };
1537
+ },
1538
+ invalidRowLimit(value) {
1539
+ return {
1540
+ kind: "invalid-row-limit",
1541
+ value,
1542
+ message: `rowLimit must be a positive integer, got ${value}`
1543
+ };
1544
+ },
1545
+ invalidStartRow(value) {
1546
+ return {
1547
+ kind: "invalid-start-row",
1548
+ value,
1549
+ message: `startRow must be a non-negative integer, got ${value}`
1550
+ };
1551
+ },
1552
+ hourDimensionRequiresHourlyState() {
1553
+ return {
1554
+ kind: "invalid-data-state",
1555
+ message: "hour dimension requires dataState: \"hourly_all\""
1556
+ };
1557
+ },
1558
+ hourlyStateRequiresHourDimension() {
1559
+ return {
1560
+ kind: "invalid-data-state",
1561
+ message: "dataState: \"hourly_all\" requires grouping by hour dimension"
1562
+ };
1563
+ },
1564
+ byPropertyUnsupportedSearchType() {
1565
+ return {
1566
+ kind: "invalid-aggregation-type",
1567
+ message: "aggregationType: \"byProperty\" is not supported for type \"discover\" or \"googleNews\""
1568
+ };
1569
+ },
1570
+ byPropertyNotAllowedWithPage() {
1571
+ return {
1572
+ kind: "invalid-aggregation-type",
1573
+ message: "aggregationType: \"byProperty\" is not allowed when grouping or filtering by page"
1574
+ };
1575
+ },
1576
+ byNewsShowcaseRequiresSearchType() {
1577
+ return {
1578
+ kind: "invalid-aggregation-type",
1579
+ message: "aggregationType: \"byNewsShowcasePanel\" requires type \"discover\" or \"googleNews\""
1580
+ };
1581
+ },
1582
+ byNewsShowcaseNotAllowedWithPage() {
1583
+ return {
1584
+ kind: "invalid-aggregation-type",
1585
+ message: "aggregationType: \"byNewsShowcasePanel\" is not allowed when grouping or filtering by page"
1586
+ };
1587
+ },
1588
+ byNewsShowcaseRequiresShowcaseFilter() {
1589
+ return {
1590
+ kind: "invalid-aggregation-type",
1591
+ message: "aggregationType: \"byNewsShowcasePanel\" requires a searchAppearance equals \"NEWS_SHOWCASE\" filter and no other searchAppearance filter"
1592
+ };
1593
+ },
1594
+ invalidBuilderState(cause) {
1595
+ return {
1596
+ kind: "invalid-builder-state",
1597
+ cause,
1598
+ message: "Invalid state"
1599
+ };
1600
+ },
1601
+ unsupportedCapability(capability, context) {
1602
+ return {
1603
+ kind: "unsupported-capability",
1604
+ capability,
1605
+ context,
1606
+ message: `${context} requires ${capability} capability`
1607
+ };
1608
+ },
1609
+ unresolvableDataset(dimensions, filterDims = []) {
1610
+ const grouped = dimensions.filter((d) => !TIME_AXIS_DIMENSIONS.has(d));
1611
+ const filtered = filterDims.filter((d) => !TIME_AXIS_DIMENSIONS.has(d));
1612
+ return {
1613
+ kind: "unresolvable-dataset",
1614
+ dimensions,
1615
+ filterDims,
1616
+ message: `Cannot resolve a [${grouped.join(", ")}] breakdown filtered by [${filtered.join(", ")}] from stored data: these dimensions live in separate per-dimension tables. Only the live GSC API computes cross-dimension aggregates.`
1617
+ };
1618
+ }
1619
+ };
1620
+ var UnsupportedLogicalCapabilityError = class extends Error {
1621
+ queryError;
1622
+ constructor(capability, context) {
1623
+ const error = queryErrors.unsupportedCapability(capability, context);
1624
+ super(error.message);
1625
+ this.name = "UnsupportedLogicalCapabilityError";
1626
+ this.queryError = error;
1627
+ }
1628
+ };
1629
+ var UnresolvableDatasetError = class extends Error {
1630
+ queryError;
1631
+ constructor(dimensions, filterDims = []) {
1632
+ const error = queryErrors.unresolvableDataset(dimensions, filterDims);
1633
+ super(error.message);
1634
+ this.name = "UnresolvableDatasetError";
1635
+ this.queryError = error;
1636
+ }
1637
+ };
1638
+ function queryErrorToException(error) {
1639
+ switch (error.kind) {
1640
+ case "unsupported-capability": return new UnsupportedLogicalCapabilityError(error.capability, error.context);
1641
+ case "unresolvable-dataset": return new UnresolvableDatasetError(error.dimensions, error.filterDims);
1642
+ default: {
1643
+ const exception = new Error(error.message);
1644
+ if ("cause" in error && error.cause !== void 0) exception.cause = error.cause;
1645
+ exception.queryError = error;
1646
+ return exception;
1647
+ }
1648
+ }
1649
+ }
1650
+ const DATE_OPERATORS = [
1651
+ "gte",
1652
+ "gt",
1653
+ "lte",
1654
+ "lt",
1655
+ "between"
1656
+ ];
1657
+ const METRIC_OPERATORS = [
1658
+ "metricGte",
1659
+ "metricGt",
1660
+ "metricLte",
1661
+ "metricLt",
1662
+ "metricBetween"
1663
+ ];
1664
+ const SPECIAL_OPERATORS = ["topLevel"];
1665
+ const QUERY_PARAMS = ["searchType"];
1666
+ function isDateOperator(op) {
1667
+ return DATE_OPERATORS.includes(op);
1668
+ }
1669
+ function isMetricOperator(op) {
1670
+ return METRIC_OPERATORS.includes(op);
1671
+ }
1672
+ function isSpecialOperator(op) {
1673
+ return SPECIAL_OPERATORS.includes(op);
1674
+ }
1675
+ function isQueryParam(value) {
1676
+ return QUERY_PARAMS.includes(value);
1677
+ }
1678
+ new Set(Object.values(SearchTypes));
1679
+ function extractSpecialFilters(filter) {
1680
+ if (!filter) return {};
1681
+ let startDate;
1682
+ let endDate;
1683
+ let searchType;
1684
+ const otherFilters = [];
1685
+ const cleanedNestedGroups = [];
1686
+ for (const f of filter._filters) if (f.dimension === "date" && isDateOperator(f.operator)) switch (f.operator) {
1687
+ case "gte":
1688
+ startDate = f.expression;
1689
+ break;
1690
+ case "gt":
1691
+ startDate = addDays(f.expression, 1);
1692
+ break;
1693
+ case "lte":
1694
+ endDate = f.expression;
1695
+ break;
1696
+ case "lt":
1697
+ endDate = addDays(f.expression, -1);
1698
+ break;
1699
+ case "between":
1700
+ startDate = f.expression;
1701
+ endDate = f.expression2;
1702
+ break;
1703
+ }
1704
+ else if (isQueryParam(f.dimension)) {
1705
+ if (f.dimension === "searchType") searchType = f.expression;
1706
+ } else if (isMetricOperator(f.operator) || isSpecialOperator(f.operator)) otherFilters.push(f);
1707
+ else otherFilters.push(f);
1708
+ if (filter._nestedGroups) for (const nested of filter._nestedGroups) {
1709
+ const extracted = extractSpecialFilters(nested);
1710
+ if (!startDate && extracted.startDate) startDate = extracted.startDate;
1711
+ if (!endDate && extracted.endDate) endDate = extracted.endDate;
1712
+ if (!searchType && extracted.searchType) searchType = extracted.searchType;
1713
+ if (extracted.dimensionFilter) cleanedNestedGroups.push(extracted.dimensionFilter);
1714
+ }
1715
+ const dimensionFilter = otherFilters.length > 0 || cleanedNestedGroups.length > 0 ? {
1716
+ ...filter,
1717
+ _filters: otherFilters,
1718
+ _nestedGroups: cleanedNestedGroups.length > 0 ? cleanedNestedGroups : void 0
1719
+ } : void 0;
1720
+ return {
1721
+ startDate,
1722
+ endDate,
1723
+ searchType,
1724
+ dimensionFilter
1725
+ };
1726
+ }
1727
+ function resolveToBodyResult(state) {
1728
+ const { startDate, endDate, searchType, dimensionFilter } = extractSpecialFilters(state.filter);
1729
+ if (!startDate || !endDate) return err(queryErrors.missingDateRange());
1730
+ const body = {
1731
+ dimensions: state.dimensions,
1732
+ startDate,
1733
+ endDate
1734
+ };
1735
+ const resolvedType = state.searchType ?? searchType;
1736
+ if (resolvedType) body.type = resolvedType;
1737
+ if (state.rowLimit !== void 0) {
1738
+ if (!Number.isInteger(state.rowLimit) || state.rowLimit < 1) return err(queryErrors.invalidRowLimit(state.rowLimit));
1739
+ body.rowLimit = state.rowLimit;
1740
+ }
1741
+ if (state.startRow !== void 0) {
1742
+ if (!Number.isInteger(state.startRow) || state.startRow < 0) return err(queryErrors.invalidStartRow(state.startRow));
1743
+ if (state.startRow > 0) body.startRow = state.startRow;
1744
+ }
1745
+ const hasHour = state.dimensions?.includes("hour");
1746
+ if (hasHour && state.dataState !== "hourly_all") return err(queryErrors.hourDimensionRequiresHourlyState());
1747
+ if (state.dataState === "hourly_all" && !hasHour) return err(queryErrors.hourlyStateRequiresHourDimension());
1748
+ if (state.dataState) body.dataState = state.dataState;
1749
+ const filterGroups = resolveFilter(dimensionFilter);
1750
+ if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
1751
+ if (state.aggregationType) {
1752
+ const groupsByPage = (body.dimensions ?? []).includes("page");
1753
+ const apiLeafFilters = filterGroups.flatMap((g) => g.filters ?? []);
1754
+ const filtersByPage = apiLeafFilters.some((f) => f.dimension === "page");
1755
+ if (state.aggregationType === "byProperty") {
1756
+ if (body.type === "discover" || body.type === "googleNews") return err(queryErrors.byPropertyUnsupportedSearchType());
1757
+ if (groupsByPage || filtersByPage) return err(queryErrors.byPropertyNotAllowedWithPage());
1758
+ }
1759
+ if (state.aggregationType === "byNewsShowcasePanel") {
1760
+ if (body.type !== "discover" && body.type !== "googleNews") return err(queryErrors.byNewsShowcaseRequiresSearchType());
1761
+ if (groupsByPage || filtersByPage) return err(queryErrors.byNewsShowcaseNotAllowedWithPage());
1762
+ const saFilters = apiLeafFilters.filter((f) => f.dimension === "searchAppearance");
1763
+ const hasNewsShowcase = saFilters.some((f) => f.operator === "equals" && f.expression === "NEWS_SHOWCASE");
1764
+ const hasOther = saFilters.some((f) => !(f.operator === "equals" && f.expression === "NEWS_SHOWCASE"));
1765
+ if (!hasNewsShowcase || hasOther) return err(queryErrors.byNewsShowcaseRequiresShowcaseFilter());
1766
+ }
1767
+ body.aggregationType = state.aggregationType;
1768
+ }
1769
+ return ok(body);
1770
+ }
1771
+ function resolveToBody(state) {
1772
+ return unwrapResult(resolveToBodyResult(state), queryErrorToException);
1773
+ }
1774
+ function isApiFilter(f) {
1775
+ return !isMetricOperator(f.operator) && !isSpecialOperator(f.operator);
1776
+ }
1777
+ function resolveFilter(filter) {
1778
+ if (!filter) return [];
1779
+ const groups = [];
1780
+ const groupType = filter._groupType ?? "and";
1781
+ const apiFilters = filter._filters.filter(isApiFilter);
1782
+ if (groupType === "or") {
1783
+ if (apiFilters.length > 0) groups.push({
1784
+ groupType: "or",
1785
+ filters: apiFilters.map((f) => ({
1786
+ dimension: f.dimension,
1787
+ operator: f.operator,
1788
+ expression: f.expression
1789
+ }))
1790
+ });
1791
+ } else if (apiFilters.length > 0) groups.push({ filters: apiFilters.map((f) => ({
1792
+ dimension: f.dimension,
1793
+ operator: f.operator,
1794
+ expression: f.expression
1795
+ })) });
1796
+ if (filter._nestedGroups) for (const nested of filter._nestedGroups) groups.push(...resolveFilter(nested));
1797
+ return groups;
1798
+ }
1799
+ function rowWithMetricDefaults(row) {
1800
+ return {
1801
+ clicks: row.clicks ?? 0,
1802
+ impressions: row.impressions ?? 0,
1803
+ ctr: row.ctr ?? 0,
1804
+ position: row.position ?? 0
1805
+ };
1806
+ }
1807
+ const TRAILING_SLASH_RE = /\/$/;
1808
+ function gscdumpApi(options) {
1809
+ const baseUrl = options.baseUrl?.replace(TRAILING_SLASH_RE, "") || "https://gscdump.com";
1810
+ const fetch = ofetch.create({
1811
+ baseURL: baseUrl,
1812
+ retry: 3,
1813
+ retryDelay: 1e3,
1814
+ retryStatusCodes: [
1815
+ 408,
1816
+ 409,
1817
+ 425,
1818
+ 429,
1819
+ 500,
1820
+ 502,
1821
+ 503,
1822
+ 504
1823
+ ],
1824
+ headers: {
1825
+ "x-api-key": options.apiKey,
1826
+ "Content-Type": "application/json"
1827
+ }
1828
+ });
1829
+ const rawQuery = async (siteId, body, opts) => {
1830
+ const response = await fetch(`/api/sites/${encodeURIComponent(siteId)}/query`, {
1831
+ method: "POST",
1832
+ body,
1833
+ signal: opts?.signal
1834
+ });
1835
+ return { rows: response.rows.map((row) => {
1836
+ return {
1837
+ keys: response.meta.dimensions.map((dim) => String(row[dim] ?? "")),
1838
+ clicks: row.clicks,
1839
+ impressions: row.impressions,
1840
+ ctr: row.ctr,
1841
+ position: row.position
1842
+ };
1843
+ }) };
1844
+ };
1845
+ return {
1846
+ async *query(siteId, builder, opts) {
1847
+ const state = builder.getState();
1848
+ const body = resolveToBody(state);
1849
+ const totalCap = body.rowLimit;
1850
+ const pageSize = Math.min(totalCap ?? 25e3, 25e3);
1851
+ let startRow = body.startRow || 0;
1852
+ let yielded = 0;
1853
+ let metadata;
1854
+ while (true) {
1855
+ opts?.signal?.throwIfAborted();
1856
+ const remaining = totalCap ? totalCap - yielded : pageSize;
1857
+ if (remaining <= 0) break;
1858
+ const rowLimit = Math.min(pageSize, remaining);
1859
+ const response = await fetch(`/api/sites/${encodeURIComponent(siteId)}/query`, {
1860
+ method: "POST",
1861
+ body: {
1862
+ ...body,
1863
+ startRow,
1864
+ rowLimit
1865
+ },
1866
+ signal: opts?.signal
1867
+ });
1868
+ if (response.metadata) metadata = response.metadata;
1869
+ const rows = response.rows.map((row) => {
1870
+ const result = rowWithMetricDefaults(row);
1871
+ state.dimensions.forEach((dim) => {
1872
+ result[dim] = row[dim];
1873
+ });
1874
+ return result;
1875
+ });
1876
+ yield rows;
1877
+ yielded += rows.length;
1878
+ if (!response.meta.hasMore || rows.length < rowLimit) break;
1879
+ startRow += rows.length;
1880
+ }
1881
+ return { metadata };
1882
+ },
1883
+ sites: (() => {
1884
+ const list = async (opts) => {
1885
+ return (await fetch("/api/sites", { signal: opts?.signal })).sites.map((s) => ({
1886
+ siteUrl: s.gscSiteUrl,
1887
+ permissionLevel: s.permissionLevel || "siteOwner"
1888
+ }));
1889
+ };
1890
+ const unsupported = (op) => () => {
1891
+ throw new Error(`sites.${op} not available via gscdump API. Use googleSearchConsole() with OAuth credentials.`);
1892
+ };
1893
+ return Object.assign(list, {
1894
+ list,
1895
+ get: unsupported("get"),
1896
+ add: unsupported("add"),
1897
+ delete: unsupported("delete")
1898
+ });
1899
+ })(),
1900
+ verification: {
1901
+ getToken: () => {
1902
+ throw new Error("Site Verification API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1903
+ },
1904
+ insert: () => {
1905
+ throw new Error("Site Verification API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1906
+ },
1907
+ list: () => {
1908
+ throw new Error("Site Verification API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1909
+ },
1910
+ get: () => {
1911
+ throw new Error("Site Verification API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1912
+ },
1913
+ delete: () => {
1914
+ throw new Error("Site Verification API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1915
+ }
1916
+ },
1917
+ inspect: () => {
1918
+ throw new Error("URL inspection not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1919
+ },
1920
+ sitemaps: {
1921
+ list: async (siteId, opts) => {
1922
+ return (await fetch(`/api/sites/${encodeURIComponent(siteId)}/sitemaps`, { signal: opts?.signal })).sitemaps || [];
1923
+ },
1924
+ get: () => {
1925
+ throw new Error("Sitemap get not available via gscdump API.");
1926
+ },
1927
+ submit: () => {
1928
+ throw new Error("Sitemap submit not available via gscdump API.");
1929
+ },
1930
+ delete: () => {
1931
+ throw new Error("Sitemap delete not available via gscdump API.");
1932
+ }
1933
+ },
1934
+ indexing: {
1935
+ publish: () => {
1936
+ throw new Error("Indexing API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1937
+ },
1938
+ getMetadata: () => {
1939
+ throw new Error("Indexing API not available via gscdump API. Use googleSearchConsole() with OAuth credentials.");
1940
+ }
1941
+ },
1942
+ _rawQuery: rawQuery
1943
+ };
1944
+ }
1945
+ const GSC_API = "https://searchconsole.googleapis.com";
1946
+ const INDEXING_API = "https://indexing.googleapis.com";
1947
+ const SITE_VERIFICATION_API = "https://www.googleapis.com/siteVerification/v1";
1948
+ function encodeSiteUrl(siteUrl) {
1949
+ if (siteUrl.startsWith("sc-domain:")) return `sc-domain:${encodeURIComponent(siteUrl.slice(10))}`;
1950
+ return encodeURIComponent(siteUrl);
1951
+ }
1952
+ function assertValidSiteUrl(siteUrl) {
1953
+ if (siteUrl.startsWith("sc-domain:") && siteUrl.length > 10) return;
1954
+ if (/^https?:\/\/.+/.test(siteUrl)) return;
1955
+ throw new Error(`Invalid siteUrl: expected "https?://…" or "sc-domain:…", got "${siteUrl}"`);
1956
+ }
1957
+ function createAuth(options) {
1958
+ let credentials = { refresh_token: options.refreshToken };
1959
+ return {
1960
+ get credentials() {
1961
+ return credentials;
1962
+ },
1963
+ async getAccessToken() {
1964
+ if (credentials?.access_token && credentials.expiry_date && credentials.expiry_date > Date.now()) return { token: credentials.access_token };
1965
+ const response = await ofetch("https://oauth2.googleapis.com/token", {
1966
+ method: "POST",
1967
+ body: {
1968
+ client_id: options.clientId,
1969
+ client_secret: options.clientSecret,
1970
+ refresh_token: options.refreshToken,
1971
+ grant_type: "refresh_token"
1972
+ }
1973
+ });
1974
+ credentials = {
1975
+ ...credentials,
1976
+ access_token: response.access_token,
1977
+ expiry_date: Date.now() + response.expires_in * 1e3
1978
+ };
1979
+ return { token: response.access_token };
1980
+ }
1981
+ };
1982
+ }
1983
+ async function resolveToken(auth) {
1984
+ if (typeof auth === "string") return auth;
1985
+ if ("accessToken" in auth && typeof auth.accessToken === "string") return auth.accessToken;
1986
+ if ("getAccessToken" in auth && typeof auth.getAccessToken === "function") {
1987
+ const { token } = await auth.getAccessToken();
1988
+ return token || "";
1989
+ }
1990
+ if ("credentials" in auth && auth.credentials) return auth.credentials.access_token || "";
1991
+ return "";
1992
+ }
1993
+ function createFetch(auth, options) {
1994
+ const authState = typeof auth === "object" && auth !== null && "clientId" in auth && "refreshToken" in auth && !("getAccessToken" in auth) ? createAuth(auth) : auth;
1995
+ return ofetch.create({
1996
+ ...options,
1997
+ retry: 3,
1998
+ retryDelay: (ctx) => {
1999
+ const status = ctx.response?.status;
2000
+ if (status === 429 || status === 503) {
2001
+ const header = ctx.response?.headers.get("retry-after");
2002
+ if (header) {
2003
+ const secs = Number.parseInt(header, 10);
2004
+ if (Number.isFinite(secs)) return secs * 1e3;
2005
+ const when = Date.parse(header);
2006
+ if (Number.isFinite(when)) return Math.max(0, when - Date.now());
2007
+ }
2008
+ }
2009
+ return 1e3;
2010
+ },
2011
+ retryStatusCodes: [
2012
+ 408,
2013
+ 425,
2014
+ 429,
2015
+ 500,
2016
+ 502,
2017
+ 503,
2018
+ 504
2019
+ ],
2020
+ headers: {
2021
+ ...options?.headers,
2022
+ "Accept-Encoding": "gzip",
2023
+ "User-Agent": "gscdump (gzip)"
2024
+ },
2025
+ async onRequest({ options }) {
2026
+ const token = await resolveToken(authState);
2027
+ if (token) {
2028
+ options.headers = new Headers(options.headers);
2029
+ options.headers.set("Authorization", `Bearer ${token}`);
2030
+ }
2031
+ },
2032
+ async onResponseError(ctx) {
2033
+ if (ctx.response.status === 403) console.error("[gscdump] Permission denied (403). check your service account permissions being added to the GSC property.");
2034
+ if (options?.onResponseError) if (Array.isArray(options.onResponseError)) for (const handler of options.onResponseError) await handler(ctx);
2035
+ else await options.onResponseError(ctx);
2036
+ }
2037
+ });
2038
+ }
2039
+ function googleSearchConsole(auth, options = {}) {
2040
+ let fetch;
2041
+ const authState = typeof auth === "object" && auth !== null && "clientId" in auth && "refreshToken" in auth && !("getAccessToken" in auth) ? createAuth(auth) : auth;
2042
+ if (options.fetch) fetch = options.fetch;
2043
+ else {
2044
+ const fetchOptions = options.fetchOptions || {};
2045
+ if (options.onRateLimited) {
2046
+ const originalOnError = fetchOptions.onResponseError;
2047
+ fetchOptions.onResponseError = async (ctx) => {
2048
+ if (ctx.response.status === 429) await options.onRateLimited({ response: ctx.response });
2049
+ if (originalOnError) if (Array.isArray(originalOnError)) for (const handler of originalOnError) await handler(ctx);
2050
+ else await originalOnError(ctx);
2051
+ };
2052
+ }
2053
+ fetch = createFetch(authState, fetchOptions);
2054
+ }
2055
+ const rawQuery = (siteUrl, body, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}/searchAnalytics/query`, {
2056
+ method: "POST",
2057
+ body,
2058
+ signal: opts?.signal
2059
+ });
2060
+ return {
2061
+ async *query(siteUrl, builder, opts) {
2062
+ const state = builder.getState();
2063
+ const body = resolveToBody(state);
2064
+ const totalCap = body.rowLimit;
2065
+ const pageSize = Math.min(totalCap ?? 25e3, 25e3);
2066
+ let startRow = body.startRow || 0;
2067
+ let yielded = 0;
2068
+ let metadata;
2069
+ let responseAggregationType;
2070
+ while (true) {
2071
+ opts?.signal?.throwIfAborted();
2072
+ const remaining = totalCap ? totalCap - yielded : pageSize;
2073
+ if (remaining <= 0) break;
2074
+ const rowLimit = Math.min(pageSize, remaining);
2075
+ const response = await rawQuery(siteUrl, {
2076
+ ...body,
2077
+ startRow,
2078
+ rowLimit
2079
+ }, opts);
2080
+ if (response.metadata) metadata = response.metadata;
2081
+ if (response.responseAggregationType) responseAggregationType = response.responseAggregationType;
2082
+ const rows = (response.rows || []).map((row) => {
2083
+ const result = rowWithMetricDefaults(row);
2084
+ state.dimensions.forEach((dim, i) => {
2085
+ result[dim] = row.keys?.[i];
2086
+ });
2087
+ return result;
2088
+ });
2089
+ if (rows.length === 0) break;
2090
+ yield rows;
2091
+ yielded += rows.length;
2092
+ startRow += rows.length;
2093
+ }
2094
+ return {
2095
+ metadata,
2096
+ responseAggregationType
2097
+ };
2098
+ },
2099
+ sites: (() => {
2100
+ const list = async (opts) => {
2101
+ return (await fetch(`${GSC_API}/webmasters/v3/sites`, { signal: opts?.signal })).siteEntry || [];
2102
+ };
2103
+ return Object.assign(list, {
2104
+ list,
2105
+ get: (siteUrl, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}`, { signal: opts?.signal }),
2106
+ add: (siteUrl, opts) => {
2107
+ assertValidSiteUrl(siteUrl);
2108
+ return fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}`, {
2109
+ method: "PUT",
2110
+ signal: opts?.signal
2111
+ });
2112
+ },
2113
+ delete: (siteUrl, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}`, {
2114
+ method: "DELETE",
2115
+ signal: opts?.signal
2116
+ })
2117
+ });
2118
+ })(),
2119
+ verification: {
2120
+ getToken: (params, opts) => fetch(`${SITE_VERIFICATION_API}/token`, {
2121
+ method: "POST",
2122
+ body: params,
2123
+ signal: opts?.signal
2124
+ }),
2125
+ insert: (params, opts) => fetch(`${SITE_VERIFICATION_API}/webResource`, {
2126
+ method: "POST",
2127
+ query: { verificationMethod: params.verificationMethod },
2128
+ body: { site: params.site },
2129
+ signal: opts?.signal
2130
+ }),
2131
+ list: async (opts) => {
2132
+ return (await fetch(`${SITE_VERIFICATION_API}/webResource`, { signal: opts?.signal })).items || [];
2133
+ },
2134
+ get: (id, opts) => fetch(`${SITE_VERIFICATION_API}/webResource/${encodeURIComponent(id)}`, { signal: opts?.signal }),
2135
+ delete: (id, opts) => fetch(`${SITE_VERIFICATION_API}/webResource/${encodeURIComponent(id)}`, {
2136
+ method: "DELETE",
2137
+ signal: opts?.signal
2138
+ })
2139
+ },
2140
+ inspect: (siteUrl, url, opts) => fetch(`${GSC_API}/v1/urlInspection/index:inspect`, {
2141
+ method: "POST",
2142
+ body: opts?.languageCode ? {
2143
+ inspectionUrl: url,
2144
+ siteUrl,
2145
+ languageCode: opts.languageCode
2146
+ } : {
2147
+ inspectionUrl: url,
2148
+ siteUrl
2149
+ },
2150
+ signal: opts?.signal
2151
+ }),
2152
+ sitemaps: {
2153
+ list: async (siteUrl, opts) => {
2154
+ return (await fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}/sitemaps`, {
2155
+ signal: opts?.signal,
2156
+ query: opts?.sitemapIndex ? { sitemapIndex: opts.sitemapIndex } : void 0
2157
+ })).sitemap || [];
2158
+ },
2159
+ get: (siteUrl, feedpath, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}/sitemaps/${encodeURIComponent(feedpath)}`, { signal: opts?.signal }),
2160
+ submit: (siteUrl, feedpath, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}/sitemaps/${encodeURIComponent(feedpath)}`, {
2161
+ method: "PUT",
2162
+ signal: opts?.signal
2163
+ }),
2164
+ delete: (siteUrl, feedpath, opts) => fetch(`${GSC_API}/webmasters/v3/sites/${encodeSiteUrl(siteUrl)}/sitemaps/${encodeURIComponent(feedpath)}`, {
2165
+ method: "DELETE",
2166
+ signal: opts?.signal
2167
+ })
2168
+ },
2169
+ indexing: {
2170
+ publish: (url, type, opts) => fetch(`${INDEXING_API}/v3/urlNotifications:publish`, {
2171
+ method: "POST",
2172
+ body: {
2173
+ url,
2174
+ type
2175
+ },
2176
+ signal: opts?.signal
2177
+ }),
2178
+ getMetadata: (url, opts) => fetch(`${INDEXING_API}/v3/urlNotifications/metadata`, {
2179
+ query: { url },
2180
+ signal: opts?.signal
2181
+ })
2182
+ },
2183
+ _rawQuery: rawQuery
2184
+ };
2185
+ }
2186
+ const GSC_QUOTAS = {
2187
+ searchAnalytics: 25e3,
2188
+ urlInspection: 2e3,
2189
+ indexing: 200
2190
+ };
2191
+ function pickField(error, paths, is) {
2192
+ if (!error || typeof error !== "object") return void 0;
2193
+ for (const path of paths) {
2194
+ let current = error;
2195
+ for (const key of path) {
2196
+ if (!current || typeof current !== "object") {
2197
+ current = void 0;
2198
+ break;
2199
+ }
2200
+ current = current[key];
2201
+ }
2202
+ if (is(current)) return current;
2203
+ }
2204
+ }
2205
+ const isNumber = (v) => typeof v === "number";
2206
+ const isString = (v) => typeof v === "string";
2207
+ function extractStatus(error) {
2208
+ return pickField(error, [
2209
+ ["statusCode"],
2210
+ ["status"],
2211
+ ["response", "status"],
2212
+ ["code"]
2213
+ ], isNumber);
2214
+ }
2215
+ function extractMessage(error) {
2216
+ if (!error) return "Unknown error";
2217
+ if (typeof error === "string") return error;
2218
+ if (error instanceof Error) return error.message;
2219
+ if (typeof error !== "object") return String(error);
2220
+ return pickField(error, [
2221
+ [
2222
+ "data",
2223
+ "error",
2224
+ "message"
2225
+ ],
2226
+ ["message"],
2227
+ ["statusMessage"]
2228
+ ], isString) ?? String(error);
2229
+ }
2230
+ function extractRetryAfter(error) {
2231
+ const raw = pickField(error, [
2232
+ ["headers", "retry-after"],
2233
+ ["headers", "Retry-After"],
2234
+ [
2235
+ "response",
2236
+ "headers",
2237
+ "retry-after"
2238
+ ],
2239
+ [
2240
+ "response",
2241
+ "headers",
2242
+ "Retry-After"
2243
+ ]
2244
+ ], (v) => typeof v === "number" || typeof v === "string");
2245
+ if (typeof raw === "number") return raw;
2246
+ if (typeof raw === "string") {
2247
+ const seconds = Number.parseInt(raw, 10);
2248
+ return Number.isNaN(seconds) ? void 0 : seconds;
2249
+ }
2250
+ }
2251
+ const QUOTA_MESSAGE_RE = /quota|rate\s*limit/i;
2252
+ const QUOTA_REASONS = new Set([
2253
+ "dailyLimitExceeded",
2254
+ "dailyLimitExceededUnreg",
2255
+ "rateLimitExceeded",
2256
+ "rateLimitExceededUnreg",
2257
+ "userRateLimitExceeded",
2258
+ "userRateLimitExceededUnreg",
2259
+ "quotaExceeded",
2260
+ "concurrentLimitExceeded",
2261
+ "variableTermLimitExceeded",
2262
+ "variableTermExpiredDailyExceeded",
2263
+ "servingLimitExceeded",
2264
+ "responseTooLarge",
2265
+ "limitExceeded",
2266
+ "batchSizeTooLarge",
2267
+ "RATE_LIMIT_EXCEEDED",
2268
+ "RESOURCE_EXHAUSTED"
2269
+ ]);
2270
+ function extractReason(cause) {
2271
+ const data = pickField(cause, [["data"]], (_v) => true);
2272
+ if (data) {
2273
+ const errorInfo = pickField(data, [["error", "details"]], (v) => Array.isArray(v));
2274
+ if (errorInfo) {
2275
+ const reason = errorInfo.find((d) => typeof d["@type"] === "string" && d["@type"].includes("ErrorInfo"))?.reason;
2276
+ if (typeof reason === "string") return reason;
2277
+ }
2278
+ const directErrors = pickField(data, [["error", "errors"]], (v) => Array.isArray(v));
2279
+ if (directErrors) {
2280
+ const reason = directErrors[0]?.reason;
2281
+ if (typeof reason === "string") return reason;
2282
+ }
2283
+ }
2284
+ }
2285
+ function isQuotaCondition(cause, message) {
2286
+ const reason = extractReason(cause);
2287
+ if (reason && QUOTA_REASONS.has(reason)) return true;
2288
+ return QUOTA_MESSAGE_RE.test(message);
2289
+ }
2290
+ function classifyError(cause) {
2291
+ const status = extractStatus(cause);
2292
+ const message = extractMessage(cause);
2293
+ if (status === 401) return {
2294
+ kind: "auth-expired",
2295
+ message,
2296
+ cause
2297
+ };
2298
+ if (status === 429) return {
2299
+ kind: "rate-limited",
2300
+ message,
2301
+ retryAfter: extractRetryAfter(cause),
2302
+ cause
2303
+ };
2304
+ if (status === 403) {
2305
+ if (isQuotaCondition(cause, message)) return {
2306
+ kind: "rate-limited",
2307
+ message,
2308
+ retryAfter: extractRetryAfter(cause),
2309
+ cause
2310
+ };
2311
+ return {
2312
+ kind: "auth-expired",
2313
+ message,
2314
+ cause
2315
+ };
2316
+ }
2317
+ if (status === 404 || status === 410) return {
2318
+ kind: "not-found",
2319
+ message,
2320
+ cause
2321
+ };
2322
+ if (status === 400 || status === 402 || status === 409 || status === 413 || status === 422) return {
2323
+ kind: "validation",
2324
+ message,
2325
+ cause
2326
+ };
2327
+ return {
2328
+ kind: "transport",
2329
+ message,
2330
+ status,
2331
+ cause
2332
+ };
2333
+ }
2334
+ function storageError(message, cause) {
2335
+ return {
2336
+ kind: "storage",
2337
+ message,
2338
+ cause
2339
+ };
2340
+ }
2341
+ function gscErrorToException(error) {
2342
+ const exception = new Error(error.message);
2343
+ if (error.cause !== void 0) exception.cause = error.cause;
2344
+ exception.gscError = error;
2345
+ return exception;
2346
+ }
2347
+ function parseGoogleError(text, httpStatus) {
2348
+ let parsed = null;
2349
+ try {
2350
+ parsed = JSON.parse(text);
2351
+ } catch {}
2352
+ if (!parsed || !("error" in parsed)) return {
2353
+ code: httpStatus ?? 500,
2354
+ message: text || "Unknown Google API error"
2355
+ };
2356
+ if (typeof parsed.error === "string") {
2357
+ const oauth = parsed;
2358
+ return {
2359
+ code: httpStatus ?? 400,
2360
+ message: oauth.error_description || oauth.error,
2361
+ reason: oauth.error
2362
+ };
2363
+ }
2364
+ const err = parsed.error;
2365
+ const errorInfo = err.details?.find((d) => d["@type"]?.includes("ErrorInfo"));
2366
+ return {
2367
+ code: err.code ?? httpStatus ?? 500,
2368
+ message: err.message || err.status || text || `HTTP ${httpStatus ?? "?"}`,
2369
+ reason: errorInfo?.reason,
2370
+ status: err.status
2371
+ };
2372
+ }
2373
+ var GscApiError = class extends Error {
2374
+ info;
2375
+ constructor(message, info) {
2376
+ super(message);
2377
+ this.info = info;
2378
+ this.name = "GscApiError";
2379
+ }
2380
+ };
2381
+ function rethrowAsGscApiError(prefix) {
2382
+ return (err) => {
2383
+ if (err instanceof GscApiError) throw err;
2384
+ const maybe = err;
2385
+ if (maybe && maybe.name === "FetchError") {
2386
+ const info = parseGoogleError(typeof maybe.data === "string" ? maybe.data : JSON.stringify(maybe.data ?? {}), maybe.statusCode);
2387
+ throw new GscApiError(`${prefix}: ${info.message}`, info);
2388
+ }
2389
+ throw err;
2390
+ };
2391
+ }
2392
+ const PERMISSION_SIGNALS = [
2393
+ "403 forbidden",
2394
+ "permission_denied",
2395
+ "does not have sufficient permission",
2396
+ "insufficient permission"
2397
+ ];
2398
+ function isPermissionDeniedError(err) {
2399
+ const msg = String(err?.message ?? err ?? "").toLowerCase();
2400
+ return PERMISSION_SIGNALS.some((s) => msg.includes(s));
2401
+ }
2402
+ function suggestionFor(err) {
2403
+ switch (err.kind) {
2404
+ case "auth-expired": return "Run `gscdump auth` to re-authenticate.";
2405
+ case "rate-limited": {
2406
+ const retryIn = err.retryAfter ? `${err.retryAfter}s` : "a few minutes";
2407
+ if (QUOTA_MESSAGE_RE.test(err.message)) {
2408
+ if (err.message.includes("Indexing API")) return `Indexing API quota exhausted (~${GSC_QUOTAS.indexing}/day). Try again tomorrow.`;
2409
+ return `Quota or rate limit hit (Search Analytics ~${GSC_QUOTAS.searchAnalytics}/day). Try again in ${retryIn}.`;
2410
+ }
2411
+ return `Rate limited. Slow down requests. Try again in ${retryIn}.`;
2412
+ }
2413
+ case "not-found":
2414
+ case "validation":
2415
+ case "storage":
2416
+ case "transport": return "";
2417
+ }
2418
+ }
2419
+ function formatErrorForCli(cause) {
2420
+ const err = classifyError(cause);
2421
+ const lines = [`\x1B[31m${err.message}\x1B[0m`];
2422
+ const suggestion = suggestionFor(err);
2423
+ if (suggestion) {
2424
+ lines.push("");
2425
+ lines.push(suggestion);
2426
+ }
2427
+ return lines.join("\n");
2428
+ }
2429
+ const SCHEME_RE = /^(sc-domain:|https?:\/\/)/;
2430
+ function parseGscSiteUrl(siteUrl) {
2431
+ const isDomain = siteUrl.startsWith("sc-domain:");
2432
+ let hostname = siteUrl;
2433
+ if (isDomain) hostname = siteUrl.slice(10);
2434
+ else try {
2435
+ hostname = new URL(siteUrl).hostname;
2436
+ } catch {
2437
+ hostname = siteUrl;
2438
+ }
2439
+ const displayLabel = siteUrl.replace(SCHEME_RE, "").replace(/\/$/, "");
2440
+ return {
2441
+ label: siteUrl,
2442
+ hostname,
2443
+ displayLabel,
2444
+ propertyType: isDomain ? "domain" : "url-prefix",
2445
+ isDomain
2446
+ };
2447
+ }
2448
+ function normalizeGscSiteUrl(siteUrl) {
2449
+ return siteUrl.replace(/^sc-domain:/, "").replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/$/, "").toLowerCase();
2450
+ }
2451
+ function normalizeRegistrationTarget(inputUrl) {
2452
+ const trimmed = inputUrl.trim();
2453
+ if (!trimmed) return null;
2454
+ const inputParsed = parseGscSiteUrl(trimmed);
2455
+ if (inputParsed.isDomain) return inputParsed.hostname.toLowerCase();
2456
+ return trimmed.match(/^(?:https?:\/\/)?([^/]+)/)?.[1]?.toLowerCase() ?? null;
2457
+ }
2458
+ const VERIFIED_PERMISSIONS = new Set([
2459
+ "siteOwner",
2460
+ "siteFullUser",
2461
+ "siteRestrictedUser"
2462
+ ]);
2463
+ function isVerifiedGscProperty(property) {
2464
+ return !!property?.permissionLevel && VERIFIED_PERMISSIONS.has(property.permissionLevel);
2465
+ }
2466
+ function isVerifiedGscPermission(level) {
2467
+ return !!level && VERIFIED_PERMISSIONS.has(level);
2468
+ }
2469
+ const stripWww = (d) => d.replace(/^www\./, "");
2470
+ function gscPropertyMatchesTarget(targetDomain, propertyUrl) {
2471
+ if (!propertyUrl) return false;
2472
+ const cleanTarget = stripWww(targetDomain);
2473
+ const parsed = parseGscSiteUrl(propertyUrl);
2474
+ if (parsed.isDomain) return cleanTarget === parsed.hostname || cleanTarget.endsWith(`.${parsed.hostname}`);
2475
+ const match = propertyUrl.match(/^https?:\/\/([^/]+)/);
2476
+ return !!match && stripWww(match[1].toLowerCase()) === cleanTarget;
2477
+ }
2478
+ function matchGscSite(siteUrl, gscSiteUrl) {
2479
+ if (!siteUrl || !gscSiteUrl) return false;
2480
+ const getHostname = (url) => {
2481
+ if (url.startsWith("sc-domain:")) return url.replace("sc-domain:", "");
2482
+ try {
2483
+ return new URL(url).hostname;
2484
+ } catch {
2485
+ return url;
2486
+ }
2487
+ };
2488
+ return gscPropertyMatchesTarget(getHostname(siteUrl), gscSiteUrl);
2489
+ }
2490
+ function pickBestGscProperty(origin, availableSites) {
2491
+ const matches = availableSites.filter((p) => matchGscSite(origin, p.siteUrl));
2492
+ if (!matches.length) return void 0;
2493
+ const isDomain = (p) => !!p.siteUrl?.startsWith("sc-domain:");
2494
+ const verified = matches.filter((p) => isVerifiedGscPermission(p.permissionLevel));
2495
+ const pool = verified.length ? verified : matches;
2496
+ return pool.find(isDomain) ?? pool[0];
2497
+ }
2498
+ function findBestGscProperty(targetDomain, properties) {
2499
+ const cleanTarget = stripWww(targetDomain);
2500
+ const domainProperty = properties.find((property) => {
2501
+ if (!property.siteUrl) return false;
2502
+ const parsed = parseGscSiteUrl(property.siteUrl);
2503
+ if (!parsed.isDomain) return false;
2504
+ return cleanTarget === parsed.hostname || cleanTarget.endsWith(`.${parsed.hostname}`);
2505
+ });
2506
+ const urlProperty = properties.find((property) => {
2507
+ if (!property.siteUrl) return false;
2508
+ const match = property.siteUrl.match(/^https?:\/\/([^/]+)/);
2509
+ return match && stripWww(match[1].toLowerCase()) === cleanTarget;
2510
+ });
2511
+ return {
2512
+ matchedSite: (isVerifiedGscProperty(domainProperty) ? domainProperty : isVerifiedGscProperty(urlProperty) ? urlProperty : domainProperty || urlProperty) ?? null,
2513
+ domainProperty: domainProperty ?? null,
2514
+ urlProperty: urlProperty ?? null
2515
+ };
2516
+ }
2517
+ function findExactGscProperty(propertyUrl, properties) {
2518
+ return properties.find((property) => property.siteUrl === propertyUrl) ?? null;
2519
+ }
2520
+ function formatGscPropertyCandidates(candidates) {
2521
+ return candidates.filter((c) => !!c).map((property) => `${property.siteUrl} (${property.permissionLevel})`).join(", ");
2522
+ }
2523
+ const URL_INSPECTION_DAILY_LIMIT = 2e3;
2524
+ const URL_INSPECTION_EFFECTIVE_LIMIT = 1800;
2525
+ const WEBMASTERS_READ = "https://www.googleapis.com/auth/webmasters.readonly";
2526
+ const WEBMASTERS_WRITE = "https://www.googleapis.com/auth/webmasters";
2527
+ const INDEXING = "https://www.googleapis.com/auth/indexing";
2528
+ function tokenize(scopes) {
2529
+ if (!scopes) return [];
2530
+ return scopes.split(/\s+/).filter(Boolean);
2531
+ }
2532
+ function hasScope(scopes, scope) {
2533
+ const tokens = tokenize(scopes);
2534
+ const suffix = scope.replace("https://www.googleapis.com/auth/", "");
2535
+ return tokens.includes(scope) || tokens.includes(suffix);
2536
+ }
2537
+ function hasGscReadScope(scopes) {
2538
+ return hasScope(scopes, WEBMASTERS_READ) || hasScope(scopes, WEBMASTERS_WRITE);
2539
+ }
2540
+ function hasGscWriteScope(scopes) {
2541
+ return hasScope(scopes, WEBMASTERS_WRITE);
2542
+ }
2543
+ function hasIndexingScope(scopes) {
2544
+ return hasScope(scopes, INDEXING);
2545
+ }
2546
+ const FETCH_TIMEOUT_MS = 1e4;
2547
+ const COMMON_PATHS = ["/sitemap.xml", "/sitemap_index.xml"];
2548
+ const SITEMAP_DIRECTIVE_RE = /^Sitemap:\s*(\S+)/im;
2549
+ async function discoverSitemap(domain, options = {}) {
2550
+ const userAgent = options.userAgent ?? "gscdump sitemap fetcher";
2551
+ const baseUrl = `https://${domain}`;
2552
+ const signalFor = () => options.signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS);
2553
+ const robotsRes = await fetch(`${baseUrl}/robots.txt`, {
2554
+ headers: { "User-Agent": userAgent },
2555
+ signal: signalFor()
2556
+ }).catch(() => null);
2557
+ if (robotsRes?.ok) {
2558
+ const match = (await robotsRes.text()).match(SITEMAP_DIRECTIVE_RE);
2559
+ if (match?.[1]) {
2560
+ if ((await fetch(match[1], {
2561
+ method: "HEAD",
2562
+ signal: signalFor()
2563
+ }).catch(() => null))?.ok) return match[1];
2564
+ }
2565
+ }
2566
+ for (const path of COMMON_PATHS) {
2567
+ const url = `${baseUrl}${path}`;
2568
+ if ((await fetch(url, {
2569
+ method: "HEAD",
2570
+ headers: { "User-Agent": userAgent },
2571
+ signal: signalFor()
2572
+ }).catch(() => null))?.ok) return url;
2573
+ }
2574
+ return null;
2575
+ }
2576
+ const LOC_RE = /<loc>([^<]+)<\/loc>/gi;
2577
+ const SITEMAPINDEX_RE = /<sitemapindex\b/i;
2578
+ async function fetchSitemapUrls(sitemapUrl, options = {}) {
2579
+ const userAgent = options.userAgent ?? "gscdump sitemap fetcher";
2580
+ const maxDepth = options.maxDepth ?? 3;
2581
+ const limit = options.limit;
2582
+ const signalFor = () => options.signal ?? AbortSignal.timeout(FETCH_TIMEOUT_MS);
2583
+ const seen = /* @__PURE__ */ new Set();
2584
+ const out = [];
2585
+ const visit = async (url, depth) => {
2586
+ if (limit != null && out.length >= limit) return;
2587
+ if (depth > maxDepth) return;
2588
+ const res = await fetch(url, {
2589
+ headers: { "User-Agent": userAgent },
2590
+ signal: signalFor()
2591
+ });
2592
+ if (!res.ok) throw new Error(`Fetch ${url} failed: ${res.status}`);
2593
+ const text = await res.text();
2594
+ const isIndex = SITEMAPINDEX_RE.test(text);
2595
+ const matches = [...text.matchAll(LOC_RE)].map((m) => m[1].trim()).filter(Boolean);
2596
+ if (isIndex) {
2597
+ for (const child of matches) {
2598
+ if (limit != null && out.length >= limit) return;
2599
+ await visit(child, depth + 1);
2600
+ }
2601
+ return;
2602
+ }
2603
+ for (const u of matches) {
2604
+ if (seen.has(u)) continue;
2605
+ seen.add(u);
2606
+ out.push(u);
2607
+ if (limit != null && out.length >= limit) return;
2608
+ }
2609
+ };
2610
+ await visit(sitemapUrl, 0);
2611
+ return out;
2612
+ }
2613
+ function urlMatchKey(url) {
2614
+ const u = URL.parse(url);
2615
+ if (!u) return null;
2616
+ return [u.hostname.replace(/^www\./, ""), u.pathname.replace(/\/$/, "") || "/"].join("").toLowerCase();
2617
+ }
2618
+ async function runSequentialBatch(items, operation, options = {}) {
2619
+ const { delayMs = 0, concurrency = 1, onProgress } = options;
2620
+ const results = Array.from({ length: items.length });
2621
+ let completed = 0;
2622
+ if (concurrency <= 1) {
2623
+ for (let i = 0; i < items.length; i++) {
2624
+ const result = await operation(items[i], i);
2625
+ results[i] = result;
2626
+ onProgress?.(result, i, items.length);
2627
+ if (i < items.length - 1 && delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
2628
+ }
2629
+ return results;
2630
+ }
2631
+ const cursor = { i: 0 };
2632
+ const worker = async () => {
2633
+ while (true) {
2634
+ const i = cursor.i++;
2635
+ if (i >= items.length) return;
2636
+ const result = await operation(items[i], i);
2637
+ results[i] = result;
2638
+ completed++;
2639
+ onProgress?.(result, completed - 1, items.length);
2640
+ if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
2641
+ }
2642
+ };
2643
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, worker));
2644
+ return results;
2645
+ }
2646
+ async function requestIndexing(client, url, options = {}) {
2647
+ const { type = "URL_UPDATED" } = options;
2648
+ return client.indexing.publish(url, type).then((r) => ({
2649
+ url,
2650
+ type,
2651
+ notifyTime: r.urlNotificationMetadata?.latestUpdate?.notifyTime || void 0
2652
+ }));
2653
+ }
2654
+ async function getIndexingMetadata(client, url) {
2655
+ return client.indexing.getMetadata(url).then((r) => ({
2656
+ url,
2657
+ latestUpdate: r.latestUpdate || void 0,
2658
+ latestRemove: r.latestRemove || void 0
2659
+ }));
2660
+ }
2661
+ async function batchRequestIndexing(client, urls, options = {}) {
2662
+ const { type = "URL_UPDATED", delayMs = 100, concurrency, onProgress } = options;
2663
+ return runSequentialBatch(urls, (url) => requestIndexing(client, url, { type }), {
2664
+ delayMs,
2665
+ concurrency,
2666
+ onProgress
2667
+ });
2668
+ }
2669
+ async function inspectUrl(client, siteUrl, inspectionUrl) {
2670
+ const inspection = (await client.inspect(siteUrl, inspectionUrl)).inspectionResult;
2671
+ return {
2672
+ inspection,
2673
+ isIndexed: inspection?.indexStatusResult?.verdict === "PASS"
2674
+ };
2675
+ }
2676
+ async function batchInspectUrls(client, siteUrl, urls, options = {}) {
2677
+ const { delayMs = 200, concurrency, onProgress } = options;
2678
+ return runSequentialBatch(urls, async (url) => {
2679
+ const { inspection, isIndexed } = await inspectUrl(client, siteUrl, url);
2680
+ return {
2681
+ url,
2682
+ inspection,
2683
+ isIndexed
2684
+ };
2685
+ }, {
2686
+ delayMs,
2687
+ concurrency,
2688
+ onProgress
2689
+ });
2690
+ }
2691
+ async function inspectUrlFlat(client, siteUrl, inspectionUrl) {
2692
+ const inspection = (await client.inspect(siteUrl, inspectionUrl)).inspectionResult;
2693
+ const index = inspection?.indexStatusResult;
2694
+ const mobile = inspection?.mobileUsabilityResult;
2695
+ const rich = inspection?.richResultsResult;
2696
+ const amp = inspection?.ampResult;
2697
+ return {
2698
+ url: inspectionUrl,
2699
+ verdict: index?.verdict ?? null,
2700
+ coverageState: index?.coverageState ?? null,
2701
+ indexingState: index?.indexingState ?? null,
2702
+ robotsTxtState: index?.robotsTxtState ?? null,
2703
+ pageFetchState: index?.pageFetchState ?? null,
2704
+ lastCrawlTime: index?.lastCrawlTime ?? null,
2705
+ crawlingUserAgent: index?.crawledAs ?? null,
2706
+ userCanonical: index?.userCanonical ?? null,
2707
+ googleCanonical: index?.googleCanonical ?? null,
2708
+ sitemaps: index?.sitemap?.length ? JSON.stringify(index.sitemap) : null,
2709
+ referringUrls: index?.referringUrls?.length ? JSON.stringify(index.referringUrls) : null,
2710
+ mobileVerdict: mobile?.verdict ?? null,
2711
+ mobileIssues: mobile?.issues?.length ? JSON.stringify(mobile.issues) : null,
2712
+ richResultsVerdict: rich?.verdict ?? null,
2713
+ richResultsItems: rich?.detectedItems?.length ? JSON.stringify(rich.detectedItems) : null,
2714
+ ampVerdict: amp?.verdict ?? null,
2715
+ ampUrl: amp?.ampUrl ?? null,
2716
+ ampIndexingState: amp?.indexingState ?? null,
2717
+ ampIndexStatusVerdict: amp?.ampIndexStatusVerdict ?? null,
2718
+ ampRobotsTxtState: amp?.robotsTxtState ?? null,
2719
+ ampPageFetchState: amp?.pageFetchState ?? null,
2720
+ ampLastCrawlTime: amp?.lastCrawlTime ?? null,
2721
+ ampIssues: amp?.issues?.length ? JSON.stringify(amp.issues) : null,
2722
+ inspectionResultLink: inspection?.inspectionResultLink ?? null
2723
+ };
2724
+ }
2725
+ function getNextCheckPriority(result) {
2726
+ if (!result.verdict || result.verdict === "VERDICT_UNSPECIFIED") return "medium";
2727
+ if (result.verdict === "FAIL" || result.verdict === "PARTIAL" || result.verdict === "NEUTRAL") return "high";
2728
+ if (result.verdict === "PASS") return "low";
2729
+ return "medium";
2730
+ }
2731
+ function getNextCheckAfter(priority) {
2732
+ const now = Math.floor(Date.now() / 1e3);
2733
+ switch (priority) {
2734
+ case "high": return now + 7 * 86400;
2735
+ case "medium": return now + 14 * 86400;
2736
+ case "low": return now + 30 * 86400;
2737
+ }
2738
+ }
2739
+ const INSPECTION_ALLOWED_PERMISSIONS = new Set([
2740
+ "siteOwner",
2741
+ "siteFullUser",
2742
+ "siteRestrictedUser"
2743
+ ]);
2744
+ function canUseUrlInspection(permissionLevel) {
2745
+ return !!permissionLevel && INSPECTION_ALLOWED_PERMISSIONS.has(permissionLevel);
2746
+ }
2747
+ function grantedScopeList(scopes) {
2748
+ return scopes?.split(/\s+/).map((s) => s.trim()).filter(Boolean) ?? [];
2749
+ }
2750
+ function getIndexingEligibility(grantedScopes, permissionLevel) {
2751
+ const scopes = grantedScopeList(grantedScopes);
2752
+ if (!hasIndexingScope(grantedScopes)) return {
2753
+ indexingEligible: false,
2754
+ indexingIneligibleReason: "missing_indexing_scope",
2755
+ indexingPermissionLevel: permissionLevel ?? null,
2756
+ grantedScopes: scopes
2757
+ };
2758
+ if (!canUseUrlInspection(permissionLevel)) return {
2759
+ indexingEligible: false,
2760
+ indexingIneligibleReason: "insufficient_gsc_permission",
2761
+ indexingPermissionLevel: permissionLevel ?? null,
2762
+ grantedScopes: scopes
2763
+ };
2764
+ return {
2765
+ indexingEligible: true,
2766
+ indexingPermissionLevel: permissionLevel ?? null,
2767
+ grantedScopes: scopes
2768
+ };
2769
+ }
2770
+ const OAUTH_TOKEN_URL = "https://oauth2.googleapis.com/token";
2771
+ const OAUTH_TIMEOUT_MS = 8e3;
2772
+ const OAUTH_MAX_ATTEMPTS = 3;
2773
+ const OAUTH_BACKOFF_MS = [
2774
+ 0,
2775
+ 400,
2776
+ 1500
2777
+ ];
2778
+ async function refreshAccessTokenResult(refreshToken, clientId, clientSecret) {
2779
+ return postOAuthTokenResult(new URLSearchParams({
2780
+ client_id: clientId,
2781
+ client_secret: clientSecret,
2782
+ refresh_token: refreshToken,
2783
+ grant_type: "refresh_token"
2784
+ }), "refresh");
2785
+ }
2786
+ async function refreshAccessToken(refreshToken, clientId, clientSecret) {
2787
+ return unwrapResult(await refreshAccessTokenResult(refreshToken, clientId, clientSecret), oauthErrorToException);
2788
+ }
2789
+ async function exchangeAuthCodeResult(code, clientId, clientSecret, redirectUri) {
2790
+ const result = await postOAuthTokenResult(new URLSearchParams({
2791
+ client_id: clientId,
2792
+ client_secret: clientSecret,
2793
+ code,
2794
+ redirect_uri: redirectUri,
2795
+ grant_type: "authorization_code"
2796
+ }), "exchange");
2797
+ if (!result.ok) return result;
2798
+ const refreshToken = result.value.refresh_token;
2799
+ return ok({
2800
+ ...result.value,
2801
+ refreshToken
2802
+ });
2803
+ }
2804
+ async function exchangeAuthCode(code, clientId, clientSecret, redirectUri) {
2805
+ return unwrapResult(await exchangeAuthCodeResult(code, clientId, clientSecret, redirectUri), oauthErrorToException);
2806
+ }
2807
+ function oauthHttpError(op, info) {
2808
+ const message = `Failed to ${op} token: ${info.message}`;
2809
+ const cause = new GscApiError(message, info);
2810
+ return info.reason === "invalid_grant" || info.code === 400 || info.code === 401 || info.code === 403 ? {
2811
+ kind: "auth-expired",
2812
+ message,
2813
+ cause
2814
+ } : {
2815
+ kind: "transport",
2816
+ message,
2817
+ status: info.code,
2818
+ cause
2819
+ };
2820
+ }
2821
+ function oauthErrorToException(error) {
2822
+ return error.cause instanceof Error ? error.cause : gscErrorToException(error);
2823
+ }
2824
+ async function postOAuthTokenResult(body, op) {
2825
+ let lastError;
2826
+ for (let attempt = 0; attempt < OAUTH_MAX_ATTEMPTS; attempt++) {
2827
+ if (OAUTH_BACKOFF_MS[attempt]) await new Promise((r) => setTimeout(r, OAUTH_BACKOFF_MS[attempt]));
2828
+ const res = await fetch(OAUTH_TOKEN_URL, {
2829
+ method: "POST",
2830
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
2831
+ body,
2832
+ signal: AbortSignal.timeout(OAUTH_TIMEOUT_MS)
2833
+ }).catch((error) => {
2834
+ lastError = error;
2835
+ return null;
2836
+ });
2837
+ if (!res) continue;
2838
+ if (!res.ok) return err(oauthHttpError(op, parseGoogleError(await res.text(), res.status)));
2839
+ const data = await res.json();
2840
+ return ok({
2841
+ accessToken: data.access_token,
2842
+ expiresAt: Math.floor(Date.now() / 1e3) + data.expires_in,
2843
+ refresh_token: data.refresh_token
2844
+ });
2845
+ }
2846
+ return err({
2847
+ kind: "transport",
2848
+ message: lastError instanceof Error ? lastError.message : `OAuth ${op} failed after ${OAUTH_MAX_ATTEMPTS} attempts`,
2849
+ cause: lastError
2850
+ });
2851
+ }
2852
+ async function fetchSites(client) {
2853
+ return client.sites();
2854
+ }
2855
+ async function fetchSitesWithSitemaps(client) {
2856
+ const sites = (await client.sites()).filter((s) => !!s.siteUrl && s.permissionLevel !== "siteUnverifiedUser");
2857
+ return Promise.all(sites.map(async (site) => {
2858
+ const sitemaps = await client.sitemaps.list(site.siteUrl).catch(() => []);
2859
+ return {
2860
+ ...site,
2861
+ sitemaps
2862
+ };
2863
+ }));
2864
+ }
2865
+ async function fetchSitemaps(client, siteUrl) {
2866
+ return client.sitemaps.list(siteUrl);
2867
+ }
2868
+ async function fetchSitemap(client, siteUrl, feedpath) {
2869
+ return client.sitemaps.get(siteUrl, feedpath);
2870
+ }
2871
+ async function submitSitemap(client, siteUrl, feedpath) {
2872
+ return client.sitemaps.submit(siteUrl, feedpath);
2873
+ }
2874
+ async function deleteSitemap(client, siteUrl, feedpath) {
2875
+ return client.sitemaps.delete(siteUrl, feedpath);
2876
+ }
2877
+ async function addSite(client, siteUrl) {
2878
+ return client.sites.add(siteUrl);
2879
+ }
2880
+ async function deleteSite(client, siteUrl) {
2881
+ return client.sites.delete(siteUrl);
2882
+ }
2883
+ const SC_DOMAIN_PREFIX = "sc-domain:";
2884
+ function siteUrlToVerificationSite(siteUrl) {
2885
+ if (siteUrl.startsWith(SC_DOMAIN_PREFIX)) return {
2886
+ type: "INET_DOMAIN",
2887
+ identifier: siteUrl.slice(10)
2888
+ };
2889
+ return {
2890
+ type: "SITE",
2891
+ identifier: siteUrl
2892
+ };
2893
+ }
2894
+ function verificationMethodsFor(site) {
2895
+ if (site.type === "INET_DOMAIN") return ["DNS_TXT", "DNS_CNAME"];
2896
+ return [
2897
+ "META",
2898
+ "FILE",
2899
+ "ANALYTICS",
2900
+ "TAG_MANAGER"
2901
+ ];
2902
+ }
2903
+ async function getVerificationToken(client, siteUrl, method) {
2904
+ const site = siteUrlToVerificationSite(siteUrl);
2905
+ return {
2906
+ ...await client.verification.getToken({
2907
+ site,
2908
+ verificationMethod: method
2909
+ }),
2910
+ site
2911
+ };
2912
+ }
2913
+ async function verifySite(client, siteUrl, method) {
2914
+ const site = siteUrlToVerificationSite(siteUrl);
2915
+ return client.verification.insert({
2916
+ site,
2917
+ verificationMethod: method
2918
+ });
2919
+ }
2920
+ async function listVerifiedSites(client) {
2921
+ return client.verification.list();
2922
+ }
2923
+ async function getVerifiedSite(client, id) {
2924
+ return client.verification.get(id);
2925
+ }
2926
+ async function unverifySite(client, id) {
2927
+ return client.verification.delete(id);
2928
+ }
2929
+ export { GSC_QUOTAS, GscApiError, URL_INSPECTION_DAILY_LIMIT, URL_INSPECTION_EFFECTIVE_LIMIT, addSite, batchInspectUrls, batchRequestIndexing, canUseUrlInspection, classifyError, createAuth, createFetch, deleteSite, deleteSitemap, discoverSitemap, exchangeAuthCode, exchangeAuthCodeResult, fetchSitemap, fetchSitemapUrls, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, findBestGscProperty, findExactGscProperty, formatErrorForCli, formatGscPropertyCandidates, getIndexingEligibility, getIndexingMetadata, getNextCheckAfter, getNextCheckPriority, getVerificationToken, getVerifiedSite, googleSearchConsole, grantedScopeList, gscErrorToException, gscPropertyMatchesTarget, gscdumpApi, hasGscReadScope, hasGscWriteScope, hasIndexingScope, inspectUrl, inspectUrlFlat, isPermissionDeniedError, isVerifiedGscPermission, isVerifiedGscProperty, listVerifiedSites, matchGscSite, normalizeGscSiteUrl, normalizeRegistrationTarget, parseGoogleError, parseGscSiteUrl, pickBestGscProperty, refreshAccessToken, refreshAccessTokenResult, requestIndexing, rethrowAsGscApiError, runSequentialBatch, siteUrlToVerificationSite, storageError, submitSitemap, unverifySite, urlMatchKey, verificationMethodsFor, verifySite };