@treeviz/familysearch-catalog-sdk
v1.0.4
Published
TypeScript SDK for FamilySearch Catalog and Places APIs - Parish records, coverage periods, and place resolution
Maintainers
Readme
@treeviz/familysearch-catalog-sdk
Part of the @treeviz organization - A collection of tools for genealogy data processing and visualization.
A modern TypeScript SDK for interacting with the FamilySearch Catalog and Places APIs. This package provides reusable utilities for resolving place names, looking up parish records, and extracting coverage periods from genealogical records.
Features
- 🗺️ Places API - Search and normalize place names
- 📚 Catalog API - Search parish and civil records
- 🔍 Metadata Parsing - Extract parish names, date ranges, and registry types
- 💾 Smart Caching - In-memory LRU cache with TTL support
- 🔐 OAuth Integration - Reuses
@treeviz/familysearch-sdkfor authentication - 📘 TypeScript-first - Full type definitions included
- ⚡ Promise-based - Modern async/await API
Installation
npm install @treeviz/familysearch-catalog-sdkQuick Start
import { FamilySearchCatalog } from "@treeviz/familysearch-catalog-sdk";
// Initialize the resolver
const resolver = new FamilySearchCatalog({
clientId: process.env.FS_CLIENT_ID!,
clientSecret: process.env.FS_CLIENT_SECRET,
environment: "production",
enableCache: true,
});
// Resolve a place name
const result = await resolver.resolvePlace("Kismaros, Hungary");
console.log(result);
// Output:
// {
// placeId: "...",
// standardizedName: "Kismaros, Pest, Hungary",
// registry: "Roman Catholic Parish of Nagymaros",
// coverage: "1730-1895",
// sources: [...]
// }Usage
Basic Place Resolution
const result = await resolver.resolvePlace("Budapest");
if (result) {
console.log(`Standardized: ${result.standardizedName}`);
console.log(`Registry: ${result.registry}`);
console.log(`Coverage: ${result.coverage}`);
}Search Places
const places = await resolver.searchPlaces("Kismaros", 5);
for (const place of places) {
console.log(`${place.name} - ${place.fullName}`);
// URLs are automatically generated for the configured environment
console.log(`Place details: ${place.url}`);
console.log(`Catalog search: ${place.catalogUrl}`);
console.log(`Records search: ${place.recordsUrl}`);
}Note: The SDK automatically generates FamilySearch web UI URLs (url, catalogUrl, recordsUrl) for each place result based on the configured environment (production/beta/integration).
Search Catalog
const records = await resolver.searchCatalog("Kismaros, Hungary");
for (const record of records) {
console.log(`${record.title} (${record.coverageYears})`);
console.log(`Author: ${record.author}`);
console.log(`URL: ${record.url}`);
}Using Individual Modules
import { CatalogPlacesClient, PlacesAPI, CatalogAPI } from "@treeviz/familysearch-catalog-sdk";
const client = new CatalogPlacesClient({
clientId: process.env.FS_CLIENT_ID!,
environment: "production",
});
const places = new PlacesAPI(client);
const catalog = new CatalogAPI(client);
// Search places
const placeResults = await places.searchPlace("Budapest");
// Search catalog
const catalogResults = await catalog.searchByPlace("Budapest");
// Extract coverage period
const coverage = catalog.getCoveragePeriod(catalogResults);
console.log(`Coverage: ${coverage?.startYear}-${coverage?.endYear}`);Parser Utilities
import * as Parser from "@treeviz/familysearch-catalog-sdk/parser";
// Extract parish name from title
const parish = Parser.extractParishName("Roman Catholic Parish of Nagymaros");
console.log(parish); // "Nagymaros"
// Parse date range
const range = Parser.parseDateRange("Records from 1730-1895");
console.log(range); // { start: 1730, end: 1895 }
// Extract registry type
const type = Parser.extractRegistryType("Roman Catholic Parish of Nagymaros");
console.log(type); // "Roman Catholic"
// Normalize place name
const normalized = Parser.normalizePlaceName("Kismarós");
console.log(normalized); // "kismaros"Caching
const resolver = new FamilySearchCatalog({
clientId: process.env.FS_CLIENT_ID!,
enableCache: true,
cacheTTL: 3600, // 1 hour
});
// First call - makes API request
await resolver.resolvePlace("Budapest");
// Second call - uses cached result
await resolver.resolvePlace("Budapest");
// Clear cache
resolver.clearCache();
// Get cache stats
const stats = resolver.getCacheStats();
console.log(`Cache size: ${stats.size}, enabled: ${stats.enabled}`);Authentication
// Set access token for authenticated requests
resolver.setAccessToken("your-oauth-token");
// Now you can make authenticated requests
const result = await resolver.resolvePlace("Budapest");API Reference
FamilySearchCatalog
The main class for high-level operations.
Constructor
new FamilySearchCatalog(config: CatalogPlacesClientConfig)Config options:
clientId(required) - FamilySearch OAuth client IDclientSecret(optional) - FamilySearch OAuth client secretenvironment(optional) - Environment:"production"(default),"beta", or"integration"enableCache(optional) - Enable caching (default:true)cacheTTL(optional) - Cache TTL in seconds (default:3600)debug(optional) - Enable debug logging (default:false)
Methods
resolvePlace(placeName, options?)- Resolve a place namesearchPlaces(query, count?)- Search for placessearchCatalog(placeName, count?)- Search cataloggetPlaceById(placeId)- Get place details by IDsetAccessToken(token)- Set OAuth access tokenclearCache()- Clear the cachegetCacheStats()- Get cache statistics
PlacesAPI
Low-level Places API.
searchPlace(query, options?)- Search for placesgetPlaceById(placeId)- Get place by IDnormalizePlace(placeName)- Normalize a place name
CatalogAPI
Low-level Catalog API.
searchByPlace(placeName, options?)- Search catalog by placegetRecordDetails(recordId)- Get catalog record detailsgetCoveragePeriod(records)- Extract coverage period from recordsextractParishInfo(records)- Extract parish information
Parser Utilities
extractParishName(title)- Extract parish name from titleextractRegistryType(title)- Extract registry typeparseDateRange(text)- Parse date range from textextractAuthor(attribution)- Extract author nameformatYearRange(start, end)- Format year range as stringnormalizePlaceName(placeName)- Normalize place name for comparisoncalculateSimilarity(str1, str2)- Calculate string similarity
Type Definitions
ResolvedPlace
interface ResolvedPlace {
placeId: string;
standardizedName: string;
registry: string;
coverage: string;
sources: CatalogSource[];
}CatalogSource
interface CatalogSource {
id: string;
title: string;
author: string;
years: string;
url: string;
}PlaceSearchResult
interface PlaceSearchResult {
id: string;
name: string;
fullName: string;
type?: string;
latitude?: number;
longitude?: number;
parent?: {
id: string;
name: string;
};
}CatalogSearchResult
interface CatalogSearchResult {
id: string;
title: string;
author: string;
coverageYears: string;
place: string;
type: string;
url: string;
metadata?: Record<string, unknown>;
}Dependencies
This package depends on:
@treeviz/familysearch-sdk- For OAuth authentication and base HTTP client
Development
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm test
# Watch mode
npm run devRelated Packages
- @treeviz/familysearch-sdk - Core FamilySearch API SDK
- @treeviz/gedcom-parser - GEDCOM file parser
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
MIT License - see LICENSE file for details
Copyright (c) 2026 idavidka and @treeviz contributors
Author
idavidka and @treeviz contributors
Repository
https://github.com/idavidka/familysearch-catalog-sdk
