Pre & Post-Request Scripting
Veyak v0.8.0 introduces an advanced scripting subsystem embedded directly into the Rust backend. Scripting allows you to programmatically modify outgoing requests, validate response payloads, extract variables, and chain authentication flows.
🚀 Overview & Runtime
Veyak embeds QuickJS — an ultra-lightweight, high-performance, ES2020-compliant JavaScript engine built directly into the client. Scripts run in an isolated sandbox with zero Node.js or browser overhead.
In addition to JavaScript, Veyak supports scripting hooks in:
- JavaScript (Built-in via QuickJS engine)
- Python (System runtime)
- Go (System toolchain)
- Rust (Cargo toolchain)
🔄 Execution Lifecycle
- Pre-Request Script Execution:
- Executes immediately before URL parsing, header assembly, or socket connection.
- Has access to the outgoing
requestand the collection’s activeenvironment. - Any updates made via
veyak.environment.set()take effect immediately and are substituted into the current request’s{{placeholders}}.
- Network Dispatch:
- Variables are interpolated across all fields (URL, headers, query params, cookies, bodies, auth).
- HTTP/gRPC/WebSocket payload is sent over native OS sockets.
- Post-Request Script Execution:
- Executes immediately upon receiving the response headers and body.
- Has access to
request,response, andenvironment. - Runs test assertions and persists new variables back to the collection environment.
🧰 The veyak Global API
All scripts have access to the veyak namespace:
1. veyak.environment
Manage collection-scoped environment variables dynamically:
// Retrieve a variable from the active collection environment
const baseUrl = veyak.environment.get("BASE_URL");
// Set or update a variable (persisted to SQLite immediately)
veyak.environment.set("ACCESS_TOKEN", "eyJhbGciOi...");
2. veyak.request
Inspect or mutate outgoing request data in pre-request scripts:
// Access request properties
console.log(veyak.request.method); // "GET", "POST", etc.
console.log(veyak.request.url); // Raw URL before or during interpolation
// Add or override a custom header dynamically
veyak.request.headers["X-Request-Timestamp"] = Date.now().toString();
3. veyak.response (Post-Request Only)
Inspect the received response attributes:
// Status code and status text
console.log(veyak.response.status); // 200
console.log(veyak.response.statusText); // "OK"
// Latency and payload size
console.log(veyak.response.timeMs); // e.g. 42
console.log(veyak.response.sizeBytes); // e.g. 1024
// Response headers (case-insensitive object)
console.log(veyak.response.headers["content-type"]);
// Raw response body as string
const rawText = veyak.response.body;
// Parsed JSON helper (throws if invalid JSON)
const json = veyak.response.json();
4. veyak.test(name, assertionFn)
Define test assertions for automated contract validation:
veyak.test("Status code is 200 OK", () => {
if (veyak.response.status !== 200) {
throw new Error(`Expected 200, got ${veyak.response.status}`);
}
});
veyak.test("Response contains user ID", () => {
const data = veyak.response.json();
if (!data.id || typeof data.id !== "number") {
throw new Error("Missing or invalid user id in response");
}
});
5. console.log(...)
Standard logging statements are captured and streamed directly to the Console tab in the Response Panel for debugging.
💡 Practical Examples
Example 1: Token Chaining (Login -> Authorized Requests)
Step 1: In your POST /api/auth/login request, add this Post-request Script:
veyak.test("Login successful", () => {
if (veyak.response.status !== 200) {
throw new Error("Login failed with status " + veyak.response.status);
}
});
const payload = veyak.response.json();
if (payload.token) {
veyak.environment.set("BEARER_TOKEN", payload.token);
console.log("Token updated for subsequent calls.");
}
Step 2: In your protected endpoints (e.g., GET /api/user/profile), set your Bearer Auth token to {{BEARER_TOKEN}}. The new token is automatically used on the next run!
Example 2: Dynamic HMAC Request Signing
In your Pre-request Script:
// Generate request timestamp and nonce
const timestamp = Math.floor(Date.now() / 1000).toString();
const nonce = Math.random().toString(36).substring(2, 15);
veyak.environment.set("REQ_TIMESTAMP", timestamp);
veyak.environment.set("REQ_NONCE", nonce);
console.log(`Prepared request headers with timestamp ${timestamp}`);
🖥️ Viewing Test Results & Logs
When a request executes with scripts:
- Scripts Sub-tab: View and edit the pre- and post-request code snippets.
- Console Sub-tab: Real-time stdout output and log traces captured during script evaluation.
- Tests Sub-tab: Visual summary of passing (
✓) and failing (✕) test assertions, including error messages and stack traces. - Environment Updates Indicator: Displays any variables modified and saved back to your collection database.