Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintignore

This file was deleted.

44 changes: 0 additions & 44 deletions .eslintrc.json

This file was deleted.

79 changes: 79 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# AGENT.md

## Project Overview

**servemocks** is a mock server tool that generates REST APIs from JSON, XML, and other sample files in a directory. It's built on Express and can be used as a CLI tool or mounted as middleware in an existing Express app.

## Commands

```bash
# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Lint
npm run lint

# Fix lint issues
npm run lint:fix

# Release (uses standard-version)
npm run release # patch release
npm run release:patch # patch release
npm run release:minor # minor release
npm run release:major # major release
```

## Quality checks

- Make sure to run `npm test` and `npm run lint:fix` after changes have been finished
- Keep the project lightweight and avoid adding more dependencies
- Make sure to update `src/serve-mocks.spec.js` with tests for new features, it is basically a kind of e2e test which covers most of logic

## Project Structure

```
src/
├── serve-mocks.js # Main entry point
├── public-api.js # Public exports
├── mock-file-types.js # Supported file types
├── cli.js # CLI implementation
├── serve-mocks.spec.js # Main tests
├── service/
│ ├── endpoint-registration.service.js # Endpoint registration logic
│ ├── script-evaluation.service.js # Dynamic response (.mjs) evaluation
│ └── logger.js # Logging utility
└── utilities/
├── sorting.js # Endpoint sorting by specificity
├── http-method.js # HTTP method utilities
├── encoding.js # Encoding utilities
└── async-utilities.js # Async utilities
```

## Key Concepts

### Mock File Conventions
- File naming: `<http-method>.<extension>` or `<path>.<http-method>.<extension>`
- Example: `user.post.json` → POST /user
- `[any]` can be used as a wildcard for any path segment
- HTTP method is derived from the filename (get, post, put, patch, delete)

### Dynamic Responses
- Use `.mjs` files for dynamic/mock responses
- Supported modes: `eval`, `dynamicImport`, `disabled`

### Options
- `responseDelay_ms`: Default delay before responses (default: 100)
- `dynamicMockResponsesMode`: `'eval' | 'dynamicImport' | 'disabled'` (default: `'eval'`)
- `endpointRegistrationLogging`: `'verbose' | 'compact' | 'disabled'` (default: `'verbose'`)

## Dependencies

- **express**: Web framework
- **chalk**: Terminal colors
- **commander**: CLI parsing
- **cors**: CORS middleware
- **glob**: File pattern matching
- **ajv**: JSON Schema validation
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,31 @@ Starting from version 2 it is also possible to produce dynamic mock responses by
as mock file. Use the file extension `.mjs` to enable this function.
Example: [examples/v3](https://github.com/diva-e/servemocks/tree/main/examples/mock-api/v3).

## OpenAPI Import

You can import endpoints from an OpenAPI 3.x specification to generate mock files:

```bash
servemocks import <spec-file> <output-dir> [-i, --ignore-examples]
```

**Options:**

`-i, --ignore-examples` - Ignore examples in the spec and generate your own

**Example:**

```bash
servemocks import openapi.json ./mock-api
```

This will create mock files for each endpoint in the specification:

* File naming uses explicit HTTP method (e.g., `user.get.json`, `user.post.json`)
* Path parameters are converted to wildcards (e.g., `/pets/{petId}` → `pets/[any]/petId.get.json`)
* Request body schemas are converted to JSON Schema validation
* Response examples from the spec are used when available

## Getting Started

### Install
Expand All @@ -54,10 +79,18 @@ npm add -D servemocks

### Usage

**Start the mock server:**

```plain
servemocks <directory> [-p, --port=8080] [-c, --compact-logging]
```

**Import from OpenAPI spec:**

```plain
servemocks import <spec-file> <output-dir> [-i, --ignore-examples]
```

Example:

```bash
Expand Down
26 changes: 25 additions & 1 deletion cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,41 @@

import { program } from 'commander'
import { serveMocks } from './src/serve-mocks.js'
import { importOpenAPI } from './src/service/openapi-import.service.js'
import { readFileSync } from 'fs'
import { Logger } from './src/service/logger.js'

import { fileURLToPath } from 'url'
import path from 'path'

const logger = new Logger()

const packageJsonPath = path.join(fileURLToPath(import.meta.url), '../package.json')
const { version } = JSON.parse(readFileSync(packageJsonPath, { encoding: 'utf-8' }))

const hostname = process.env.SERVEMOCKS_HOST || '127.0.0.1'

program
.name('servemocks')
.description('Conventional Mock-Server')
.version(version)

program
.command('import <spec-file> <output-dir>')
.description('Import endpoints from an OpenAPI 3.x specification')
.option('-i, --ignore-examples', 'Ignore examples in the spec and generate our own')
.action(async (specFile, outputDir, options) => {
try {
await importOpenAPI(specFile, outputDir, {
ignoreExamples: options.ignoreExamples
})
} catch (error) {
logger.error('Import failed:', error.message)
process.exit(1)
}
})

program
.arguments('<mock-directory>')
.option('-p, --port <port>', 'Change webserver port')
.option('-c, --compact-logging', 'Limits the number of endpoints which are being printed to the console on init')
Expand All @@ -24,4 +47,5 @@ program
}
serveMocks(mockDirectory, env.port || 8080, hostname, options)
})
.parse(process.argv)

program.parse(process.argv)
53 changes: 53 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import js from '@eslint/js'
import jsdoc from 'eslint-plugin-jsdoc'
import globals from 'globals'

export default [
{
ignores: ['examples/**', 'node_modules/**']
},
js.configs.recommended,
{
files: ['**/*.js'],
plugins: {
jsdoc
},
languageOptions: {
ecmaVersion: 2020,
sourceType: 'module',
globals: {
...globals.node,
...globals.jest
}
},
rules: {
'indent': ['error', 2],
'linebreak-style': ['error', 'unix'],
'quotes': ['error', 'single'],
'max-len': ['warn', 120],
'semi': ['warn', 'never'],
'comma-dangle': ['error', 'only-multiline'],
'no-unused-vars': ['error', {
argsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}],
'no-console': 'error',
'jsdoc/require-param-description': 'off',
'jsdoc/require-returns-description': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/require-jsdoc': ['error', {
require: {
FunctionDeclaration: true,
MethodDefinition: true,
ClassDeclaration: true
}
}]
}
},
{
files: ['**/*.spec.js'],
rules: {
'no-console': 'off'
}
}
]
Loading