369 lines
9.0 KiB
TypeScript

import axios from "axios";
import { Species, InsertSpecies } from "@shared/schema";
export const CITES_API_ENDPOINTS = {
CITES_LEGISLATION: "cites_legislation",
DISTRIBUTIONS: "distributions",
EU_LEGISLATION: "eu_legislation",
REFERENCES: "references"
};
export const IUCN_API_ENDPOINTS = {
// V3 API (legacy)
V3_BASE_URL: "https://apiv3.iucnredlist.org/api/v3",
// V4 API (new version)
BASE_URL: "https://apiv4.iucnredlist.org/api/v4",
VERSION: "version",
TAXA: "taxa",
TAXA_BY_SCIENTIFIC_NAME: "taxa/scientific_name",
THREATS: "threats",
CONSERVATION_MEASURES: "conservation_measures",
HABITATS: "habitats"
};
// API types
export interface ApiResponse<T> {
success: boolean;
data?: T;
message?: string;
status?: number;
}
export interface TokenResponse {
token: string | null;
iucnToken: string | null;
}
export interface ApiStatusResponse {
success: boolean;
connected: boolean;
message?: string;
}
export interface SpeciesSearchResponse {
taxon_concepts: TaxonConcept[];
pagination: {
current_page: number;
per_page: number;
total_entries: number;
total_pages: number;
};
}
export interface TaxonConcept {
id: number;
full_name: string;
author_year: string;
rank: string;
name_status: string;
taxonomy: {
kingdom: string;
phylum: string;
class: string;
order: string;
family: string;
genus: string;
};
cites_listing: string;
cites_listings: CitesListing[];
common_names: CommonName[];
}
export interface CitesListing {
appendix: string;
annotation: string | null;
effective_at: string;
}
export interface CommonName {
name: string;
language: string;
iso_code: string;
}
export interface CitesLegislation {
cites_listings: CitesListing[];
cites_quotas: any[];
cites_suspensions: any[];
}
export interface Distribution {
id: number;
name: string;
iso_code2: string;
geo_entity_type: string;
tags: string[];
references: Reference[];
}
export interface Reference {
id: number;
citation: string;
author: string;
title: string;
year: number;
}
export interface IucnSpeciesResult {
taxonid: number;
scientific_name: string;
kingdom: string;
phylum: string;
class: string;
order: string;
family: string;
genus: string;
main_common_name: string;
authority: string;
published_year: number;
category: string;
assessment_date: string;
criteria: string;
population_trend: string;
marine_system: boolean;
freshwater_system: boolean;
terrestrial_system: boolean;
}
export interface IucnSpeciesResponse {
result: IucnSpeciesResult[];
}
export interface IucnThreat {
code: string;
title: string;
timing: string;
scope: string;
severity: string;
score: string;
}
export interface IucnThreatsResponse {
result: IucnThreat[];
}
export interface IucnHabitat {
code: string;
habitat: string;
suitability: string;
season: string;
majorimportance: string;
}
export interface IucnHabitatsResponse {
result: IucnHabitat[];
}
export interface IucnMeasure {
code: string;
title: string;
year: number;
}
export interface IucnMeasuresResponse {
result: IucnMeasure[];
}
// API client for interacting with our backend
export const apiClient = {
// API Status methods
async checkIucnApiStatus(): Promise<ApiStatusResponse> {
try {
const response = await axios.get<ApiStatusResponse>("/api/iucn/status");
return response.data;
} catch (error: any) {
return {
success: false,
connected: false,
message: error.response?.data?.message || "Failed to check IUCN API status"
};
}
},
async checkCitesApiStatus(): Promise<ApiStatusResponse> {
try {
const response = await axios.get<ApiStatusResponse>("/api/cites/status");
return response.data;
} catch (error: any) {
return {
success: false,
connected: false,
message: error.response?.data?.message || "Failed to check CITES API status"
};
}
},
// Token management
async saveToken(token: string, iucnToken?: string): Promise<ApiResponse<any>> {
try {
const response = await axios.post<ApiResponse<any>>("/api/token", {
token,
iucnToken,
isActive: true
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to save token"
};
}
},
async getTokens(): Promise<TokenResponse> {
try {
const response = await axios.get<TokenResponse>("/api/token");
return response.data;
} catch (error) {
console.error("Failed to retrieve API tokens:", error);
return { token: null, iucnToken: null };
}
},
async getToken(): Promise<string | null> {
try {
const response = await axios.get<TokenResponse>("/api/token");
return response.data.token;
} catch (error) {
console.error("Failed to retrieve API token:", error);
return null;
}
},
// Species search
async searchSpecies(query: string, format: "json" | "xml" = "json"): Promise<ApiResponse<SpeciesSearchResponse>> {
try {
const response = await axios.get<ApiResponse<SpeciesSearchResponse>>("/api/species/search", {
params: { query, format }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to search species"
};
}
},
// Get specific species details
async getSpeciesDetails(
id: number,
endpoint?: string,
format: "json" | "xml" = "json"
): Promise<ApiResponse<any>> {
try {
const response = await axios.get<ApiResponse<any>>(`/api/species/${id}`, {
params: { endpoint, format }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to get species details"
};
}
},
// Save species to database
async saveSpecies(speciesData: InsertSpecies): Promise<ApiResponse<Species>> {
try {
const response = await axios.post<ApiResponse<Species>>("/api/species", speciesData);
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to save species data"
};
}
},
// Get all saved species
async getSavedSpecies(): Promise<ApiResponse<Species[]>> {
try {
const response = await axios.get<{success: boolean; species: Species[]}>("/api/species");
return {
success: true,
data: response.data.species
};
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve saved species"
};
}
},
// Get recent searches
async getRecentSearches(limit: number = 10): Promise<ApiResponse<any>> {
try {
const response = await axios.get<ApiResponse<any>>("/api/searches", {
params: { limit }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve recent searches"
};
}
},
// IUCN Red List API methods
async getIucnSpeciesByName(scientificName: string): Promise<ApiResponse<IucnSpeciesResponse>> {
try {
const response = await axios.get<ApiResponse<IucnSpeciesResponse>>("/api/iucn/species", {
params: { name: scientificName }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve IUCN species data"
};
}
},
async getIucnThreats(scientificName: string): Promise<ApiResponse<IucnThreatsResponse>> {
try {
const response = await axios.get<ApiResponse<IucnThreatsResponse>>("/api/iucn/threats", {
params: { name: scientificName }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve IUCN threats data"
};
}
},
async getIucnHabitats(scientificName: string): Promise<ApiResponse<IucnHabitatsResponse>> {
try {
const response = await axios.get<ApiResponse<IucnHabitatsResponse>>("/api/iucn/habitats", {
params: { name: scientificName }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve IUCN habitats data"
};
}
},
async getIucnMeasures(scientificName: string): Promise<ApiResponse<IucnMeasuresResponse>> {
try {
const response = await axios.get<ApiResponse<IucnMeasuresResponse>>("/api/iucn/measures", {
params: { name: scientificName }
});
return response.data;
} catch (error: any) {
return {
success: false,
message: error.response?.data?.message || "Failed to retrieve IUCN conservation measures data"
};
}
}
};