npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rachelallyson/planning-center-people-ts

v4.0.0

Published

A strictly typed TypeScript client for Planning Center Online People API with comprehensive functionality and enhanced developer experience

Readme

@rachelallyson/planning-center-people-ts

A modern, type-safe TypeScript library for interacting with the Planning Center Online People API. Built with a class-based architecture, comprehensive error handling, and advanced features like person matching.

📖 For the latest documentation and examples, see the Monorepo Documentation Site

Features

  • Strict TypeScript: Full type safety with no any types
  • JSON:API 1.0 Compliant: Follows the JSON:API specification exactly
  • Class-based API: PcoClient with modules (people, contacts, workflows, etc.)
  • Rate Limiting: Built-in rate limiting with PCO's 100 req/20s policy
  • Modern HTTP: Uses native fetch API (no external dependencies)
  • Authentication: Supports both Personal Access Tokens and OAuth 2.0
  • Error Handling: PcoApiError with status and JSON:API error details; check error.status (401, 422, 429, etc.)
  • Request Timeouts: Optional timeout in config
  • Pagination: Automatic pagination support
  • File Upload Handling: Intelligent file upload detection and processing for custom fields
  • No Index Signatures: Clean type definitions without index signatures

Installation

npm install @planning-center-people-ts

No external dependencies required! This package uses the native fetch API available in all modern environments.

Quick Start

import { PcoClient } from '@rachelallyson/planning-center-people-ts';

const client = new PcoClient({
    auth: {
        type: 'basic',
        appId: 'your-app-id',
        appSecret: 'your-app-secret',
    },
    // Or OAuth: auth: { type: 'oauth', accessToken, refreshToken, onRefresh, onRefreshFailure }
});

const people = await client.people.getPage({ per_page: 10, include: ['emails', 'phone_numbers'] });
const person = await client.people.getById('person-id', { include: ['emails'] });
const newPerson = await client.people.create({ first_name: 'John', last_name: 'Doe', status: 'active' });
const updatedPerson = await client.people.update('person-id', { first_name: 'Jane' });
await client.people.delete('person-id');

// Smart file upload for custom fields
await client.fields.createPersonFieldData('person-id', 'field-definition-id', '<a href="https://example.com/document.pdf" download>View File</a>');

Imports

This package exports the client, resource types, PcoApiError, and the JSON:API types used in responses (Relationship, ResourceIdentifier, ResourceObject), plus the package’s own error-handling and helper APIs. For lower-level utilities (e.g. createDebugLogger, PcoRateLimiter, rate-limit headers), use @rachelallyson/planning-center-base-ts directly.

Configuration

Debug logging

Turn logs on or off to see everything that happens inside the package (requests, auth, rate limit, cache, errors). Debug is provided by the base package and shared across all PCO clients. Enable at creation or at runtime:

import { PcoClient } from '@rachelallyson/planning-center-people-ts';

// Enable at creation
const client = new PcoClient({
  auth: { type: 'personal_access_token', personalAccessToken: '...' },
  debug: true,
});

// Or with options
const client = new PcoClient({
  auth: { ... },
  debug: {
    prefix: '[MyApp]',
    includePayloads: false,  // set true to log request/response bodies (avoid in production)
    onLog: (message, data) => myLogger.info(message, data),
  },
});

// Toggle at runtime
client.updateConfig({ debug: true });
client.updateConfig({ debug: false });

With debug: true, every event is logged with a clear prefix (default [PCO People]), including:

  • request start (method, endpoint, requestId)
  • request complete (status, duration)
  • request error
  • auth success/failure/refresh
  • rate limit and rate available
  • cache hit/miss/set/invalidate
  • generic errors

Authentication

Use PcoClient with one of three auth types:

Personal Access Token:

const client = new PcoClient({
  auth: {
    type: 'personal_access_token',
    personalAccessToken: 'your-token-here',
    personalAccessTokenSecret: 'optional-secret', // or use env
  },
});

OAuth 2.0 (requires onRefresh and onRefreshFailure):

const client = new PcoClient({
  auth: {
    type: 'oauth',
    accessToken: '...',
    refreshToken: '...',
    onRefresh: async (tokens) => { /* save tokens */ },
    onRefreshFailure: async (err) => { /* handle */ },
  },
});

Basic (app id/secret): auth: { type: 'basic', appId, appSecret }.

Optional config: baseURL, timeout, headers, debug. See the config reference in the monorepo docs.

API overview

Use PcoClient and its modules. Each list-capable module (e.g. people, households, workflows) provides:

  • getAll(options?) – Fetch all pages; returns PaginationResult<T> with data, totalCount, pagesFetched.
  • getPage(options?) – Fetch a single page; returns { data, meta?, links? }.
  • getById(id, options?) – Fetch one resource; use options.include for related data (e.g. { include: ['emails'] }).
  • create(data), update(id, data), delete(id) – Mutations.

Example: client.people.getAll({ where: { status: 'active' } }), client.people.getPage({ per_page: 25, page: 1 }), client.people.getById('id', { include: ['emails'] }). Contacts are person-scoped: client.contacts.createEmail(personId, data).

Error Handling

Use PcoApiError from the package (re-exported from @rachelallyson/planning-center-base-ts) for catch blocks. The client uses the core package for HTTP, retries, and rate limiting.

import { PcoClient, PcoApiError } from '@rachelallyson/planning-center-people-ts';

try {
    const people = await client.people.getPage({ per_page: 10 });
} catch (error) {
    if (error instanceof PcoApiError) {
        console.error('PCO Error:', { message: error.message, status: error.status, errors: error.errors });
        if (error.status === 401) { /* auth */ }
        if (error.status === 429) { /* rate limit */ }
        if (error.status === 422) { /* validation */ }
    }
    throw error;
}

Type Safety

All methods are fully typed; resources are flattened (attributes at top level):

const person = await client.people.getById('person-id');
console.log(person.first_name); // ✅ TypeScript knows this exists
const newPerson = await client.people.create({ first_name: 'John', last_name: 'Doe', status: 'active' });

Rate Limiting

Rate limiting is handled automatically by the core client. Check status with:

const rateLimitInfo = client.getRateLimitInfo();
console.log('Requests used:', rateLimitInfo.requestsUsed);
console.log('Requests remaining:', rateLimitInfo.requestsRemaining);

Pagination

const page = await client.people.getPage({ per_page: 10, page: 1 });
const allPeople = await client.people.getAll({ per_page: 100 });

Environment Support

This package uses the native fetch API, which is available in:

  • Node.js 18+ (built-in)
  • All modern browsers (built-in)
  • Deno (built-in)

For older Node.js versions, you can use a fetch polyfill:

npm install node-fetch
import fetch from 'node-fetch';
global.fetch = fetch;

API Style

Use the class-based client and modules (v2.0+):

const client = new PcoClient({ auth: { type: 'basic', appId, appSecret } });
const people = await client.people.getPage({ per_page: 10 });
const all = await client.people.getAll({ where: { status: 'active' } });

Testing

Unit Tests

Run the comprehensive unit test suite:

npm test              # Run all unit tests
npm run test:watch    # Run tests in watch mode
npm run test:coverage # Run tests with coverage report
npm run test:ci       # Run tests for CI/CD

The unit tests cover:

  • Rate limiting functionality
  • Error handling and retry logic
  • Core client operations
  • All People API functions
  • Type safety and edge cases

Integration Tests

Test against the real PCO API to validate functionality:

npm run test:integration

Prerequisites:

  1. Copy .env.test.example to .env.test

  2. Fill in your PCO credentials:

    PCO_APP_ID=your_app_id_here
    PCO_APP_SECRET=your_app_secret_here
    # OR use OAuth:
    # PCO_ACCESS_TOKEN=your_token_here
  3. Ensure your PCO app has People API permissions

What Integration Tests Cover:

  • Authentication and configuration
  • Read operations (people, households, field definitions)
  • Write operations with automatic cleanup
  • Rate limiting and performance
  • Error handling with real API responses
  • Concurrent request handling
  • Runtime type validation - All 11 core resource types validated against real API responses

Type Validation:

The integration tests include comprehensive runtime validation to ensure TypeScript types match actual PCO API responses:

  • 11 Resource Types Validated: Person, Email, PhoneNumber, Address, Household, SocialProfile, FieldDefinition, FieldOption, FieldDatum, WorkflowCard, WorkflowCardNote
  • Attribute Type Checking: Validates all attributes match expected types (string, number, boolean, date, null)
  • Relationship Validation: Ensures relationship structures conform to JSON:API specification
  • Pagination Validation: Validates links and metadata structures
  • API Change Detection: Catches breaking changes in PCO API immediately

See TYPE_VALIDATION_SUMMARY.md for detailed documentation on type validation coverage and approaches for the remaining 11 resource types.

Safety Features:

  • All test data is automatically cleaned up
  • Uses descriptive test names (e.g., "TEST_INTEGRATION_2025")
  • Respects PCO rate limits (100 requests per 20 seconds)
  • 30-second timeout per test
  • Comprehensive error handling

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests (both unit and integration)
  5. Submit a pull request

📚 Comprehensive Documentation

Complete documentation is available in the monorepo documentation site:

License

MIT