# Lorem Forge

Simulates a REST API server with mock data based on a user-defined schema.

## Installation

```bash
npm install lorem-forge
```

## Usage

Create a schema which defines your server, routes, and data models.

```typescript
import { ServerConfig } from 'lorem-forge'

const exampleConfig: ServerConfig = {
  type: 'server',
  name: 'Test Server',
  description: 'A test server schema',
  options: {
    maxPageSize: 2,
    paginationMethod: 'limitOffset',
  },
  routes: [
    {
      type: 'route',
      description: 'Get all users',
      method: 'GET',
      routeKey: '/users',
      responseKey: 'Users',
    },
    {
      type: 'route',
      description: 'Get user by ID',
      method: 'GET',
      routeKey: '/users/{id}',
      responseKey: 'Users',
    },
  ],
  data: {
    Users: {
      type: 'object',
      seed: 12345,
      refDate: '2025-09-12T19:44:39.374Z',
      locale: 'en',
      count: 50,
      index: 'id',
      properties: {
        id: {
          type: 'string',
          format: 'uuid',
        },
        '...': {
          type: 'person',
          fields: ['email', 'lastName', 'firstName'],
        },
        age: {
          type: 'integer',
          minimum: 18,
          maximum: 100,
          distribution: 'normal',
          mean: 30,
          stddev: 10,
        },
        meta: {
          type: 'object',
          properties: {
            createdAt: {
              type: 'date',
              format: 'dateTime',
            },
            isActive: {
              type: 'boolean',
              probability: 0.7,
            },
            role: {
              type: 'string',
              enum: ['admin', 'user', 'guest'],
            },
          },
        },
      },
    },
  },
}

```

Then create a `ServerParser` instance with the schema and generate mock API responses.

```typescript
import { ServerParser } from 'lorem-forge'

const sp = new ServerParser(exampleConfig)

const page1 = sp.generate({
  method: 'GET',
  proxy: '/users'
})

console.log(page1)

// {
//   items: [
//     {
//       id: 'e52399fa-babf-4014-8acd-fbab757bfac2',
//       email: 'Colin_Mante@hotmail.com',
//       lastName: 'Mante',
//       firstName: 'Colin',
//       age: 18,
//       meta: {
//         createdAt: '2025-09-12T18:03:17.275Z',
//         isActive: false,
//         role: 'guest'
//       }
//     },
//     {
//       id: 'e07890eb-d8c1-4347-a7b2-82ce9276de65',
//       email: 'Jermaine_Metz@gmail.com',
//       lastName: 'Metz',
//       firstName: 'Jermaine',
//       age: 31,
//       meta: {
//         createdAt: '2025-09-12T18:03:17.275Z',
//         isActive: true,
//         role: 'admin'
//       }
//     }
//   ],
//   from: 1,
//   to: 2,
//   total: 50,
//   limit: 2,
//   offset: 0,
//   hasMore: true
// }

const user = sp.generate({
  method: 'GET',
  proxy: '/users/e52399fa-babf-4014-8acd-fbab757bfac2'
})

console.log(user)

// {
//   id: "e52399fa-babf-4014-8acd-fbab757bfac2",
//   email: "Colin_Mante@hotmail.com",
//   lastName: "Mante",
//   firstName: "Colin",
//   age: 18,
//   meta: {
//     createdAt: "2025-09-12T18:03:17.275Z",
//     isActive: false,
//     role: "guest"
//   }
// }
```

## API Reference

### ServerParser

The `ServerParser` class is responsible for parsing the server configuration and generating mock API responses.

#### Methods

- `generate(request: HTTPRequest): ApiResponse`

Generates a mock API response based on the provided request.

**Parameters:**

- `request`: The API request object containing method, proxy, and other relevant information.

**Returns:**

- An `ApiResponse` object containing the generated mock data.




## Schema Reference

### Server Schema

The server schema defines the overall structure of your mock API server.

```typescript
{
  type: 'server',                    // Required: Must be 'server'
  name: string,                      // Required: Server name (1-256 chars)
  description: string,               // Required: Server description (max 1024 chars)
  routes: Route[],                   // Required: Array of route definitions
  data: Record<string, DataSchema>,  // Required: Named data schemas
  options?: {                        // Optional: Server configuration
    paginationMethod?: 'limitOffset' | 'cursor',  // Default: 'limitOffset'
    maxPageSize?: number,            // Default: 20, Range: 1-50
  }
}
```

### Route Schema

Routes define API endpoints and link them to data schemas.

```typescript
{
  type: 'route',                     // Required: Must be 'route'
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH',  // Required
  routeKey: string,                  // Required: Route pattern (e.g., '/users/{id}')
  responseKey?: string,              // Optional: Key of data schema for response
  description?: string,              // Optional: Route description
}
```

**Route Pattern Examples:**
- `/users` - Simple route
- `/users/{id}` - Route with path parameter
- `/posts/{postId}/comments/{commentId}` - Multiple path parameters

### Data Schema

Data schemas define the structure and generation rules for mock data.

```typescript
{
  type: 'object',                    // Required: Must be 'object' for root
  locale?: 'en' | 'es' | 'fr' | 'de' | 'it',  // Optional: Default 'en'
  seed?: number,                     // Optional: Random seed for deterministic data
  refDate?: string,                  // Optional: Reference date (ISO 8601)
  count?: number,                    // Optional: Items to generate (1-500, default: 1)
  index?: string,                    // Optional: Property to use for item lookup
  properties?: Record<string, Property>,  // Optional: Object properties
}
```

### Property Types

#### String Properties

```typescript
{
  type: 'string',
  enum?: string[],                   // Array of possible values
  minLength?: number,                // Minimum string length
  maxLength?: number,                // Maximum string length
  pattern?: string,                  // Regex pattern (anchors ^ $ are stripped)
  format?: 'lorem' | 'email' | 'uuid' | 'url' | 'ipv4' | 'ipv6' | 'hostname'
}
```

**Format Examples:**
- `lorem`: Lorem ipsum text
- `email`: Valid email addresses
- `uuid`: UUID v4 format
- `url`: HTTP/HTTPS URLs
- `ipv4`: IPv4 addresses
- `ipv6`: IPv6 addresses
- `hostname`: Domain names

#### Number Properties

```typescript
{
  type: 'integer' | 'float',         // Default: 'integer'
  minimum?: number,                  // Default: 0
  maximum?: number,                  // Default: 200
  distribution?: 'normal' | 'uniform',  // Default: 'uniform'
  mean?: number,                     // Default: 100 (for normal distribution)
  stddev?: number,                   // Default: 20 (for normal distribution)
  precision?: number,                // Default: 1 (for floats)
  count?: number,                    // Default: 1 (returns array if > 1)
}
```

#### Boolean Properties

```typescript
{
  type: 'boolean',
  probability?: number,              // Default: 0.5 (0.0 = always false, 1.0 = always true)
}
```

#### Date Properties

```typescript
{
  type: 'date',
  format?: 'dateTime' | 'time' | 'date',  // Default: 'dateTime'
  when?: 'recent' | 'soon' | 'past' | 'future',  // Relative to refDate
  start?: string,                    // Start date for range (ISO 8601)
  end?: string,                      // End date for range (ISO 8601)
}
```

#### Person Properties

```typescript
{
  type: 'person',
  value?: 'prefix' | 'firstName' | 'lastName' | 'email' | 'phone' | 'address',
  fields?: ('prefix' | 'firstName' | 'lastName' | 'email' | 'phone' | 'address')[],
  pattern?: string,                  // Substitution pattern using {fieldName}
}
```

**Pattern Example:**
```typescript
{
  type: 'person',
  pattern: '{prefix} {firstName} {lastName} <{email}>'
}
// Generates: "Mr. John Doe <john.doe@example.com>"
```

#### Array Properties

```typescript
{
  type: 'array',
  items: Property,                   // Schema for array items
  minItems?: number,                 // Minimum array length
  maxItems?: number,                 // Maximum array length
}
```

#### Object Properties

```typescript
{
  type: 'object',
  properties?: Record<string, Property>,  // Object properties
  required?: string[],               // Required property names
}
```

### Object Spreading

Use the special `'...'` key to spread properties from another schema into an object:

```typescript
{
  type: 'object',
  properties: {
    id: { type: 'string', format: 'uuid' },
    '...': { type: 'person', fields: ['firstName', 'lastName', 'email'] },
    isActive: { type: 'boolean' }
  }
}
```

This generates:
```json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "firstName": "John",
  "lastName": "Doe", 
  "email": "john.doe@example.com",
  "isActive": true
}
```

### Pagination

#### Limit-Offset Pagination (Default)

Query parameters: `?limit=10&offset=20`

Response format:
```typescript
{
  items: T[],
  from: number,
  to: number,
  total: number,
  limit: number,
  offset: number,
  hasMore: boolean,
}
```

#### Cursor-Based Pagination

Set `options.paginationMethod: 'cursor'` in server schema.

Query parameters: `?limit=10&cursor={key:value}`

Response format:
```typescript
{
  items: T[],
  cursor: string | null,
  nextCursor: string | null,
  prevCursor: string | null,
  limit: number
}
```
