Skip to content

khalic-lab/schmock

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

472 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Schmock

Mock APIs from OpenAPI specs or hand-crafted routes. Callable API, plugin pipeline, framework adapters.

import { schmock } from '@schmock/core'
import { openapi } from '@schmock/openapi'

const mock = schmock({ state: {} })

mock.pipe(await openapi({
  spec: './petstore.yaml',
  seed: { pets: { count: 5 } }
}))

const res = await mock.handle('GET', '/pets')
// → { status: 200, body: [{ petId: 1, name: "Rex", ... }, ...] }

Why Schmock?

  • OpenAPI-first: Point at a spec, get a fully functional CRUD mock with stateful collections, seed data, security validation, and content negotiation
  • Callable API: No HTTP server needed — call mock.handle() directly in tests
  • Plugin pipeline: Chain plugins with .pipe() for validation, pagination, filtering, or custom logic
  • Framework adapters: Drop into Express middleware or Angular HTTP interceptor
  • Smart data generation: Field-name-aware faker generates realistic data from schemas

Packages

Package Description
@schmock/core Core mock builder, routing, and plugin pipeline
@schmock/openapi Auto-register routes from OpenAPI/Swagger specs
@schmock/faker Faker-powered automatic data generation
@schmock/validation Request/response validation via AJV
@schmock/query Pagination, sorting, and filtering
@schmock/express Express middleware adapter
@schmock/angular Angular HTTP interceptor adapter
@schmock/cli Standalone CLI mock server

Quick Start

npm install @schmock/core

Define routes, call them directly

const mock = schmock()

mock('GET /users', [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
])

mock('GET /users/:id', ({ params }) => {
  const users = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
  return users.find(u => u.id === Number(params.id)) || [404, { error: 'Not found' }]
})

const res = await mock.handle('GET', '/users/1')
// → { status: 200, body: { id: 1, name: 'Alice' }, headers: {...} }

Stateful mocks with CRUD

const mock = schmock({ state: { items: [] } })

mock('POST /items', ({ body, state }) => {
  const item = { id: state.items.length + 1, ...body }
  state.items.push(item)
  return [201, item]
})

mock('GET /items', ({ state }) => state.items)

await mock.handle('POST', '/items', { body: { name: 'Widget' } })
const list = await mock.handle('GET', '/items')
// list.body → [{ id: 1, name: 'Widget' }]

Mock from an OpenAPI spec

import { openapi } from '@schmock/openapi'

const mock = schmock({ state: {} })
mock.pipe(await openapi({
  spec: './petstore.yaml',
  seed: { pets: [{ petId: 1, name: 'Rex', tag: 'dog' }] },
  security: true,
}))

await mock.handle('GET', '/pets')           // list
await mock.handle('GET', '/pets/1')         // get by id
await mock.handle('POST', '/pets', {        // create
  body: { name: 'Buddy', tag: 'dog' },
  headers: { authorization: 'Bearer token' },
})
await mock.handle('DELETE', '/pets/1')      // delete

Request spying

await mock.handle('POST', '/items', { body: { name: 'A' } })
await mock.handle('POST', '/items', { body: { name: 'B' } })

mock.called('POST', '/items')       // true
mock.callCount('POST', '/items')    // 2
mock.lastRequest('POST', '/items')  // { body: { name: 'B' }, ... }

Plugin pipeline

import { validationPlugin } from '@schmock/validation'
import { queryPlugin } from '@schmock/query'

mock('GET /users', ({ state }) => state.users)
  .pipe(validationPlugin({ request: { query: querySchema } }))
  .pipe(queryPlugin({
    pagination: { defaultLimit: 20 },
    sorting: { allowed: ['name', 'created_at'] },
    filtering: { allowed: ['role'] },
  }))

// GET /users?filter[role]=admin&sort=name&page=2&limit=10

Framework adapters

Express:

import { toExpress } from '@schmock/express'
app.use('/api', toExpress(mock))

Angular:

import { provideSchmockInterceptor } from '@schmock/angular'
providers: [provideSchmockInterceptor(mock, { baseUrl: '/api' })]

CLI server

npm install -g @schmock/cli
schmock petstore.yaml --port 8080 --cors --seed seed.json

Documentation

Guide Description
Getting Started Installation, core concepts, first mock
OpenAPI Auto-mocking, CRUD, seed data, Prefer header, security, schema patching
Testing Unit tests, integration tests, Angular & Express testing patterns
Express Adapter Express middleware setup and options
Angular Adapter Angular interceptor, helpers, TestBed setup
CLI Command-line mock server
Plugin Development Writing custom plugins
API Reference Complete type and method reference
Debug Mode Request lifecycle logging

Contributing

See CONTRIBUTING.md for development setup and workflow.

License

MIT