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

@type_sync/testing

v0.1.2

Published

Testing utilities for TypeSync - mock generation and type-safe test client

Readme

@typesync/testing

Testing utilities for TypeSync - mock data generation and type-safe test client.

Features

  • 🎭 Mock Generation - Generate realistic mock data from Zod schemas
  • 🧪 Test Client - Type-safe HTTP client for testing APIs
  • Assertions - Custom assertions for API testing
  • 🔄 Reproducible - Seeded random generation for consistent tests

Installation

pnpm add -D @typesync/testing

Mock Generation

Generate realistic test data from your Zod schemas:

import { generateMock, generateMocks } from '@typesync/testing';
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string(),
  email: z.string().email(),
  age: z.number().min(18).max(100),
});

// Generate a single mock
const mockUser = generateMock(UserSchema);
// { id: '123e4567-...', name: 'John Doe', email: '[email protected]', age: 25 }

// Generate multiple mocks
const mockUsers = generateMocks(UserSchema, 10);

Custom Values

Override specific fields:

const mockUser = generateMock(UserSchema, {
  overrides: {
    name: 'Alice Smith',
    email: '[email protected]',
  },
});

Custom Generators

Provide custom generators for specific fields:

const mockUser = generateMock(UserSchema, {
  generators: {
    id: () => 'custom-id-123',
    age: () => Math.floor(Math.random() * 50) + 18,
  },
});

Reproducible Mocks

Use a seed for reproducible test data:

const mockUser1 = generateMock(UserSchema, { seed: 12345 });
const mockUser2 = generateMock(UserSchema, { seed: 12345 });
// mockUser1 and mockUser2 are identical

Test Client

Type-safe HTTP client for testing your APIs:

import { createTestClient } from '@typesync/testing';

const client = createTestClient({
  baseURL: 'http://localhost:3000',
});

// Make requests
const response = await client.get('/users');
const user = await client.post('/users', {
  name: 'John Doe',
  email: '[email protected]',
});

// With params and query
const user = await client.get('/users/:id', {
  params: { id: '123' },
  query: { include: 'posts' },
});

// With headers
const response = await client.get('/protected', {
  headers: { Authorization: 'Bearer token' },
});

// Or use setAuth helper
client.setAuth('your-token');
const response = await client.get('/protected');

Test Response

Every response includes:

interface TestResponse<T> {
  status: number;        // HTTP status code
  statusText: string;    // Status text
  headers: Headers;      // Response headers
  data: T;              // Parsed response data
  raw: Response;        // Raw fetch Response
}

Assertions

Custom assertions for API testing:

import { expect, assertStatus, assertSchema } from '@typesync/testing';

// Assert status code
assertStatus(response, 200);

// Assert successful response (2xx)
assertSuccess(response);

// Assert error response (4xx or 5xx)
assertError(response);

// Assert response matches schema
assertSchema(response, UserSchema);

// Assert response has property
assertHasProperty(response, 'id');

// Assert response header
assertHeader(response, 'Content-Type', 'application/json');

// Assert cached response
assertCached(response);

// Assert validation errors
assertValidationError(response, {
  email: 'Invalid email',
  age: 'must be greater than or equal to 18',
});

Using with Test Frameworks

With Vitest:

import { describe, it, expect as vitestExpect } from 'vitest';
import { createTestClient, assertStatus, assertSchema } from '@typesync/testing';

describe('User API', () => {
  const client = createTestClient();

  it('should create a user', async () => {
    const response = await client.post('/users', {
      name: 'John Doe',
      email: '[email protected]',
    });

    assertStatus(response, 201);
    assertSchema(response, UserSchema);
    vitestExpect(response.data.name).toBe('John Doe');
  });
});

With Jest:

import { createTestClient, assertStatus } from '@typesync/testing';

describe('User API', () => {
  const client = createTestClient();

  test('should get users', async () => {
    const response = await client.get('/users');

    assertStatus(response, 200);
    expect(Array.isArray(response.data)).toBe(true);
  });
});

Complete Example

import { describe, it, expect } from 'vitest';
import {
  createTestClient,
  generateMock,
  assertStatus,
  assertSchema,
  assertValidationError,
} from '@typesync/testing';
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  name: z.string().min(2),
  email: z.string().email(),
  age: z.number().min(18),
});

describe('User API', () => {
  const client = createTestClient({
    baseURL: 'http://localhost:3000',
  });

  it('should create a user with valid data', async () => {
    const mockUser = generateMock(UserSchema, {
      overrides: { id: undefined }, // Don't send ID
    });

    const response = await client.post('/users', mockUser);

    assertStatus(response, 201);
    assertSchema(response, UserSchema);
    expect(response.data.name).toBe(mockUser.name);
  });

  it('should reject invalid email', async () => {
    const response = await client.post('/users', {
      name: 'John',
      email: 'invalid-email',
      age: 25,
    });

    assertValidationError(response, {
      email: 'Invalid email',
    });
  });

  it('should reject age under 18', async () => {
    const response = await client.post('/users', {
      name: 'John',
      email: '[email protected]',
      age: 15,
    });

    assertValidationError(response, {
      age: 'greater than or equal to 18',
    });
  });

  it('should get user by ID', async () => {
    // Create user first
    const mockUser = generateMock(UserSchema);
    const createResponse = await client.post('/users', mockUser);

    // Get user
    const response = await client.get('/users/:id', {
      params: { id: createResponse.data.id },
    });

    assertStatus(response, 200);
    assertSchema(response, UserSchema);
    expect(response.data.id).toBe(createResponse.data.id);
  });

  it('should cache GET requests', async () => {
    const response1 = await client.get('/users');
    assertStatus(response1, 200);

    const response2 = await client.get('/users');
    assertCached(response2);
  });
});

API Reference

Mock Generation

  • generateMock<T>(schema, options?) - Generate a single mock
  • generateMocks<T>(schema, count, options?) - Generate multiple mocks
  • createMockGenerator(options) - Create a mock generator with preset options

Test Client

  • createTestClient(options) - Create a test client
  • client.get(path, options) - GET request
  • client.post(path, body, options) - POST request
  • client.put(path, body, options) - PUT request
  • client.patch(path, body, options) - PATCH request
  • client.delete(path, options) - DELETE request
  • client.setAuth(token, type?) - Set authorization header
  • client.setHeader(key, value) - Set header

Assertions

  • assertStatus(response, expected) - Assert status code
  • assertSuccess(response) - Assert 2xx status
  • assertError(response) - Assert 4xx/5xx status
  • assertSchema(response, schema) - Assert data matches schema
  • assertHasProperty(response, property) - Assert property exists
  • assertHeader(response, header, value?) - Assert header
  • assertCached(response) - Assert X-Cache: HIT
  • assertNotCached(response) - Assert X-Cache: MISS
  • assertEqual(actual, expected) - Deep equality
  • assertValidationError(response, fields) - Assert validation errors

License

MIT