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

@factify/sdk-ts

v0.1.0

Published

TypeScript SDK for Factify API integration

Readme

Factify TypeScript SDK

The official TypeScript SDK for Factify's API. Built with ConnectRPC for type-safe, protocol-agnostic API calls.

🚀 Quick Start

npm install @factify/sdk-ts
import { FactifyClient } from '@factify/sdk-ts';

const client = new FactifyClient({
  baseUrl: 'https://rpc.factify.com',
  apiTokenAuth: {
    apiToken: process.env.FACTIFY_API_TOKEN, // ffy.{id}.{secret}
    validateFormat: true,
  },
});

// Create document
const pdfFile = new File(['PDF content'], 'document.pdf', { type: 'application/pdf' });
const result = await client.documents.createDocument(pdfFile, {
  name: 'My Document',
  description: 'Document description'
});

// Generate cover page
const coverPage = await client.coverPages.createDocumentCoverPage({
  documentId: result.documentId,
  title: 'My Document',
  description: 'Detailed document description'
});

📚 Documentation

✨ Features

  • 🔐 API Token Authentication - Secure machine-to-machine auth with ffy.{id}.{secret} tokens
  • 📄 Document Management - Create and manage documents
  • 🎨 Entry Page Generation - Create branded entry pages
  • 🔒 Access Control - Attach/detach access policies for document permissions
  • 📝 Form Submissions - Retrieve and manage form data with filtering
  • ⚡ ConnectRPC Protocol - Type-safe calls over REST/JSON or gRPC-Web
  • 🔄 Automatic Retries - Built-in exponential backoff for reliability
  • 🌐 Universal Support - Works in Node.js and browsers
  • 📦 TypeScript Native - Full type safety and IntelliSense

🏗️ Core Workflow

The Factify SDK provides a simplified PDF document workflow:

// 1. Initialize client
const client = new FactifyClient({
  baseUrl: 'https://rpc.factify.com',
  apiTokenAuth: { apiToken: 'ffy.your_token_id.your_token_secret' }
});

// 2. Create and upload PDF document
const pdfFile = new File(['PDF content'], 'report.pdf', { type: 'application/pdf' });
const result = await client.documents.createDocument(pdfFile, {
  name: 'Quarterly Report',
  description: 'Q4 2024 performance analysis'
});

// 3. Configure access (optional)
await client.access.attachAccessPolicy({
  organizationId: 'your-org-id',
  documentId: result.documentId,
  policyId: 'your-policy-id'
});

// 4. Generate cover page
const coverPage = await client.coverPages.createDocumentCoverPage({
  documentId: result.documentId,
  title: 'Quarterly Report',
  description: 'Comprehensive Q4 analysis with recommendations',
  downloadLinkExpirationSeconds: 7200
});

// 5. Retrieve form submissions (if applicable)
const submissions = await client.forms.getFormSubmissions({
  formId: 'your-form-id',
  filters: {
    createdAtAfter: { seconds: BigInt(Date.now() / 1000 - 86400) } // Last 24h
  }
});

🔧 Environment Setup

The SDK reads environment variables but does NOT automatically load .env files. You must manually configure dotenv in your application:

# .env file
FACTIFY_API_TOKEN=ffy.your_token_id.your_token_secret
FACTIFY_API_URL=https://rpc-stage.factify.com
// Load environment variables manually (recommended)
import dotenv from 'dotenv';
dotenv.config();

// Then initialize client
const client = new FactifyClient({
  baseUrl: process.env.FACTIFY_API_URL || 'https://rpc.factify.com',
  apiTokenAuth: {
    apiToken: process.env.FACTIFY_API_TOKEN!,
    validateFormat: true
  }
});

🎯 Service Overview

| Service | Purpose | Key Methods | |---------|---------|-------------| | documents | PDF document management | createDocument(), getDocument(), listDocuments() | | coverPages | Branded cover generation | createDocumentCoverPage() | | access | Permission management | attachAccessPolicy(), detachAccessPolicy(), inspectAccess() | | forms | Form data retrieval | getFormSubmissions() |

🏃♂️ Development

# Setup
npm install

# Build
npm run build

# Test
npm test

# Development with watch
npm run dev

# Generate types from proto (developers only)
npm run generate

📖 Examples

Basic PDF Document Upload

// Create a PDF file (browser or Node.js)
const pdfFile = new File(['PDF content'], 'contract.pdf', { type: 'application/pdf' });

const result = await client.documents.createDocument(pdfFile, {
  name: 'Service Contract',
  description: 'Service agreement for Q1 2024'
});

console.log('Document created:', result.documentId);

Access Control

// Attach policy
await client.access.attachAccessPolicy({
  organizationId: 'org-123',
  documentId: 'doc-456', 
  policyId: 'policy-789'
});

// Check what policies are attached
const access = await client.access.inspectAccess({
  documentId: 'doc-456'
});
console.log(`${access.accessPolicies.length} policies attached`);

Form Data with Filtering

import { create, TimestampSchema } from '@bufbuild/protobuf';

const submissions = await client.forms.getFormSubmissions({
  formId: 'form-123',
  filters: {
    createdAtAfter: create(TimestampSchema, {
      seconds: BigInt(Math.floor(Date.now() / 1000) - 86400) // 24h ago
    })
  }
});