HTTP Forge Core - API Test Execution Engine
npm install @http-forge/coreLightweight, VS Code-independent HTTP API testing engine - The execution core of HTTP Forge.


@http-forge/core is a standalone, dependency-injection-based HTTP execution engine that powers HTTP Forge. It provides a clean API for:
- 🚀 Executing HTTP requests with full HTTP Forge collection support
- 🔄 Running pre-request and post-response scripts
- 🌍 Managing environments and variables
- 🍪 Automatic cookie handling
- 📊 Test assertions and validations
- 🔌 Extensible via interceptors and custom implementations
Perfect for:
- Building custom API testing tools
- Integrating HTTP Forge into CI/CD pipelines
- Creating CLI tools for API testing
- Headless API testing automation
``bash`
npm install @http-forge/core
Or using the tarball:
`bash`
npm install ./http-forge-core-0.1.0.tgz
`typescript
import { ForgeContainer } from '@http-forge/core';
// Create a container with default settings
const forge = new ForgeContainer();
// Load a collection
const collection = await forge.loadCollection('./my-api.forge.json');
// Execute a request
const result = await forge.execute(collection.items[0], collection);
console.log(result.response.status); // 200
console.log(result.response.body); // Response data
console.log(result.postResponseResult?.assertions); // Test results
`
`typescript
const forge = new ForgeContainer();
// Set environment variables
forge.setEnvironment({
baseUrl: 'https://api.example.com',
apiKey: 'your-api-key',
timeout: '5000'
});
// Variables are automatically interpolated in requests
// URL: {{baseUrl}}/users -> https://api.example.com/users
const result = await forge.execute(request, collection);
`
`typescript`
const forge = new ForgeContainer({
// Use native Node.js http/https instead of fetch
useNativeHttp: true,
// Enable automatic cookie management
enableCookies: true,
// Set request timeout
requestTimeout: 10000,
// Enable request history
enableHistory: true,
maxHistoryEntries: 50,
// Storage format
storageFormat: 'folder' // or 'file'
});
The main entry point - a dependency injection container that wires up all components.
`typescript
const forge = new ForgeContainer(options);
// Load collections
const collection = await forge.loadCollection(path);
const folderCollection = await forge.loadFolderCollection(path);
// Execute requests
const result = await forge.execute(request, collection, options);
// Manage environments
forge.setEnvironment(variables);
forge.setActiveEnvironment(name);
const resolved = forge.getResolvedEnvironment();
// Access services
const executor = forge.getRequestExecutor();
const loader = forge.getCollectionLoader();
`
Execute requests with full control over the execution pipeline:
`typescript
const result = await forge.execute(request, collection, {
environment: 'production',
overrides: {
url: 'https://override.com/api',
headers: { 'X-Custom': 'value' }
},
skipPreRequest: false,
skipPostResponse: false,
timeout: 5000
});
// Access results
console.log(result.response); // HTTP response
console.log(result.preRequestResult); // Pre-request script output
console.log(result.postResponseResult); // Test results
`
Run pre-request and post-response scripts:
Pre-request script:
`javascript
// Set variables before request
forge.env.set('timestamp', Date.now());
forge.env.set('requestId', forge.uuid());
// Modify request
forge.request.headers['X-Request-ID'] = forge.env.get('requestId');
`
Post-response script:
`javascript
// Run tests
forge.expect(forge.response.status).toBe(200);
forge.expect(forge.response.body.success).toBeTruthy();
// Extract data from response
const token = forge.response.body.token;
forge.env.set('authToken', token);
`
`typescript
// Define multiple environments
forge.setEnvironmentConfig({
dev: { baseUrl: 'https://dev.api.com', apiKey: 'dev-key' },
staging: { baseUrl: 'https://staging.api.com', apiKey: 'staging-key' },
prod: { baseUrl: 'https://api.com', apiKey: 'prod-key' }
});
// Switch environments
forge.setActiveEnvironment('prod');
// Get resolved variables (with inheritance and overrides)
const vars = forge.getResolvedEnvironment('prod');
`
Implement your own HTTP client:
`typescript
import { IHttpClient, HttpRequest, HttpResponse } from '@http-forge/core';
class CustomHttpClient implements IHttpClient {
async send(request: HttpRequest): Promise
// Your custom HTTP logic
return {
status: 200,
statusText: 'OK',
headers: {},
body: {},
duration: 100,
size: 1024
};
}
}
const forge = new ForgeContainer({
httpClient: new CustomHttpClient()
});
`
Add custom interceptors to modify requests and responses:
`typescript
import { IRequestInterceptor, IResponseInterceptor } from '@http-forge/core';
// Request interceptor
class AuthInterceptor implements IRequestInterceptor {
async intercept(request: HttpRequest): Promise
request.headers['Authorization'] = Bearer ${getToken()};
return request;
}
}
// Response interceptor
class LoggingInterceptor implements IResponseInterceptor {
async intercept(response: HttpResponse, request: HttpRequest): Promise
console.log(${request.method} ${request.url} -> ${response.status});
return response;
}
}
const forge = new ForgeContainer({
requestInterceptors: [new AuthInterceptor()],
responseInterceptors: [new LoggingInterceptor()]
});
`
Automatic cookie handling across requests:
`typescript
const forge = new ForgeContainer({
enableCookies: true
});
// Cookies are automatically stored and sent
const loginResult = await forge.execute(loginRequest, collection);
// Session cookie from login is automatically included in next request
const dataResult = await forge.execute(dataRequest, collection);
`
Track all executed requests:
`typescript
const forge = new ForgeContainer({
enableHistory: true,
maxHistoryEntries: 100
});
// Execute requests
await forge.execute(request1, collection);
await forge.execute(request2, collection);
// Access history
const history = forge.getRequestHistory();
const entries = history.getAll(); // All requests
const byId = history.getByRequestId(id); // Specific request history
`
Constructor Options:
`typescript`
interface ForgeContainerOptions {
forgeRoot?: string; // Path to http-forge folder
storageFormat?: 'file' | 'folder'; // Collection storage format
// HTTP Settings
useNativeHttp?: boolean; // Use native http/https
httpClient?: IHttpClient; // Custom HTTP client
httpSettings?: RequestSettings; // Default HTTP settings
requestTimeout?: number; // Request timeout (ms)
// Cookie Settings
enableCookies?: boolean; // Enable cookie jar
cookieJar?: ICookieJar; // Custom cookie jar
// Interceptors
requestInterceptors?: IRequestInterceptor[];
responseInterceptors?: IResponseInterceptor[];
errorInterceptors?: IErrorInterceptor[];
// Script Settings
scriptRunner?: IScriptRunner; // Custom script runner
scriptTimeout?: number; // Script timeout (ms)
// History
enableHistory?: boolean; // Enable request history
maxHistoryEntries?: number; // Max history size
}
Methods:
`typescript
// Collection loading
loadCollection(path: string): Promise
loadFolderCollection(path: string): Promise
// Request execution
execute(
request: UnifiedRequest,
collection: UnifiedCollection,
options?: ExecuteOptions
): Promise
// Environment management
setEnvironment(variables: Record
setEnvironmentConfig(config: EnvironmentConfig): void
setActiveEnvironment(name: string): void
getResolvedEnvironment(name?: string): Record
// Service access
getRequestExecutor(): RequestExecutor
getCollectionLoader(): ICollectionLoader
getEnvironmentResolver(): EnvironmentResolver
getRequestHistory(): IRequestHistory
`
`typescript`
interface ExecuteResult {
response: HttpResponse; // HTTP response
preRequestResult?: ScriptResult; // Pre-request script output
postResponseResult?: ScriptResult; // Test results
requestId: string; // Unique request ID
timestamp: number; // Execution timestamp
}
`typescript`
interface HttpResponse {
status: number; // HTTP status code
statusText: string; // Status text
headers: Record
body: any; // Parsed response body
cookies?: Cookie[]; // Response cookies
duration: number; // Request duration (ms)
size: number; // Response size (bytes)
redirected?: boolean; // Whether redirected
}
`typescript
#!/usr/bin/env node
import { ForgeContainer } from '@http-forge/core';
async function runTests(collectionPath: string) {
const forge = new ForgeContainer();
const collection = await forge.loadCollection(collectionPath);
for (const request of collection.items) {
const result = await forge.execute(request, collection);
const tests = result.postResponseResult?.assertions || [];
console.log(\n${request.name}: ${result.response.status}); ${test.passed ? '✓' : '✗'} ${test.name}
tests.forEach(test => {
console.log();
});
}
}
runTests(process.argv[2]);
`
`typescript
import { ForgeContainer } from '@http-forge/core';
async function ciTest() {
const forge = new ForgeContainer({
enableCookies: true,
requestTimeout: 30000
});
forge.setEnvironment({
baseUrl: process.env.API_URL,
apiKey: process.env.API_KEY
});
const collection = await forge.loadCollection('./api-tests.forge.json');
let failedTests = 0;
for (const request of collection.items) {
const result = await forge.execute(request, collection);
const failed = result.postResponseResult?.assertions?.filter(t => !t.passed) || [];
failedTests += failed.length;
}
process.exit(failedTests > 0 ? 1 : 0);
}
`
`typescript
import { ForgeContainer } from '@http-forge/core';
class ApiTestRunner {
private forge: ForgeContainer;
constructor() {
this.forge = new ForgeContainer({
enableCookies: true,
enableHistory: true
});
}
async runSuite(suites: TestSuite[]) {
for (const suite of suites) {
await this.runTests(suite);
}
}
async runTests(suite: TestSuite) {
const collection = await this.forge.loadCollection(suite.collection);
for (const request of collection.items) {
const result = await this.forge.execute(request, collection);
suite.results.push(result);
}
}
}
`
my-api.forge.json
`$3
`
my-api/
collection.json
requests/
login/
request.json
users/
get-users/
request.json
create-user/
request.json
``Contributions are welcome! Please feel free to submit a Pull Request.
MIT © Henry Huang
- HTTP Forge Extension
- GitHub Repository
- Issues
- ✅ Core request execution engine
- ✅ Environment and variable management
- ✅ Pre-request and post-response scripts
- ✅ Cookie jar support
- ✅ Request/response interceptors
- ✅ Request history tracking
- ✅ File and folder collection formats
- ✅ Full TypeScript support
- ✅ Comprehensive test coverage