@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.js
CHANGED
|
@@ -327,7 +327,9 @@ var ObservationStatsResultSchema = z2.object({
|
|
|
327
327
|
var DEFAULT_CONFIG = {
|
|
328
328
|
baseUrl: (typeof process !== "undefined" ? process.env.GEOLAYERS_BASE_URL : void 0) || "",
|
|
329
329
|
timeout: 3e4,
|
|
330
|
-
retries: 2
|
|
330
|
+
retries: 2,
|
|
331
|
+
apiVersion: "v1",
|
|
332
|
+
apiBasePath: "/api"
|
|
331
333
|
};
|
|
332
334
|
|
|
333
335
|
// src/core/errors.ts
|
|
@@ -357,14 +359,79 @@ var GeoLayersValidationError = class extends GeoLayersError {
|
|
|
357
359
|
var BaseClient = class {
|
|
358
360
|
http;
|
|
359
361
|
config;
|
|
362
|
+
preferredVersion;
|
|
360
363
|
constructor(config) {
|
|
361
|
-
this.config = {
|
|
364
|
+
this.config = {
|
|
365
|
+
...DEFAULT_CONFIG,
|
|
366
|
+
...config,
|
|
367
|
+
apiBasePath: config.apiBasePath ?? DEFAULT_CONFIG.apiBasePath ?? "/api",
|
|
368
|
+
apiVersion: config.apiVersion ?? DEFAULT_CONFIG.apiVersion ?? "v1"
|
|
369
|
+
};
|
|
370
|
+
this.preferredVersion = this.config.apiVersion;
|
|
362
371
|
this.http = axios.create({
|
|
363
372
|
baseURL: this.config.baseUrl,
|
|
364
373
|
timeout: this.config.timeout
|
|
365
374
|
});
|
|
366
375
|
this.setupInterceptors();
|
|
367
376
|
}
|
|
377
|
+
/**
|
|
378
|
+
* Returns true if the SDK prefers API v2.
|
|
379
|
+
*/
|
|
380
|
+
get isV2() {
|
|
381
|
+
return this.preferredVersion === "v2";
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Returns the preferred API version.
|
|
385
|
+
*/
|
|
386
|
+
get apiVersion() {
|
|
387
|
+
return this.preferredVersion;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Builds a versioned URL path.
|
|
391
|
+
* @param version API version to use
|
|
392
|
+
* @param endpoint Endpoint path (without version prefix)
|
|
393
|
+
*/
|
|
394
|
+
buildVersionedPath(version, endpoint) {
|
|
395
|
+
const basePath = this.config.apiBasePath;
|
|
396
|
+
const normalizedEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
|
|
397
|
+
return `${basePath}/${version}${normalizedEndpoint}`;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Resolves the appropriate URL based on API version and availability.
|
|
401
|
+
* Falls back to the other version if preferred is not available.
|
|
402
|
+
*
|
|
403
|
+
* @param endpoints Object with v1 and v2 URL paths (use null if unavailable)
|
|
404
|
+
* @returns ResolvedUrl with full path and selected version
|
|
405
|
+
* @throws Error if no endpoint is available for either version
|
|
406
|
+
*/
|
|
407
|
+
resolveEndpoint(endpoints) {
|
|
408
|
+
if (this.isV2 && endpoints.v2 !== null) {
|
|
409
|
+
return {
|
|
410
|
+
url: this.buildVersionedPath("v2", endpoints.v2),
|
|
411
|
+
version: "v2"
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
if (endpoints.v1 !== null) {
|
|
415
|
+
return {
|
|
416
|
+
url: this.buildVersionedPath("v1", endpoints.v1),
|
|
417
|
+
version: "v1"
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
if (endpoints.v2 !== null) {
|
|
421
|
+
return {
|
|
422
|
+
url: this.buildVersionedPath("v2", endpoints.v2),
|
|
423
|
+
version: "v2"
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
throw new Error("No endpoint available for either API version");
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Resolves URL - convenience method that returns just the URL string.
|
|
430
|
+
* Use resolveEndpoint() if you need to know which version was selected.
|
|
431
|
+
*/
|
|
432
|
+
resolveUrl(endpoints) {
|
|
433
|
+
return this.resolveEndpoint(endpoints).url;
|
|
434
|
+
}
|
|
368
435
|
setupInterceptors() {
|
|
369
436
|
this.http.interceptors.request.use((config) => {
|
|
370
437
|
config.headers["X-API-Key"] = this.config.apiKey;
|
|
@@ -433,6 +500,33 @@ var BaseClient = class {
|
|
|
433
500
|
const schema = createLayerResponseSchema(createFeatureCollectionSchema(propsSchema));
|
|
434
501
|
return schema.parse(data);
|
|
435
502
|
}
|
|
503
|
+
/**
|
|
504
|
+
* Normalizes API responses to a consistent LayerResponse format.
|
|
505
|
+
* Handles both:
|
|
506
|
+
* - v1 responses: LayerResponse envelope with data field
|
|
507
|
+
* - v2 responses: Direct FeatureCollection
|
|
508
|
+
*
|
|
509
|
+
* @param data Raw response data from the API
|
|
510
|
+
* @param propsSchema Zod schema for feature properties
|
|
511
|
+
* @param provider Provider name to use when wrapping v2 responses
|
|
512
|
+
*/
|
|
513
|
+
normalizeGeoJSONResponse(data, propsSchema, provider) {
|
|
514
|
+
const record = data;
|
|
515
|
+
if (record?.provider && record?.data && record?.timestamp) {
|
|
516
|
+
return this.parseGeoJSON(data, propsSchema);
|
|
517
|
+
}
|
|
518
|
+
if (record?.type === "FeatureCollection" && Array.isArray(record?.features)) {
|
|
519
|
+
const featureCollectionSchema = createFeatureCollectionSchema(propsSchema);
|
|
520
|
+
const featureCollection = featureCollectionSchema.parse(data);
|
|
521
|
+
return {
|
|
522
|
+
provider,
|
|
523
|
+
data: featureCollection,
|
|
524
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
525
|
+
count: featureCollection.features.length
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
return this.parseGeoJSON(data, propsSchema);
|
|
529
|
+
}
|
|
436
530
|
};
|
|
437
531
|
|
|
438
532
|
// src/domains/aviation.ts
|
|
@@ -442,33 +536,41 @@ var AviationDomain = class extends BaseClient {
|
|
|
442
536
|
* @param filters Optional bounding box filters. Defaults to whole world.
|
|
443
537
|
*/
|
|
444
538
|
async getGlobalFlights(filters = {}) {
|
|
539
|
+
const url = this.resolveUrl({
|
|
540
|
+
v1: "/geojson/flights/global",
|
|
541
|
+
v2: null
|
|
542
|
+
});
|
|
445
543
|
const params = {
|
|
446
544
|
lamin: filters.lamin ?? -90,
|
|
447
545
|
lomin: filters.lomin ?? -180,
|
|
448
546
|
lamax: filters.lamax ?? 90,
|
|
449
547
|
lomax: filters.lomax ?? 180
|
|
450
548
|
};
|
|
451
|
-
const data = await this.get(
|
|
452
|
-
return this.
|
|
549
|
+
const data = await this.get(url, params);
|
|
550
|
+
return this.normalizeGeoJSONResponse(data, FlightPropsSchema, "global-flights");
|
|
453
551
|
}
|
|
454
552
|
/**
|
|
455
553
|
* Get live flights (subset of global flights).
|
|
456
554
|
* @param filters Center point and radius filters. Defaults to New York if not provided.
|
|
457
555
|
*/
|
|
458
556
|
async getLiveFlights(filters = { lat: 40.7128, lng: -74.006 }) {
|
|
557
|
+
const url = this.resolveUrl({
|
|
558
|
+
v1: "/geojson/flights/live",
|
|
559
|
+
v2: null
|
|
560
|
+
});
|
|
459
561
|
const params = {
|
|
460
562
|
lat: filters.lat,
|
|
461
563
|
lng: filters.lng,
|
|
462
564
|
radius: filters.radius ?? 250
|
|
463
565
|
};
|
|
464
|
-
const data = await this.get(
|
|
465
|
-
return this.
|
|
566
|
+
const data = await this.get(url, params);
|
|
567
|
+
return this.normalizeGeoJSONResponse(data, FlightPropsSchema, "live-flights");
|
|
466
568
|
}
|
|
467
569
|
/**
|
|
468
570
|
* Get flight schedule/details by callsign from AeroDataBox.
|
|
469
571
|
* @param callsign Flight identifier (e.g., 'UAL1234', 'AA100')
|
|
470
572
|
* @returns Raw flight schedule data from AeroDataBox API.
|
|
471
|
-
*
|
|
573
|
+
*
|
|
472
574
|
* @example
|
|
473
575
|
* ```ts
|
|
474
576
|
* const schedule = await sdk.aviation.getFlightSchedule('UAL1234');
|
|
@@ -476,7 +578,11 @@ var AviationDomain = class extends BaseClient {
|
|
|
476
578
|
* ```
|
|
477
579
|
*/
|
|
478
580
|
async getFlightSchedule(callsign) {
|
|
479
|
-
const
|
|
581
|
+
const url = this.resolveUrl({
|
|
582
|
+
v1: "/geojson/flights/schedule",
|
|
583
|
+
v2: null
|
|
584
|
+
});
|
|
585
|
+
const data = await this.get(url, { callsign });
|
|
480
586
|
return FlightScheduleResponseSchema.parse(data);
|
|
481
587
|
}
|
|
482
588
|
};
|
|
@@ -503,7 +609,7 @@ var EventsDomain = class extends BaseClient {
|
|
|
503
609
|
/**
|
|
504
610
|
* Get list of available event types for the event stream.
|
|
505
611
|
* @returns Object with event types array and their descriptions.
|
|
506
|
-
*
|
|
612
|
+
*
|
|
507
613
|
* @example
|
|
508
614
|
* ```ts
|
|
509
615
|
* const { types, descriptions } = await sdk.eventsMeta.getEventTypes();
|
|
@@ -512,7 +618,11 @@ var EventsDomain = class extends BaseClient {
|
|
|
512
618
|
* ```
|
|
513
619
|
*/
|
|
514
620
|
async getEventTypes() {
|
|
515
|
-
const
|
|
621
|
+
const url = this.resolveUrl({
|
|
622
|
+
v1: "/events/types",
|
|
623
|
+
v2: null
|
|
624
|
+
});
|
|
625
|
+
const data = await this.get(url);
|
|
516
626
|
return EventTypesResponseSchema.parse(data);
|
|
517
627
|
}
|
|
518
628
|
};
|
|
@@ -524,9 +634,13 @@ var FireDomain = class extends BaseClient {
|
|
|
524
634
|
* @param filters Optional filters. Default: last 1 day.
|
|
525
635
|
*/
|
|
526
636
|
async getWildfires(filters = {}) {
|
|
637
|
+
const url = this.resolveUrl({
|
|
638
|
+
v1: "/geojson/wildfires",
|
|
639
|
+
v2: null
|
|
640
|
+
});
|
|
527
641
|
const params = { days: filters.days ?? 1 };
|
|
528
|
-
const data = await this.get(
|
|
529
|
-
return this.
|
|
642
|
+
const data = await this.get(url, params);
|
|
643
|
+
return this.normalizeGeoJSONResponse(data, WildfirePropsSchema, "wildfires");
|
|
530
644
|
}
|
|
531
645
|
};
|
|
532
646
|
|
|
@@ -536,15 +650,23 @@ var MaritimeDomain = class extends BaseClient {
|
|
|
536
650
|
* Get NOAA buoy stations (locations).
|
|
537
651
|
*/
|
|
538
652
|
async getBuoyStations() {
|
|
539
|
-
const
|
|
540
|
-
|
|
653
|
+
const url = this.resolveUrl({
|
|
654
|
+
v1: "/geojson/buoys/stations",
|
|
655
|
+
v2: "/stations?provider=buoy"
|
|
656
|
+
});
|
|
657
|
+
const data = await this.get(url);
|
|
658
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "buoy-stations");
|
|
541
659
|
}
|
|
542
660
|
/**
|
|
543
661
|
* Get latest buoy observations (real-time-ish).
|
|
544
662
|
*/
|
|
545
663
|
async getLatestBuoyObservations() {
|
|
546
|
-
const
|
|
547
|
-
|
|
664
|
+
const url = this.resolveUrl({
|
|
665
|
+
v1: "/geojson/buoys/observations",
|
|
666
|
+
v2: null
|
|
667
|
+
});
|
|
668
|
+
const data = await this.get(url);
|
|
669
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "buoy-observations");
|
|
548
670
|
}
|
|
549
671
|
/**
|
|
550
672
|
* Get historical observations for a specific buoy.
|
|
@@ -552,7 +674,11 @@ var MaritimeDomain = class extends BaseClient {
|
|
|
552
674
|
* @param filters Date range filters.
|
|
553
675
|
*/
|
|
554
676
|
async getBuoyObservations(buoyId, filters) {
|
|
555
|
-
const
|
|
677
|
+
const url = this.resolveUrl({
|
|
678
|
+
v1: `/observations/buoy/${buoyId}`,
|
|
679
|
+
v2: null
|
|
680
|
+
});
|
|
681
|
+
const data = await this.get(url, filters);
|
|
556
682
|
return ObservationQueryResultSchema.parse(data);
|
|
557
683
|
}
|
|
558
684
|
};
|
|
@@ -563,15 +689,23 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
563
689
|
* Get active WIS2 stations that reported data in the last 24 hours.
|
|
564
690
|
*/
|
|
565
691
|
async getActiveWis2Stations() {
|
|
566
|
-
const
|
|
567
|
-
|
|
692
|
+
const url = this.resolveUrl({
|
|
693
|
+
v1: "/observations/wis2/stations/active",
|
|
694
|
+
v2: null
|
|
695
|
+
});
|
|
696
|
+
const rawData = await this.get(url);
|
|
697
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, "active-wis2-stations");
|
|
568
698
|
}
|
|
569
699
|
/**
|
|
570
700
|
* Get active IEM/AZOS stations that reported data in the last 24 hours.
|
|
571
701
|
*/
|
|
572
702
|
async getActiveIemStations() {
|
|
573
|
-
const
|
|
574
|
-
|
|
703
|
+
const url = this.resolveUrl({
|
|
704
|
+
v1: "/observations/iem/stations/active",
|
|
705
|
+
v2: null
|
|
706
|
+
});
|
|
707
|
+
const rawData = await this.get(url);
|
|
708
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, "active-iem-stations");
|
|
575
709
|
}
|
|
576
710
|
/**
|
|
577
711
|
* Get observations for a station from the data warehouse.
|
|
@@ -579,8 +713,12 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
579
713
|
* @param filters Query filters including provider and date range.
|
|
580
714
|
*/
|
|
581
715
|
async getStationObservations(stationId, filters) {
|
|
716
|
+
const url = this.resolveUrl({
|
|
717
|
+
v1: `/observations/station/${stationId}`,
|
|
718
|
+
v2: null
|
|
719
|
+
});
|
|
582
720
|
const params = this.buildDateParams(filters);
|
|
583
|
-
const data = await this.get(
|
|
721
|
+
const data = await this.get(url, params);
|
|
584
722
|
return StationObservationsResultSchema.parse(data);
|
|
585
723
|
}
|
|
586
724
|
/**
|
|
@@ -589,7 +727,11 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
589
727
|
* @param provider The observation provider.
|
|
590
728
|
*/
|
|
591
729
|
async getLatestObservation(stationId, provider) {
|
|
592
|
-
const
|
|
730
|
+
const url = this.resolveUrl({
|
|
731
|
+
v1: `/observations/station/${stationId}/latest`,
|
|
732
|
+
v2: null
|
|
733
|
+
});
|
|
734
|
+
const data = await this.get(url, { provider });
|
|
593
735
|
return LatestObservationResultSchema.parse(data);
|
|
594
736
|
}
|
|
595
737
|
/**
|
|
@@ -597,6 +739,10 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
597
739
|
* @param filters Bounding box coordinates and query filters.
|
|
598
740
|
*/
|
|
599
741
|
async getObservationsByBbox(filters) {
|
|
742
|
+
const url = this.resolveUrl({
|
|
743
|
+
v1: "/observations/bbox",
|
|
744
|
+
v2: null
|
|
745
|
+
});
|
|
600
746
|
const params = {
|
|
601
747
|
...this.buildDateParams(filters),
|
|
602
748
|
minLon: filters.minLon,
|
|
@@ -604,7 +750,7 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
604
750
|
maxLon: filters.maxLon,
|
|
605
751
|
maxLat: filters.maxLat
|
|
606
752
|
};
|
|
607
|
-
const data = await this.get(
|
|
753
|
+
const data = await this.get(url, params);
|
|
608
754
|
return BboxObservationsResultSchema.parse(data);
|
|
609
755
|
}
|
|
610
756
|
/**
|
|
@@ -612,8 +758,12 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
612
758
|
* @param provider Optional provider filter. If not specified, returns stats for all providers.
|
|
613
759
|
*/
|
|
614
760
|
async getStats(provider) {
|
|
761
|
+
const url = this.resolveUrl({
|
|
762
|
+
v1: "/observations/stats",
|
|
763
|
+
v2: null
|
|
764
|
+
});
|
|
615
765
|
const params = provider ? { provider } : {};
|
|
616
|
-
const data = await this.get(
|
|
766
|
+
const data = await this.get(url, params);
|
|
617
767
|
return ObservationStatsResultSchema.parse(data);
|
|
618
768
|
}
|
|
619
769
|
/**
|
|
@@ -645,34 +795,6 @@ var ObservationsDomain = class extends BaseClient {
|
|
|
645
795
|
}
|
|
646
796
|
return params;
|
|
647
797
|
}
|
|
648
|
-
/**
|
|
649
|
-
* Parse active stations response.
|
|
650
|
-
* The endpoint may return either a FeatureCollection directly or wrapped in LayerResponse.
|
|
651
|
-
*/
|
|
652
|
-
parseActiveStationsResponse(rawData, provider) {
|
|
653
|
-
const featureCollection = rawData;
|
|
654
|
-
if (featureCollection?.type === "FeatureCollection") {
|
|
655
|
-
const features = (featureCollection.features ?? []).map((f) => {
|
|
656
|
-
const feature = f;
|
|
657
|
-
return {
|
|
658
|
-
type: "Feature",
|
|
659
|
-
geometry: feature.geometry,
|
|
660
|
-
properties: WeatherStationPropsSchema.parse(feature.properties ?? {}),
|
|
661
|
-
id: feature.id
|
|
662
|
-
};
|
|
663
|
-
});
|
|
664
|
-
return {
|
|
665
|
-
provider: `active-stations-${provider}`,
|
|
666
|
-
data: {
|
|
667
|
-
type: "FeatureCollection",
|
|
668
|
-
features
|
|
669
|
-
},
|
|
670
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
671
|
-
count: features.length
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
return this.parseGeoJSON(rawData, WeatherStationPropsSchema);
|
|
675
|
-
}
|
|
676
798
|
};
|
|
677
799
|
|
|
678
800
|
// src/domains/seismic.ts
|
|
@@ -724,8 +846,12 @@ var SeismicDomain = class extends BaseClient {
|
|
|
724
846
|
...timeRange,
|
|
725
847
|
...minMagnitude !== void 0 && { minMagnitude }
|
|
726
848
|
};
|
|
727
|
-
const
|
|
728
|
-
|
|
849
|
+
const url = this.resolveUrl({
|
|
850
|
+
v1: "/geojson/earthquakes",
|
|
851
|
+
v2: null
|
|
852
|
+
});
|
|
853
|
+
const data = await this.get(url, params);
|
|
854
|
+
return this.normalizeGeoJSONResponse(data, EarthquakePropsSchema, "earthquakes");
|
|
729
855
|
}
|
|
730
856
|
};
|
|
731
857
|
|
|
@@ -735,15 +861,23 @@ var TropicalDomain = class extends BaseClient {
|
|
|
735
861
|
* Get list of currently active tropical storms/hurricanes.
|
|
736
862
|
*/
|
|
737
863
|
async getActiveStorms() {
|
|
738
|
-
const
|
|
739
|
-
|
|
864
|
+
const url = this.resolveUrl({
|
|
865
|
+
v1: "/geojson/storms/active",
|
|
866
|
+
v2: null
|
|
867
|
+
});
|
|
868
|
+
const data = await this.get(url);
|
|
869
|
+
return this.normalizeGeoJSONResponse(data, StormPropsSchema, "active-storms");
|
|
740
870
|
}
|
|
741
871
|
/**
|
|
742
872
|
* Get list of recent tropical storms/hurricanes.
|
|
743
873
|
*/
|
|
744
874
|
async getRecentStorms() {
|
|
745
|
-
const
|
|
746
|
-
|
|
875
|
+
const url = this.resolveUrl({
|
|
876
|
+
v1: "/geojson/storms/recent",
|
|
877
|
+
v2: null
|
|
878
|
+
});
|
|
879
|
+
const data = await this.get(url);
|
|
880
|
+
return this.normalizeGeoJSONResponse(data, StormPropsSchema, "recent-storms");
|
|
747
881
|
}
|
|
748
882
|
};
|
|
749
883
|
|
|
@@ -762,7 +896,11 @@ var VolcanicDomain = class extends BaseClient {
|
|
|
762
896
|
* Note: API returns array of Features, normalized to FeatureCollection here.
|
|
763
897
|
*/
|
|
764
898
|
async getVolcanoes() {
|
|
765
|
-
const
|
|
899
|
+
const url = this.resolveUrl({
|
|
900
|
+
v1: "/geojson/volcanoes",
|
|
901
|
+
v2: null
|
|
902
|
+
});
|
|
903
|
+
const raw = await this.get(url);
|
|
766
904
|
const parsed = VolcanoesResponseSchema.parse(raw);
|
|
767
905
|
return {
|
|
768
906
|
provider: parsed.provider,
|
|
@@ -779,8 +917,12 @@ var VolcanicDomain = class extends BaseClient {
|
|
|
779
917
|
* Get list of currently active volcanoes (GDACS).
|
|
780
918
|
*/
|
|
781
919
|
async getActiveVolcanoes() {
|
|
782
|
-
const
|
|
783
|
-
|
|
920
|
+
const url = this.resolveUrl({
|
|
921
|
+
v1: "/geojson/volcanoes/active",
|
|
922
|
+
v2: null
|
|
923
|
+
});
|
|
924
|
+
const data = await this.get(url);
|
|
925
|
+
return this.normalizeGeoJSONResponse(data, ActiveVolcanoPropsSchema, "active-volcanoes");
|
|
784
926
|
}
|
|
785
927
|
};
|
|
786
928
|
|
|
@@ -791,12 +933,16 @@ var WeatherDomain = class extends BaseClient {
|
|
|
791
933
|
* @param filters Optional pagination filters.
|
|
792
934
|
*/
|
|
793
935
|
async getWis2Stations(filters = {}) {
|
|
794
|
-
const
|
|
936
|
+
const { url, version } = this.resolveEndpoint({
|
|
937
|
+
v1: "/geojson/stations/wis2",
|
|
938
|
+
v2: "/stations?provider=wis2"
|
|
939
|
+
});
|
|
940
|
+
const params = version === "v2" ? filters : {
|
|
795
941
|
limit: filters.limit ?? 100,
|
|
796
942
|
offset: filters.offset ?? 0
|
|
797
943
|
};
|
|
798
|
-
const data = await this.get(
|
|
799
|
-
return this.
|
|
944
|
+
const data = await this.get(url, params);
|
|
945
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "wis2-stations");
|
|
800
946
|
}
|
|
801
947
|
/**
|
|
802
948
|
* Get historical observations for a WIS2 station.
|
|
@@ -804,15 +950,23 @@ var WeatherDomain = class extends BaseClient {
|
|
|
804
950
|
* @param filters Date range and optional WIS2-specific filters.
|
|
805
951
|
*/
|
|
806
952
|
async getWis2Observations(stationId, filters) {
|
|
807
|
-
const
|
|
953
|
+
const url = this.resolveUrl({
|
|
954
|
+
v1: `/observations/wis2/${stationId}`,
|
|
955
|
+
v2: null
|
|
956
|
+
});
|
|
957
|
+
const data = await this.get(url, filters);
|
|
808
958
|
return ObservationQueryResultSchema.parse(data);
|
|
809
959
|
}
|
|
810
960
|
/**
|
|
811
961
|
* Get weather stations from IEM/AZOS network.
|
|
812
962
|
*/
|
|
813
963
|
async getIemStations() {
|
|
814
|
-
const
|
|
815
|
-
|
|
964
|
+
const { url, version } = this.resolveEndpoint({
|
|
965
|
+
v1: "/geojson/stations/azos",
|
|
966
|
+
v2: "/stations?provider=iem"
|
|
967
|
+
});
|
|
968
|
+
const data = await this.get(url);
|
|
969
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "iem-stations");
|
|
816
970
|
}
|
|
817
971
|
/**
|
|
818
972
|
* Get historical observations for an IEM station.
|
|
@@ -820,46 +974,35 @@ var WeatherDomain = class extends BaseClient {
|
|
|
820
974
|
* @param filters Date range filters.
|
|
821
975
|
*/
|
|
822
976
|
async getIemObservations(stationId, filters) {
|
|
823
|
-
const
|
|
977
|
+
const url = this.resolveUrl({
|
|
978
|
+
v1: `/observations/iem/${stationId}`,
|
|
979
|
+
v2: null
|
|
980
|
+
});
|
|
981
|
+
const data = await this.get(url, filters);
|
|
824
982
|
return ObservationQueryResultSchema.parse(data);
|
|
825
983
|
}
|
|
826
984
|
/**
|
|
827
985
|
* Get weather stations from NWS (National Weather Service) network.
|
|
828
986
|
*/
|
|
829
987
|
async getNWSWeatherStations() {
|
|
830
|
-
const
|
|
831
|
-
|
|
988
|
+
const url = this.resolveUrl({
|
|
989
|
+
v1: "/geojson/stations/nws",
|
|
990
|
+
v2: null
|
|
991
|
+
});
|
|
992
|
+
const data = await this.get(url);
|
|
993
|
+
return this.normalizeGeoJSONResponse(data, WeatherStationPropsSchema, "nws-stations");
|
|
832
994
|
}
|
|
833
995
|
/**
|
|
834
996
|
* Get active stations that have reported data in the last 24 hours.
|
|
835
997
|
* @param type The station network type ('iem' or 'wis2').
|
|
836
|
-
*
|
|
837
|
-
* Note: This endpoint returns FeatureCollection directly (not LayerResponse envelope).
|
|
838
998
|
*/
|
|
839
999
|
async getActiveStations(type) {
|
|
840
|
-
const
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
type: "Feature",
|
|
847
|
-
geometry: feature.geometry,
|
|
848
|
-
properties: WeatherStationPropsSchema.parse(feature.properties ?? {}),
|
|
849
|
-
id: feature.id
|
|
850
|
-
};
|
|
851
|
-
});
|
|
852
|
-
return {
|
|
853
|
-
provider: `active-stations-${type}`,
|
|
854
|
-
data: {
|
|
855
|
-
type: "FeatureCollection",
|
|
856
|
-
features
|
|
857
|
-
},
|
|
858
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
859
|
-
count: features.length
|
|
860
|
-
};
|
|
861
|
-
}
|
|
862
|
-
return this.parseGeoJSON(rawData, WeatherStationPropsSchema);
|
|
1000
|
+
const url = this.resolveUrl({
|
|
1001
|
+
v1: "/stations/active",
|
|
1002
|
+
v2: null
|
|
1003
|
+
});
|
|
1004
|
+
const rawData = await this.get(url, { type });
|
|
1005
|
+
return this.normalizeGeoJSONResponse(rawData, WeatherStationPropsSchema, `active-stations-${type}`);
|
|
863
1006
|
}
|
|
864
1007
|
};
|
|
865
1008
|
|
|
@@ -870,7 +1013,9 @@ var EventStream = class extends EventEmitter {
|
|
|
870
1013
|
url;
|
|
871
1014
|
constructor(config) {
|
|
872
1015
|
super();
|
|
873
|
-
|
|
1016
|
+
const baseUrl = config.baseUrl;
|
|
1017
|
+
const apiBasePath = config.apiBasePath ?? DEFAULT_CONFIG.apiBasePath ?? "/api";
|
|
1018
|
+
this.url = `${baseUrl}${apiBasePath}/v1/events/stream?apiKey=${config.apiKey}`;
|
|
874
1019
|
}
|
|
875
1020
|
/**
|
|
876
1021
|
* Start listening to the event stream.
|