@ibicash/geolayers-sdk 1.0.2 → 1.1.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.
- package/dist/index.cjs +242 -97
- package/dist/index.d.cts +77 -9
- package/dist/index.d.ts +77 -9
- package/dist/index.js +242 -97
- package/package.json +59 -58
package/dist/index.cjs
CHANGED
|
@@ -392,7 +392,9 @@ var ObservationStatsResultSchema = import_zod2.z.object({
|
|
|
392
392
|
var DEFAULT_CONFIG = {
|
|
393
393
|
baseUrl: (typeof process !== "undefined" ? process.env.GEOLAYERS_BASE_URL : void 0) || "",
|
|
394
394
|
timeout: 3e4,
|
|
395
|
-
retries: 2
|
|
395
|
+
retries: 2,
|
|
396
|
+
apiVersion: "v1",
|
|
397
|
+
apiBasePath: "/api"
|
|
396
398
|
};
|
|
397
399
|
|
|
398
400
|
// src/core/errors.ts
|
|
@@ -422,14 +424,79 @@ var GeoLayersValidationError = class extends GeoLayersError {
|
|
|
422
424
|
var BaseClient = class {
|
|
423
425
|
http;
|
|
424
426
|
config;
|
|
427
|
+
preferredVersion;
|
|
425
428
|
constructor(config) {
|
|
426
|
-
this.config = {
|
|
429
|
+
this.config = {
|
|
430
|
+
...DEFAULT_CONFIG,
|
|
431
|
+
...config,
|
|
432
|
+
apiBasePath: config.apiBasePath ?? DEFAULT_CONFIG.apiBasePath ?? "/api",
|
|
433
|
+
apiVersion: config.apiVersion ?? DEFAULT_CONFIG.apiVersion ?? "v1"
|
|
434
|
+
};
|
|
435
|
+
this.preferredVersion = this.config.apiVersion;
|
|
427
436
|
this.http = import_axios.default.create({
|
|
428
437
|
baseURL: this.config.baseUrl,
|
|
429
438
|
timeout: this.config.timeout
|
|
430
439
|
});
|
|
431
440
|
this.setupInterceptors();
|
|
432
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Returns true if the SDK prefers API v2.
|
|
444
|
+
*/
|
|
445
|
+
get isV2() {
|
|
446
|
+
return this.preferredVersion === "v2";
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Returns the preferred API version.
|
|
450
|
+
*/
|
|
451
|
+
get apiVersion() {
|
|
452
|
+
return this.preferredVersion;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Builds a versioned URL path.
|
|
456
|
+
* @param version API version to use
|
|
457
|
+
* @param endpoint Endpoint path (without version prefix)
|
|
458
|
+
*/
|
|
459
|
+
buildVersionedPath(version, endpoint) {
|
|
460
|
+
const basePath = this.config.apiBasePath;
|
|
461
|
+
const normalizedEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
|
|
462
|
+
return `${basePath}/${version}${normalizedEndpoint}`;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Resolves the appropriate URL based on API version and availability.
|
|
466
|
+
* Falls back to the other version if preferred is not available.
|
|
467
|
+
*
|
|
468
|
+
* @param endpoints Object with v1 and v2 URL paths (use null if unavailable)
|
|
469
|
+
* @returns ResolvedUrl with full path and selected version
|
|
470
|
+
* @throws Error if no endpoint is available for either version
|
|
471
|
+
*/
|
|
472
|
+
resolveEndpoint(endpoints) {
|
|
473
|
+
if (this.isV2 && endpoints.v2 !== null) {
|
|
474
|
+
return {
|
|
475
|
+
url: this.buildVersionedPath("v2", endpoints.v2),
|
|
476
|
+
version: "v2"
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
if (endpoints.v1 !== null) {
|
|
480
|
+
return {
|
|
481
|
+
url: this.buildVersionedPath("v1", endpoints.v1),
|
|
482
|
+
version: "v1"
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
if (endpoints.v2 !== null) {
|
|
486
|
+
return {
|
|
487
|
+
url: this.buildVersionedPath("v2", endpoints.v2),
|
|
488
|
+
version: "v2"
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
throw new Error("No endpoint available for either API version");
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* Resolves URL - convenience method that returns just the URL string.
|
|
495
|
+
* Use resolveEndpoint() if you need to know which version was selected.
|
|
496
|
+
*/
|
|
497
|
+
resolveUrl(endpoints) {
|
|
498
|
+
return this.resolveEndpoint(endpoints).url;
|
|
499
|
+
}
|
|
433
500
|
setupInterceptors() {
|
|
434
501
|
this.http.interceptors.request.use((config) => {
|
|
435
502
|
config.headers["X-API-Key"] = this.config.apiKey;
|
|
@@ -498,6 +565,33 @@ var BaseClient = class {
|
|
|
498
565
|
const schema = createLayerResponseSchema(createFeatureCollectionSchema(propsSchema));
|
|
499
566
|
return schema.parse(data);
|
|
500
567
|
}
|
|
568
|
+
/**
|
|
569
|
+
* Normalizes API responses to a consistent LayerResponse format.
|
|
570
|
+
* Handles both:
|
|
571
|
+
* - v1 responses: LayerResponse envelope with data field
|
|
572
|
+
* - v2 responses: Direct FeatureCollection
|
|
573
|
+
*
|
|
574
|
+
* @param data Raw response data from the API
|
|
575
|
+
* @param propsSchema Zod schema for feature properties
|
|
576
|
+
* @param provider Provider name to use when wrapping v2 responses
|
|
577
|
+
*/
|
|
578
|
+
normalizeGeoJSONResponse(data, propsSchema, provider) {
|
|
579
|
+
const record = data;
|
|
580
|
+
if (record?.provider && record?.data && record?.timestamp) {
|
|
581
|
+
return this.parseGeoJSON(data, propsSchema);
|
|
582
|
+
}
|
|
583
|
+
if (record?.type === "FeatureCollection" && Array.isArray(record?.features)) {
|
|
584
|
+
const featureCollectionSchema = createFeatureCollectionSchema(propsSchema);
|
|
585
|
+
const featureCollection = featureCollectionSchema.parse(data);
|
|
586
|
+
return {
|
|
587
|
+
provider,
|
|
588
|
+
data: featureCollection,
|
|
589
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
590
|
+
count: featureCollection.features.length
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
return this.parseGeoJSON(data, propsSchema);
|
|
594
|
+
}
|
|
501
595
|
};
|
|
502
596
|
|
|
503
597
|
// src/domains/aviation.ts
|
|
@@ -507,33 +601,41 @@ var AviationDomain = class extends BaseClient {
|
|
|
507
601
|
* @param filters Optional bounding box filters. Defaults to whole world.
|
|
508
602
|
*/
|
|
509
603
|
async getGlobalFlights(filters = {}) {
|
|
604
|
+
const url = this.resolveUrl({
|
|
605
|
+
v1: "/geojson/flights/global",
|
|
606
|
+
v2: null
|
|
607
|
+
});
|
|
510
608
|
const params = {
|
|
511
609
|
lamin: filters.lamin ?? -90,
|
|
512
610
|
lomin: filters.lomin ?? -180,
|
|
513
611
|
lamax: filters.lamax ?? 90,
|
|
514
612
|
lomax: filters.lomax ?? 180
|
|
515
613
|
};
|
|
516
|
-
const data = await this.get(
|
|
517
|
-
return this.
|
|
614
|
+
const data = await this.get(url, params);
|
|
615
|
+
return this.normalizeGeoJSONResponse(data, FlightPropsSchema, "global-flights");
|
|
518
616
|
}
|
|
519
617
|
/**
|
|
520
618
|
* Get live flights (subset of global flights).
|
|
521
619
|
* @param filters Center point and radius filters. Defaults to New York if not provided.
|
|
522
620
|
*/
|
|
523
621
|
async getLiveFlights(filters = { lat: 40.7128, lng: -74.006 }) {
|
|
622
|
+
const url = this.resolveUrl({
|
|
623
|
+
v1: "/geojson/flights/live",
|
|
624
|
+
v2: null
|
|
625
|
+
});
|
|
524
626
|
const params = {
|
|
525
627
|
lat: filters.lat,
|
|
526
628
|
lng: filters.lng,
|
|
527
629
|
radius: filters.radius ?? 250
|
|
528
630
|
};
|
|
529
|
-
const data = await this.get(
|
|
530
|
-
return this.
|
|
631
|
+
const data = await this.get(url, params);
|
|
632
|
+
return this.normalizeGeoJSONResponse(data, FlightPropsSchema, "live-flights");
|
|
531
633
|
}
|
|
532
634
|
/**
|
|
533
635
|
* Get flight schedule/details by callsign from AeroDataBox.
|
|
534
636
|
* @param callsign Flight identifier (e.g., 'UAL1234', 'AA100')
|
|
535
637
|
* @returns Raw flight schedule data from AeroDataBox API.
|
|
536
|
-
*
|
|
638
|
+
*
|
|
537
639
|
* @example
|
|
538
640
|
* ```ts
|
|
539
641
|
* const schedule = await sdk.aviation.getFlightSchedule('UAL1234');
|
|
@@ -541,7 +643,11 @@ var AviationDomain = class extends BaseClient {
|
|
|
541
643
|
* ```
|
|
542
644
|
*/
|
|
543
645
|
async getFlightSchedule(callsign) {
|
|
544
|
-
const
|
|
646
|
+
const url = this.resolveUrl({
|
|
647
|
+
v1: "/geojson/flights/schedule",
|
|
648
|
+
v2: null
|
|
649
|
+
});
|
|
650
|
+
const data = await this.get(url, { callsign });
|
|
545
651
|
return FlightScheduleResponseSchema.parse(data);
|
|
546
652
|
}
|
|
547
653
|
};
|
|
@@ -568,7 +674,7 @@ var EventsDomain = class extends BaseClient {
|
|
|
568
674
|
/**
|
|
569
675
|
* Get list of available event types for the event stream.
|
|
570
676
|
* @returns Object with event types array and their descriptions.
|
|
571
|
-
*
|
|
677
|
+
*
|
|
572
678
|
* @example
|
|
573
679
|
* ```ts
|
|
574
680
|
* const { types, descriptions } = await sdk.eventsMeta.getEventTypes();
|
|
@@ -577,7 +683,11 @@ var EventsDomain = class extends BaseClient {
|
|
|
577
683
|
* ```
|
|
578
684
|
*/
|
|
579
685
|
async getEventTypes() {
|
|
580
|
-
const
|
|
686
|
+
const url = this.resolveUrl({
|
|
687
|
+
v1: "/events/types",
|
|
688
|
+
v2: null
|
|
689
|
+
});
|
|
690
|
+
const data = await this.get(url);
|
|
581
691
|
return EventTypesResponseSchema.parse(data);
|
|
582
692
|
}
|
|
583
693
|
};
|
|
@@ -589,9 +699,13 @@ var FireDomain = class extends BaseClient {
|
|
|
589
699
|
* @param filters Optional filters. Default: last 1 day.
|
|
590
700
|
*/
|
|
591
701
|
async getWildfires(filters = {}) {
|
|
702
|
+
const url = this.resolveUrl({
|
|
703
|
+
v1: "/geojson/wildfires",
|
|
704
|
+
v2: null
|
|
705
|
+
});
|
|
592
706
|
const params = { days: filters.days ?? 1 };
|
|
593
|
-
const data = await this.get(
|
|
594
|
-
return this.
|
|
707
|
+
const data = await this.get(url, params);
|
|
708
|
+
return this.normalizeGeoJSONResponse(data, WildfirePropsSchema, "wildfires");
|
|
595
709
|
}
|
|
596
710
|
};
|
|
597
711
|
|
|
@@ -601,15 +715,23 @@ var MaritimeDomain = class extends BaseClient {
|
|
|
601
715
|
* Get NOAA buoy stations (locations).
|
|
602
716
|
*/
|
|
603
717
|
async getBuoyStations() {
|
|
604
|
-
const
|
|
605
|
-
|
|
718
|
+
const url = this.resolveUrl({
|
|
719
|
+
v1: "/geojson/buoys/stations",
|
|
720
|
+
v2: "/stations?provider=buoy"
|
|
721
|
+
});
|
|
722
|
+
const data = await this.get(url);
|
|
723
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "buoy-stations");
|
|
606
724
|
}
|
|
607
725
|
/**
|
|
608
726
|
* Get latest buoy observations (real-time-ish).
|
|
609
727
|
*/
|
|
610
728
|
async getLatestBuoyObservations() {
|
|
611
|
-
const
|
|
612
|
-
|
|
729
|
+
const url = this.resolveUrl({
|
|
730
|
+
v1: "/geojson/buoys/observations",
|
|
731
|
+
v2: null
|
|
732
|
+
});
|
|
733
|
+
const data = await this.get(url);
|
|
734
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "buoy-observations");
|
|
613
735
|
}
|
|
614
736
|
/**
|
|
615
737
|
* Get historical observations for a specific buoy.
|
|
@@ -617,7 +739,11 @@ var MaritimeDomain = class extends BaseClient {
|
|
|
617
739
|
* @param filters Date range filters.
|
|
618
740
|
*/
|
|
619
741
|
async getBuoyObservations(buoyId, filters) {
|
|
620
|
-
const
|
|
742
|
+
const url = this.resolveUrl({
|
|
743
|
+
v1: `/observations/buoy/${buoyId}`,
|
|
744
|
+
v2: null
|
|
745
|
+
});
|
|
746
|
+
const data = await this.get(url, filters);
|
|
621
747
|
return ObservationQueryResultSchema.parse(data);
|
|
622
748
|
}
|
|
623
749
|
};
|
|
@@ -628,15 +754,23 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
628
754
|
* Get active WIS2 stations that reported data in the last 24 hours.
|
|
629
755
|
*/
|
|
630
756
|
async getActiveWis2Stations() {
|
|
631
|
-
const
|
|
632
|
-
|
|
757
|
+
const url = this.resolveUrl({
|
|
758
|
+
v1: "/observations/wis2/stations/active",
|
|
759
|
+
v2: null
|
|
760
|
+
});
|
|
761
|
+
const rawData = await this.get(url);
|
|
762
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, "active-wis2-stations");
|
|
633
763
|
}
|
|
634
764
|
/**
|
|
635
765
|
* Get active IEM/AZOS stations that reported data in the last 24 hours.
|
|
636
766
|
*/
|
|
637
767
|
async getActiveIemStations() {
|
|
638
|
-
const
|
|
639
|
-
|
|
768
|
+
const url = this.resolveUrl({
|
|
769
|
+
v1: "/observations/iem/stations/active",
|
|
770
|
+
v2: null
|
|
771
|
+
});
|
|
772
|
+
const rawData = await this.get(url);
|
|
773
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, "active-iem-stations");
|
|
640
774
|
}
|
|
641
775
|
/**
|
|
642
776
|
* Get observations for a station from the data warehouse.
|
|
@@ -644,8 +778,12 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
644
778
|
* @param filters Query filters including provider and date range.
|
|
645
779
|
*/
|
|
646
780
|
async getStationObservations(stationId, filters) {
|
|
781
|
+
const url = this.resolveUrl({
|
|
782
|
+
v1: `/observations/station/${stationId}`,
|
|
783
|
+
v2: null
|
|
784
|
+
});
|
|
647
785
|
const params = this.buildDateParams(filters);
|
|
648
|
-
const data = await this.get(
|
|
786
|
+
const data = await this.get(url, params);
|
|
649
787
|
return StationObservationsResultSchema.parse(data);
|
|
650
788
|
}
|
|
651
789
|
/**
|
|
@@ -654,7 +792,11 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
654
792
|
* @param provider The observation provider.
|
|
655
793
|
*/
|
|
656
794
|
async getLatestObservation(stationId, provider) {
|
|
657
|
-
const
|
|
795
|
+
const url = this.resolveUrl({
|
|
796
|
+
v1: `/observations/station/${stationId}/latest`,
|
|
797
|
+
v2: null
|
|
798
|
+
});
|
|
799
|
+
const data = await this.get(url, { provider });
|
|
658
800
|
return LatestObservationResultSchema.parse(data);
|
|
659
801
|
}
|
|
660
802
|
/**
|
|
@@ -662,6 +804,10 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
662
804
|
* @param filters Bounding box coordinates and query filters.
|
|
663
805
|
*/
|
|
664
806
|
async getObservationsByBbox(filters) {
|
|
807
|
+
const url = this.resolveUrl({
|
|
808
|
+
v1: "/observations/bbox",
|
|
809
|
+
v2: null
|
|
810
|
+
});
|
|
665
811
|
const params = {
|
|
666
812
|
...this.buildDateParams(filters),
|
|
667
813
|
minLon: filters.minLon,
|
|
@@ -669,7 +815,7 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
669
815
|
maxLon: filters.maxLon,
|
|
670
816
|
maxLat: filters.maxLat
|
|
671
817
|
};
|
|
672
|
-
const data = await this.get(
|
|
818
|
+
const data = await this.get(url, params);
|
|
673
819
|
return BboxObservationsResultSchema.parse(data);
|
|
674
820
|
}
|
|
675
821
|
/**
|
|
@@ -677,8 +823,12 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
677
823
|
* @param provider Optional provider filter. If not specified, returns stats for all providers.
|
|
678
824
|
*/
|
|
679
825
|
async getStats(provider) {
|
|
826
|
+
const url = this.resolveUrl({
|
|
827
|
+
v1: "/observations/stats",
|
|
828
|
+
v2: null
|
|
829
|
+
});
|
|
680
830
|
const params = provider ? { provider } : {};
|
|
681
|
-
const data = await this.get(
|
|
831
|
+
const data = await this.get(url, params);
|
|
682
832
|
return ObservationStatsResultSchema.parse(data);
|
|
683
833
|
}
|
|
684
834
|
/**
|
|
@@ -710,34 +860,6 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
710
860
|
}
|
|
711
861
|
return params;
|
|
712
862
|
}
|
|
713
|
-
/**
|
|
714
|
-
* Parse active stations response.
|
|
715
|
-
* The endpoint may return either a FeatureCollection directly or wrapped in LayerResponse.
|
|
716
|
-
*/
|
|
717
|
-
parseActiveStationsResponse(rawData, provider) {
|
|
718
|
-
const featureCollection = rawData;
|
|
719
|
-
if (featureCollection?.type === "FeatureCollection") {
|
|
720
|
-
const features = (featureCollection.features ?? []).map((f) => {
|
|
721
|
-
const feature = f;
|
|
722
|
-
return {
|
|
723
|
-
type: "Feature",
|
|
724
|
-
geometry: feature.geometry,
|
|
725
|
-
properties: WeatherStationPropsSchema.parse(feature.properties ?? {}),
|
|
726
|
-
id: feature.id
|
|
727
|
-
};
|
|
728
|
-
});
|
|
729
|
-
return {
|
|
730
|
-
provider: `active-stations-${provider}`,
|
|
731
|
-
data: {
|
|
732
|
-
type: "FeatureCollection",
|
|
733
|
-
features
|
|
734
|
-
},
|
|
735
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
736
|
-
count: features.length
|
|
737
|
-
};
|
|
738
|
-
}
|
|
739
|
-
return this.parseGeoJSON(rawData, WeatherStationPropsSchema);
|
|
740
|
-
}
|
|
741
863
|
};
|
|
742
864
|
|
|
743
865
|
// src/domains/seismic.ts
|
|
@@ -789,8 +911,12 @@ var SeismicDomain = class extends BaseClient {
|
|
|
789
911
|
...timeRange,
|
|
790
912
|
...minMagnitude !== void 0 && { minMagnitude }
|
|
791
913
|
};
|
|
792
|
-
const
|
|
793
|
-
|
|
914
|
+
const url = this.resolveUrl({
|
|
915
|
+
v1: "/geojson/earthquakes",
|
|
916
|
+
v2: null
|
|
917
|
+
});
|
|
918
|
+
const data = await this.get(url, params);
|
|
919
|
+
return this.normalizeGeoJSONResponse(data, EarthquakePropsSchema, "earthquakes");
|
|
794
920
|
}
|
|
795
921
|
};
|
|
796
922
|
|
|
@@ -800,15 +926,23 @@ var TropicalDomain = class extends BaseClient {
|
|
|
800
926
|
* Get list of currently active tropical storms/hurricanes.
|
|
801
927
|
*/
|
|
802
928
|
async getActiveStorms() {
|
|
803
|
-
const
|
|
804
|
-
|
|
929
|
+
const url = this.resolveUrl({
|
|
930
|
+
v1: "/geojson/storms/active",
|
|
931
|
+
v2: null
|
|
932
|
+
});
|
|
933
|
+
const data = await this.get(url);
|
|
934
|
+
return this.normalizeGeoJSONResponse(data, StormPropsSchema, "active-storms");
|
|
805
935
|
}
|
|
806
936
|
/**
|
|
807
937
|
* Get list of recent tropical storms/hurricanes.
|
|
808
938
|
*/
|
|
809
939
|
async getRecentStorms() {
|
|
810
|
-
const
|
|
811
|
-
|
|
940
|
+
const url = this.resolveUrl({
|
|
941
|
+
v1: "/geojson/storms/recent",
|
|
942
|
+
v2: null
|
|
943
|
+
});
|
|
944
|
+
const data = await this.get(url);
|
|
945
|
+
return this.normalizeGeoJSONResponse(data, StormPropsSchema, "recent-storms");
|
|
812
946
|
}
|
|
813
947
|
};
|
|
814
948
|
|
|
@@ -827,7 +961,11 @@ var VolcanicDomain = class extends BaseClient {
|
|
|
827
961
|
* Note: API returns array of Features, normalized to FeatureCollection here.
|
|
828
962
|
*/
|
|
829
963
|
async getVolcanoes() {
|
|
830
|
-
const
|
|
964
|
+
const url = this.resolveUrl({
|
|
965
|
+
v1: "/geojson/volcanoes",
|
|
966
|
+
v2: null
|
|
967
|
+
});
|
|
968
|
+
const raw = await this.get(url);
|
|
831
969
|
const parsed = VolcanoesResponseSchema.parse(raw);
|
|
832
970
|
return {
|
|
833
971
|
provider: parsed.provider,
|
|
@@ -844,8 +982,12 @@ var VolcanicDomain = class extends BaseClient {
|
|
|
844
982
|
* Get list of currently active volcanoes (GDACS).
|
|
845
983
|
*/
|
|
846
984
|
async getActiveVolcanoes() {
|
|
847
|
-
const
|
|
848
|
-
|
|
985
|
+
const url = this.resolveUrl({
|
|
986
|
+
v1: "/geojson/volcanoes/active",
|
|
987
|
+
v2: null
|
|
988
|
+
});
|
|
989
|
+
const data = await this.get(url);
|
|
990
|
+
return this.normalizeGeoJSONResponse(data, ActiveVolcanoPropsSchema, "active-volcanoes");
|
|
849
991
|
}
|
|
850
992
|
};
|
|
851
993
|
|
|
@@ -856,12 +998,16 @@ var WeatherDomain = class extends BaseClient {
|
|
|
856
998
|
* @param filters Optional pagination filters.
|
|
857
999
|
*/
|
|
858
1000
|
async getWis2Stations(filters = {}) {
|
|
859
|
-
const
|
|
1001
|
+
const { url, version } = this.resolveEndpoint({
|
|
1002
|
+
v1: "/geojson/stations/wis2",
|
|
1003
|
+
v2: "/stations?provider=wis2"
|
|
1004
|
+
});
|
|
1005
|
+
const params = version === "v2" ? filters : {
|
|
860
1006
|
limit: filters.limit ?? 100,
|
|
861
1007
|
offset: filters.offset ?? 0
|
|
862
1008
|
};
|
|
863
|
-
const data = await this.get(
|
|
864
|
-
return this.
|
|
1009
|
+
const data = await this.get(url, params);
|
|
1010
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "wis2-stations");
|
|
865
1011
|
}
|
|
866
1012
|
/**
|
|
867
1013
|
* Get historical observations for a WIS2 station.
|
|
@@ -869,15 +1015,23 @@ var WeatherDomain = class extends BaseClient {
|
|
|
869
1015
|
* @param filters Date range and optional WIS2-specific filters.
|
|
870
1016
|
*/
|
|
871
1017
|
async getWis2Observations(stationId, filters) {
|
|
872
|
-
const
|
|
1018
|
+
const url = this.resolveUrl({
|
|
1019
|
+
v1: `/observations/wis2/${stationId}`,
|
|
1020
|
+
v2: null
|
|
1021
|
+
});
|
|
1022
|
+
const data = await this.get(url, filters);
|
|
873
1023
|
return ObservationQueryResultSchema.parse(data);
|
|
874
1024
|
}
|
|
875
1025
|
/**
|
|
876
1026
|
* Get weather stations from IEM/AZOS network.
|
|
877
1027
|
*/
|
|
878
1028
|
async getIemStations() {
|
|
879
|
-
const
|
|
880
|
-
|
|
1029
|
+
const { url, version } = this.resolveEndpoint({
|
|
1030
|
+
v1: "/geojson/stations/azos",
|
|
1031
|
+
v2: "/stations?provider=iem"
|
|
1032
|
+
});
|
|
1033
|
+
const data = await this.get(url);
|
|
1034
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "iem-stations");
|
|
881
1035
|
}
|
|
882
1036
|
/**
|
|
883
1037
|
* Get historical observations for an IEM station.
|
|
@@ -885,46 +1039,35 @@ var WeatherDomain = class extends BaseClient {
|
|
|
885
1039
|
* @param filters Date range filters.
|
|
886
1040
|
*/
|
|
887
1041
|
async getIemObservations(stationId, filters) {
|
|
888
|
-
const
|
|
1042
|
+
const url = this.resolveUrl({
|
|
1043
|
+
v1: `/observations/iem/${stationId}`,
|
|
1044
|
+
v2: null
|
|
1045
|
+
});
|
|
1046
|
+
const data = await this.get(url, filters);
|
|
889
1047
|
return ObservationQueryResultSchema.parse(data);
|
|
890
1048
|
}
|
|
891
1049
|
/**
|
|
892
1050
|
* Get weather stations from NWS (National Weather Service) network.
|
|
893
1051
|
*/
|
|
894
1052
|
async getNWSWeatherStations() {
|
|
895
|
-
const
|
|
896
|
-
|
|
1053
|
+
const url = this.resolveUrl({
|
|
1054
|
+
v1: "/geojson/stations/nws",
|
|
1055
|
+
v2: null
|
|
1056
|
+
});
|
|
1057
|
+
const data = await this.get(url);
|
|
1058
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "nws-stations");
|
|
897
1059
|
}
|
|
898
1060
|
/**
|
|
899
1061
|
* Get active stations that have reported data in the last 24 hours.
|
|
900
1062
|
* @param type The station network type ('iem' or 'wis2').
|
|
901
|
-
*
|
|
902
|
-
* Note: This endpoint returns FeatureCollection directly (not LayerResponse envelope).
|
|
903
1063
|
*/
|
|
904
1064
|
async getActiveStations(type) {
|
|
905
|
-
const
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
type: "Feature",
|
|
912
|
-
geometry: feature.geometry,
|
|
913
|
-
properties: WeatherStationPropsSchema.parse(feature.properties ?? {}),
|
|
914
|
-
id: feature.id
|
|
915
|
-
};
|
|
916
|
-
});
|
|
917
|
-
return {
|
|
918
|
-
provider: `active-stations-${type}`,
|
|
919
|
-
data: {
|
|
920
|
-
type: "FeatureCollection",
|
|
921
|
-
features
|
|
922
|
-
},
|
|
923
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
924
|
-
count: features.length
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
return this.parseGeoJSON(rawData, WeatherStationPropsSchema);
|
|
1065
|
+
const url = this.resolveUrl({
|
|
1066
|
+
v1: "/stations/active",
|
|
1067
|
+
v2: null
|
|
1068
|
+
});
|
|
1069
|
+
const rawData = await this.get(url, { type });
|
|
1070
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, `active-stations-${type}`);
|
|
928
1071
|
}
|
|
929
1072
|
};
|
|
930
1073
|
|
|
@@ -935,7 +1078,9 @@ var EventStream = class extends import_events.EventEmitter {
|
|
|
935
1078
|
url;
|
|
936
1079
|
constructor(config) {
|
|
937
1080
|
super();
|
|
938
|
-
|
|
1081
|
+
const baseUrl = config.baseUrl;
|
|
1082
|
+
const apiBasePath = config.apiBasePath ?? DEFAULT_CONFIG.apiBasePath ?? "/api";
|
|
1083
|
+
this.url = `${baseUrl}${apiBasePath}/v1/events/stream?apiKey=${config.apiKey}`;
|
|
939
1084
|
}
|
|
940
1085
|
/**
|
|
941
1086
|
* Start listening to the event stream.
|