npm package: @http-forge/playwright
Description: Runtime package for HTTP Forge generated Playwright API clients
Latest version: 0.1.0

# @http-forge/playwright

Runtime package for HTTP Forge generated Playwright API clients.

## Overview

`@http-forge/playwright` provides lightweight runtime dependencies for TypeScript API clients generated by `@http-forge/codegen`. It includes environment variable management, URL building, and shared types to reduce code duplication in generated files.

## Installation

```bash
npm install @http-forge/playwright @playwright/test
```

## Features

- **ForgeEnv**: Environment and variable management for API clients
- **Shared Types**: Common types (headers, request context, options) to reduce generated code size
- **Zero Dependencies**: No runtime dependencies except peer dependency on `@playwright/test`
- **Tree-shakeable**: Multiple entry points for optimal bundle size

## Usage

### Basic Environment Setup

```typescript
import { ForgeEnv } from '@http-forge/playwright';

// Create environment with variables
const env = ForgeEnv.create({
    baseUrl: 'https://api.example.com',
    apiKey: 'your-api-key',
    tenant: 'TELUS'
});

// Get variables
env.get('baseUrl'); // 'https://api.example.com'

// Resolve template strings
env.resolve('{{baseUrl}}/users'); // 'https://api.example.com/users'

// Build URLs with path params and query
env.buildUrl('{{baseUrl}}/users/:id', {
    params: { id: '123' },
    query: { include: 'profile' }
}); // 'https://api.example.com/users/123?include=profile'
```

### Multi-Environment Setup

```typescript
import { ForgeEnv } from '@http-forge/playwright';

const env = ForgeEnv.fromEnvironments(
    {
        dev: {
            baseUrl: 'https://dev-api.example.com',
            apiKey: 'dev-key'
        },
        sit: {
            baseUrl: 'https://sit-api.example.com',
            apiKey: 'sit-key'
        },
        prod: {
            baseUrl: 'https://api.example.com',
            apiKey: 'prod-key'
        }
    },
    'dev' // active environment
);

// Switch environments
env.setActiveEnvironment('sit');
env.get('baseUrl'); // 'https://sit-api.example.com'

// List available environments
env.getEnvironments(); // ['dev', 'sit', 'prod']
```

### Using with Generated API Clients

```typescript
import { test } from '@playwright/test';
import { ForgeEnv } from '@http-forge/playwright';
import { loginRequest } from './api-clients/forgerock-login/login-request';

test('login with API client', async ({ request }) => {
    const env = ForgeEnv.create({
        baseUrl: 'https://auth.example.com',
        clientId: 'my-client-id'
    });

    const response = await loginRequest({
        request,
        env,
        query: {
            client_id: '{{clientId}}',
            response_type: 'code'
        }
    });

    expect(response.ok()).toBeTruthy();
});
```

### Importing Shared Types

```typescript
import type { HttpHeaders, BaseRequestContext, BaseApiOptions } from '@http-forge/playwright/shared-types';

// Use HttpHeaders for type-safe header definitions
const headers: HttpHeaders = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer token',
    'Custom-Header': 'value'
};

// Extend BaseRequestContext for custom request contexts
interface MyRequestContext extends BaseRequestContext {
    customField?: string;
}

// Extend BaseApiOptions for custom options
interface MyOptions extends BaseApiOptions {
    retries?: number;
}
```

## API Reference

### ForgeEnv

#### Methods

- **`get(key: string): string | undefined`** - Get a variable value
- **`set(key: string, value: string): void`** - Set a variable value
- **`has(key: string): boolean`** - Check if variable exists
- **`delete(key: string): void`** - Delete a variable
- **`getAll(): Record<string, string>`** - Get all variables
- **`resolve(template: string): string`** - Resolve `{{variable}}` placeholders
- **`resolvePath(url: string, params?: Record<string, string>): string`** - Resolve URL with path params
- **`buildUrl(url: string, options?: { params?, query? }): string`** - Build complete URL
- **`resolveObject<T>(obj: T): T`** - Recursively resolve variables in an object
- **`extractVariables(template: string): string[]`** - Extract variable names from template
- **`extractPathParams(url: string): string[]`** - Extract path parameter names from URL

#### Environment Management

- **`getActiveEnvironment(): string | undefined`** - Get current environment name
- **`setActiveEnvironment(name: string): void`** - Switch to different environment
- **`getEnvironments(): string[]`** - List all available environments
- **`addEnvironment(name: string, vars: Record<string, string>): void`** - Add new environment

#### Static Factory Methods

- **`ForgeEnv.create(variables: Record<string, string>): ForgeEnv`** - Create from simple variables
- **`ForgeEnv.fromEnvironments(envs: Record<string, Record<string, string>>, active?: string): ForgeEnv`** - Create with multiple environments

### Shared Types

#### HttpHeaders

Interface for common HTTP headers with autocomplete support:

```typescript
interface HttpHeaders {
    'Content-Type'?: string;
    'Authorization'?: string;
    'Accept'?: string;
    'Cache-Control'?: string;
    // ... and more
    [key: string]: any; // Allow custom headers
}
```

#### BaseRequestContext

Base interface for request context in generated clients:

```typescript
interface BaseRequestContext {
    request: APIRequestContext; // Playwright request context
    env: IForgeEnv; // Environment instance
    headers?: HttpHeaders; // Optional headers
}
```

#### BaseApiOptions

Common options for all API requests:

```typescript
interface BaseApiOptions {
    maxRedirects?: number; // Default: 20
    timeout?: number; // Request timeout in ms
    failOnStatusCode?: boolean; // Throw on non-2xx status
}
```

## Package Exports

The package provides multiple entry points for tree-shaking:

```typescript
// Main entry - everything
import { ForgeEnv, type IForgeEnv, type HttpHeaders } from '@http-forge/playwright';

// Runtime only - ForgeEnv implementation
import { ForgeEnv, type IForgeEnv } from '@http-forge/playwright/forge-env';

// Types only - shared types
import type { HttpHeaders, BaseRequestContext, BaseApiOptions } from '@http-forge/playwright/shared-types';
```

## Integration with @http-forge/codegen

When using `@http-forge/codegen` to generate API clients, they will automatically import from this package:

```typescript
// Generated file example
import type { IForgeEnv } from '@http-forge/playwright';
import type { HttpHeaders, BaseRequestContext, BaseApiOptions } from '@http-forge/playwright/shared-types';
import type { APIRequestContext, APIResponse } from '@playwright/test';

export interface LoginRequestOptions extends BaseRequestContext, BaseApiOptions {
    query?: LoginRequestQuery;
}

export async function loginRequest(options: LoginRequestOptions): Promise<APIResponse> {
    const { request, env } = options;
    const url = env.buildUrl('https://auth.example.com/login', { query: options.query });
    // ...
}
```

## License

MIT