npm package: @koale/worms-js-sdk
Description: JS SDK for the World Register of Marine Species API
Author: Alessio Koci
Latest version: 1.0.0

# World Register of Marine Species (WoRMS) JS SDK

![WoRMS](https://www.marinespecies.org/images/layout/worms_logo.png)

----

TypeScript SDK for accessing the [World Register of Marine Species (WoRMS)](https://www.marinespecies.org/) APIs. Fully typed based on the official [WoRMS REST API Specification](https://www.marinespecies.org/rest/).

![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black)
![Node.js](https://img.shields.io/badge/Node.js-43853D?style=for-the-badge&logo=node.js&logoColor=white)
[![npm](https://img.shields.io/npm/v/@koale/worms-js-sdk?style=for-the-badge)](https://www.npmjs.com/package/@koale/worms-js-sdk)



## ✨ Features

- **🔷 Fully typed** - Auto-generated types from WoRMS OpenAPI specification
- **📖 Automatic pagination** - Handles pagination automatically for large datasets
- **🛡️ Error handling** - Typed errors
- **📚 Complete** - Covers all main WoRMS APIs including attributes and taxonomic ranks

## 🚀 Installation

```bash
npm install @koale/worms-js-sdk
# or
yarn add @koale/worms-js-sdk
# or
pnpm add @koale/worms-js-sdk
```

## 📖 Basic Usage

### Example

```typescript
import { WormsClient, AphiaRecord } from '@koale/worms-js-sdk';

const worms = new WormsClient();

// Use the default instance
const records = await worms.searchByScientificName("Homo sapiens");
console.log(`Found ${records.length} records`);


// Search with filters
const marineRecords = await worms.searchByScientificName("Carcharodon", {
    like: true,              // Use LIKE for partial search
    marineOnly: true,        // Only marine organisms
    extantOnly: true,        // Only non-extinct organisms
    pagination: { 
        autoIterate: true,   // Automatically collect all results
        maxResults: 100      // Limit to 100 results
    }
});

// Search by date range
const recentRecords = await worms.getRecordsByDate("2023-01-01", {
    endDate: "2023-12-31",
    marineOnly: true,
    pagination: { autoIterate: true }
});
```

### Automatic Pagination

```typescript
import { WormsClient } from '@koale/worms-js-sdk';

const worms = new WormsClient();

// Get all children of a taxon
const allChildren = await worms.getChildren(2, {
    marineOnly: true,
    pagination: { autoIterate: true }
});

// Get only the first 50 results
const firstBatch = await worms.getChildren(2, {
    pagination: { autoIterate: false },
    offset: 1
});
```

### Detailed Information

```typescript
// Get complete statistics ( this is a wrapper around the other methods, so can be slow)
const stats = await worms.getRecordStats(105838);
console.log(`Children: ${stats.childrenCount}`);
console.log(`Synonyms: ${stats.synonymsCount}`);
console.log(`Vernaculars: ${stats.vernacularsCount}`);
console.log(`Distributions: ${stats.distributionsCount}`);
console.log(`Sources: ${stats.sourcesCount}`);

// Get full record (JSON-LD format)
const fullRecord = await worms.getFullRecord(105838);
console.log(`Full record with linked data: ${fullRecord.scientificname}`);
```


## 🎯 Complete API Reference

### Search Methods

| Method | Description | Pagination |
|--------|-------------|-------------------|
| `searchByScientificName()` | Search by scientific name | ✅ |
| `searchByVernacular()` | Search by vernacular name | ✅ |
| `searchByScientificNames()` | Batch search by scientific names | ❌ |
| `fuzzyMatch()` | Fuzzy search with TAXAMATCH algorithm | ❌ |
| `getRecordsByDate()` | Get records by date range | ✅ |

### Records

| Method | Description | Pagination |
|--------|-------------|-------------------|
| `getRecord()` | Get record by AphiaID | ❌ |
| `getRecords()` | Get multiple records by AphiaIDs | ❌ |
| `getFullRecord()` | Get full record (JSON-LD) | ❌ |
| `getAphiaId()` | Get AphiaID by name | ❌ |
| `getName()` | Get name by AphiaID | ❌ |
| `exists()` | Check if AphiaID exists | ❌ |

### Taxonomic Hierarchy

| Method | Description | Pagination |
|--------|-------------|-------------------|
| `getClassification()` | Complete classification | ❌ |
| `getChildren()` | Direct children | ✅ |
| `getSynonyms()` | Synonyms | ✅ |
| `getVernaculars()` | Vernacular names | ❌ |

### Geographic & Reference Data

| Method | Description | Pagination Support |
|--------|-------------|-------------------|
| `getDistributions()` | Geographic distributions | ❌ |
| `getSources()` | Sources and references | ❌ |

### Attributes

| Method | Description | Pagination Support |
|--------|-------------|-------------------|
| `getAttributeKeys()` | Get attribute keys by ID | ❌ |
| `getAttributeValues()` | Get attribute values by category | ❌ |
| `getAttributes()` | Get attributes by AphiaID | ❌ |
| `getAphiaIdsByAttribute()` | Get AphiaIDs by attribute | ✅ |

### Taxonomic Ranks

| Method | Description | Pagination Support |
|--------|-------------|-------------------|
| `getTaxonRanksById()` | Get taxonomic ranks by ID | ❌ |
| `getTaxonRanksByName()` | Get taxonomic ranks by name | ❌ |
| `getRecordsByTaxonRank()` | Get records by taxonomic rank | ✅ |

### External IDs

| Method | Description |
|--------|-------------|
| `getExternalId()` | Get external ID by AphiaID |
| `getRecordByExternalId()` | Get record by external ID |

Supported external ID types: `algaebase`, `bold`, `dyntaxa`, `fishbase`, `iucn`, `lsid`, `ncbi`, `tsn`, `gisd`

### Utility Methods

These are utility methods that are wrappers around the other methods.

| Method | Description |
|--------|-------------|
| `getRecordStats()` | Get complete statistics for a record |
| `getAllResults()` | Get all results from a paginated function |
| `exists()` | Check if an AphiaID exists |

## 🛡️ Error Handling

```typescript
import { WormsError } from '@koale/worms-js-sdk';

try {
    const record = await worms.getRecord(999999999);
} catch (error) {
    if (error instanceof WormsError) {
        console.error(`WoRMS Error: ${error.message}`);
        console.error(`Status: ${error.status}`);
    } else {
        console.error('Unknown error:', error);
    }
}
```

## 🔧 Client Configuration

```typescript
const client = new WormsClient({
    baseUrl: "https://www.marinespecies.org/rest",
    fetchOptions: {
        headers: {
            "User-Agent": "MyApp/1.0",
            "Accept": "application/json"
        },
        timeout: 10000
    }
});
```

## 📊 TypeScript Types

All types are fully typed:

```typescript
import type { 
    AphiaRecord, 
    Classification, 
    Distribution, 
    Vernacular,
    Source,
    AphiaRank,
    AttributeKey,
    AttributeValue,
    Attribute,
    AphiaAttributeSet,
    AphiaRecordFull,
    WormsClientOptions,
    PaginationOptions,
    PaginatedResult,
    WormsError
} from '@koale/worms-js-sdk';
```

## 🚀 Complete Examples

Check the [examples/index.ts](examples/index.ts) file for complete usage examples.

Run the examples:

```bash
pnpm run example
# or
tsx examples/index.ts
```

## 📝 License

MIT License. See [LICENSE](LICENSE) for more details.

## 🙏 Acknowledgments

- [World Register of Marine Species (WoRMS)](https://www.marinespecies.org/)
- [WoRMS REST API](https://www.marinespecies.org/rest/)
- [openapi-fetch](https://openapi-ts.dev/openapi-fetch/)

## 💬 Support

For issues or questions:
- Open an [issue](https://github.com/alewin/worms-js-sdk/issues)
- Check the [WoRMS API documentation](https://www.marinespecies.org/rest/)