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

@bernierllc/validators-api

v0.3.0

Published

API validation - composite validator for REST APIs combining JSON structure, schema, pagination, and temporal consistency

Readme

@bernierllc/validators-api

API validation - composite domain validator for REST APIs combining JSON structure, schema, pagination, and temporal consistency.

Overview

The @bernierllc/validators-api package is a domain-level composite validator that orchestrates multiple primitive validators to provide comprehensive REST API validation. It follows the MECE (Mutually Exclusive, Collectively Exhaustive) architecture principles of the BernierLLC validators ecosystem.

Validation Coverage

  • JSON Structure - Syntax, encoding, formatting, duplicate keys
  • Schema Shape - Types, required fields, constraints, patterns
  • Referential Integrity - Foreign keys, orphaned records, circular references
  • Pagination Contract - Offset/cursor parameters, response structure
  • Temporal Consistency - Timestamps, date ranges, ordering
  • Security Headers - CSP, HSTS, X-Frame-Options, etc.

Installation

npm install @bernierllc/validators-api

Usage

Basic Validation

import { validateApi } from '@bernierllc/validators-api';
import { createSharedUtils } from '@bernierllc/validators-utils';

const utils = createSharedUtils();

const api = {
  json: '{"users": [{"id": 1, "name": "Alice"}]}',
  data: { users: [{ id: 1, name: 'Alice' }] },
  schema: {
    properties: {
      users: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            id: { type: 'number', required: true },
            name: { type: 'string', required: true }
          }
        }
      }
    }
  },
  pagination: { limit: 10, offset: 0 },
  headers: {
    'Content-Security-Policy': "default-src 'self'",
    'X-Frame-Options': 'DENY'
  }
};

const result = await validateApi(api, {}, utils);

if (result.problems.length === 0) {
  console.log('API is valid!');
} else {
  console.log('Validation issues:', result.problems);
}

Configured Validator

Create a reusable validator with specific options:

import { createApiValidator } from '@bernierllc/validators-api';
import { createSharedUtils } from '@bernierllc/validators-utils';

const utils = createSharedUtils();

const validator = createApiValidator({
  validateJsonStructure: true,
  validateSchema: true,
  validatePagination: true,
  validateHeaders: false, // Skip headers validation
  paginationOptions: {
    paginationType: 'cursor',
    maxLimit: 100
  }
});

const result = await validator.validate(api, utils);
console.log('Validation result:', result);

// Get validator metadata
const meta = validator.getMeta();
console.log('Validator:', meta.name);
console.log('Enabled rules:', meta.enabledRules);

JSON Structure Validation

const api = {
  json: '{"name": "test", "value": 123}'
};

const result = await validateApi(api, {
  validateJsonStructure: true
}, utils);

Schema Validation

const api = {
  data: { name: 'Alice', age: 30 },
  schema: {
    properties: {
      name: { type: 'string', required: true, min: 1 },
      age: { type: 'number', min: 0, max: 150 }
    }
  }
};

const result = await validateApi(api, {
  validateSchema: true
}, utils);

Referential Integrity Validation

const api = {
  referentialIntegrity: {
    schemas: [
      {
        collection: 'users',
        primaryKey: 'id',
        foreignKeys: []
      },
      {
        collection: 'posts',
        primaryKey: 'id',
        foreignKeys: [
          {
            sourceField: 'userId',
            targetCollection: 'users',
            targetField: 'id',
            required: true,
            onDelete: 'CASCADE'
          }
        ]
      }
    ],
    documents: {
      users: [{ id: 1, name: 'Alice' }],
      posts: [{ id: 1, userId: 1, title: 'Hello' }]
    }
  }
};

const result = await validateApi(api, {
  validateReferentialIntegrity: true
}, utils);

Pagination Validation

// Offset-based pagination
const api = {
  pagination: { limit: 20, offset: 0 }
};

const result = await validateApi(api, {
  validatePagination: true,
  paginationOptions: { paginationType: 'offset' }
}, utils);

// Cursor-based pagination
const api2 = {
  pagination: { limit: 20, cursor: 'abc123' }
};

const result2 = await validateApi(api2, {
  validatePagination: true,
  paginationOptions: { paginationType: 'cursor' }
}, utils);

Temporal Consistency Validation

const api = {
  temporal: {
    created_at: '2025-01-15T10:30:00Z',
    updated_at: '2025-01-15T10:35:00Z',
    start_date: '2025-01-15',
    end_date: '2025-01-20'
  }
};

const result = await validateApi(api, {
  validateTemporal: true
}, utils);

Security Headers Validation

const api = {
  headers: {
    'Content-Security-Policy': "default-src 'self'",
    'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
    'X-Frame-Options': 'DENY',
    'X-Content-Type-Options': 'nosniff',
    'Referrer-Policy': 'no-referrer'
  }
};

const result = await validateApi(api, {
  validateHeaders: true,
  headerOptions: { strictMode: true }
}, utils);

API

validateApi(api, options, utils)

Validates API content using configured primitive validators.

Parameters:

  • api (ApiContent) - API content to validate
  • options (ApiValidationOptions) - Validation options
  • utils (SharedUtils) - Shared validation utilities

Returns: Promise<ValidationResult>

createApiValidator(options)

Creates a configured API validator instance.

Parameters:

  • options (ApiValidationOptions) - Validator configuration

Returns: Validator object with validate() and getMeta() methods

Types

ApiContent

interface ApiContent {
  json?: string;                           // Raw JSON string
  data?: unknown;                          // Parsed data
  schema?: Schema;                         // Schema definition
  referentialIntegrity?: ReferentialIntegrityData;
  pagination?: unknown;                    // Pagination params/response
  temporal?: unknown;                      // Temporal data
  headers?: Record<string, string | string[]>;
}

ApiValidationOptions

interface ApiValidationOptions {
  validateJsonStructure?: boolean;         // Default: true
  validateSchema?: boolean;                // Default: true
  validateReferentialIntegrity?: boolean;  // Default: true
  validatePagination?: boolean;            // Default: true
  validateTemporal?: boolean;              // Default: true
  validateHeaders?: boolean;               // Default: true
  severity?: 'error' | 'warn' | 'info';    // Default: 'error'
  paginationOptions?: Partial<PaginationContractOptions>;
  headerOptions?: Partial<HeaderPolicyOptions>;
}

Architecture

This package is a domain-level composite validator that composes the following primitive validators:

  • @bernierllc/validators-json-structure - JSON syntax and structure
  • @bernierllc/validators-schema-shape - Schema type validation
  • @bernierllc/validators-referential-integrity - Data integrity
  • @bernierllc/validators-pagination-contract - Pagination rules
  • @bernierllc/validators-temporal-consistency - Temporal validation
  • @bernierllc/validators-header-policy - Security headers

Following MECE principles, each primitive validator handles a specific concern, and this domain validator orchestrates them for complete API validation.

Integration Status

  • Logger Integration: not-applicable - Validators are pure functions without side effects
  • Docs-Suite: ready - Full markdown documentation with code examples
  • NeverHub Integration: not-applicable - Validators operate in stateless validation mode with graceful degradation

This package follows the validators ecosystem pattern of pure validation functions that integrate seamlessly with any application architecture through explicit utility injection.

Integration

With Express.js

import express from 'express';
import { validateApi } from '@bernierllc/validators-api';
import { createSharedUtils } from '@bernierllc/validators-utils';

const app = express();
const utils = createSharedUtils();

app.get('/api/users', async (req, res) => {
  const api = {
    pagination: {
      limit: parseInt(req.query.limit as string) || 10,
      offset: parseInt(req.query.offset as string) || 0
    }
  };

  const result = await validateApi(api, {
    validatePagination: true
  }, utils);

  if (result.problems.length > 0) {
    return res.status(400).json({ errors: result.problems });
  }

  // Proceed with request...
});

With API Testing

import { validateApi } from '@bernierllc/validators-api';
import { createSharedUtils } from '@bernierllc/validators-utils';

describe('API Tests', () => {
  const utils = createSharedUtils();

  it('should validate API response', async () => {
    const response = await fetch('/api/users?limit=10&offset=0');
    const json = await response.text();
    const data = JSON.parse(json);

    const result = await validateApi({
      json,
      data,
      pagination: { limit: 10, offset: 0 },
      headers: Object.fromEntries(response.headers.entries())
    }, {}, utils);

    expect(result.problems).toHaveLength(0);
  });
});

Development

# Install dependencies
npm install

# Build
npm run build

# Test
npm test

# Lint
npm run lint

License

Copyright (c) 2025 Bernier LLC. All rights reserved.

This package is part of the BernierLLC validators ecosystem following MECE architecture principles for composable, maintainable validation logic.