
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
fluentrest-ts
Advanced tools
A lightweight, fluent TypeScript API testing library inspired by Java's RestAssured. Built on top of Axios, JSONPath, and Joi for powerful request handling and response validation.
A lightweight, fluent TypeScript API testing library inspired by Java's RestAssured. Built on top of Axios, JSONPath, and Joi for powerful request handling and response validation.
npm install fluentrest-ts
import { fluentRest } from "fluentrest-ts";
const response = await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenHeader("Accept", "application/json")
.whenGet("/posts/1");
response
.thenExpectStatus(200)
.thenExpectBody("$.id", 1);
❗️ Note:
thenExpectX
methods require the result of a request (you mustawait
thewhenX()
call).
Method | Description |
---|---|
setBaseUrl(url) | Sets the base URL |
setTimeout(ms) | Overrides timeout |
setLogLevel(level) | Sets log verbosity ("debug" | "info" | "none") |
enableFileLogging(bool) | Enables or disables file-based logging |
givenHeader(key, value) | Adds a request header |
givenQueryParam(key, value) | Adds a query parameter |
givenBody(obj) | Sets JSON request body (Serialized strings or types) / Attaches multipart form-data or files |
debug() | Prints current config to console |
getSnapshot() | Returns snapshot of current request config |
whenGet(url) | Sends a GET request |
whenPost(url) | Sends a POST request |
whenPut(url) | Sends a PUT request |
whenPatch(url) | Sends a PATCH request |
whenDelete(url) | Sends a DELETE request |
whenHead(url) | Sends a HEAD request |
whenOptions(url) | Sends an OPTIONS request |
sendAndExpect(method, url, fn, overrides?) | Sends a request and runs assertions |
> ❗️ Note: `givenBody` method is now unified with multipart form-data.
---
---
## ✅ Response Validator API
After each request, you receive a `ResponseValidator` object with the following methods:
| Method | Description |
|--------|-------------|
| `thenExpectStatus(code)` | Assert HTTP status code |
| `thenExpectBody(path, val)` | Assert JSONPath value |
| `thenExpectBodyContains(fragment)` | Assert body contains key-values |
| `thenValidateBody(schema)` | Joi schema validation |
| `thenExpectHeader(k, v)` | Assert response header |
| `thenExtract(path)` | Extract JSONPath value |
| `catchAndLog(fn)` | Wrap and log assertion failures |
| `getResponse()` | Raw Axios response |
| `getRequestConfig()` | Request config used |
| `wasFailure()` | True if request failed |
| `runAssertions()` | run multiple expectations (assertions) against a response object |
---
## 🧪 Examples by Method
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenBody({ title: "foo", body: "bar", userId: 1 })
.whenPost("/posts")
.thenExpectStatus(201)
.thenExpectBody("$.title", "foo");
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenQueryParam("userId", "1")
.whenGet("/posts")
.thenExpectStatus(200);
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenHeader("Authorization", "Bearer token")
.givenBody({ title: "updated title" })
.whenPut("/posts/1")
.thenExpectStatus(200);
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenBody({ title: "patched" })
.whenPatch("/posts/1")
.thenExpectBodyContains({ title: "patched" });
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenDelete("/posts/1")
.thenExpectStatus(200);
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenHead("/posts/1")
.thenExpectStatus(200);
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenOptions("/posts")
.thenExpectStatus(204);
await fluentRest()
.enableFileLogging(true)
.setLogLevel("debug")
.whenGet("/posts/1")
.thenExpectStatus(200);
Log levels:
"debug"
– log everything"info"
– request + response"none"
– silenceLogs are written to logs/restassured-<pid>.log
by default unless overridden via configureDefaults
.
import { configureDefaults } from "fluentrest-ts";
configureDefaults({
timeout: 15000,
logLevel: "info",
logFilePath: "logs/custom.log",
});
You may also use .env
variables:
RA_TIMEOUT=20000
RA_LOG_LEVEL=debug
RA_LOG_FILE=logs/run.log
RA_BASE_URL=https://jsonplaceholder.typicode.com
Ensure
.env
is loaded before anyfluentrest-ts
import.
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.sendAndExpect("post", "/posts", res => {
res.thenExpectStatus(201).thenExpectBody("$.title", "foo");
}, {
headers: { "Content-Type": "application/json" },
body: { title: "foo", body: "bar", userId: 1 }
});
- Run multiple assertions on a single response.
- Continue executing all checks even if one fails.
- Aggregate failures and throw a combined error.
- Use with `.catchAndLog()` for cleaner test output and logging.
const res = await fluentRest().whenGet('/posts/1');
await res.runAssertions([
r => r.thenExpectStatus(404), // will fail
r => r.thenExpectBody('$.title', 'wrong') // will also fail
]).catchAndLog(err => {
expect(err.message).toContain('Multiple assertion failures');
});
catchAndLog()
Use catchAndLog()
to wrap custom assertions or logic. If it throws, the error will be logged with context.
const response = await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenGet("/posts/1");
response.catchAndLog(() => {
const body = response.thenExtract("$.body");
if (!body || body.length < 10) {
throw new Error("Body is unexpectedly short");
}
});
This is useful for edge-case checks or combining your own logic with the library’s logging system.
const post = await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenBody({ title: "foo", body: "bar", userId: 1 })
.whenPost("/posts");
const id = post.thenExtract("$.id");
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenGet(`/posts/${id}`)
.thenExpectStatus(200);
Use Joi to validate the full response body structure:
import Joi from "joi";
const schema = Joi.object({
id: Joi.number().required(),
title: Joi.string().required(),
body: Joi.string().required(),
userId: Joi.number().required()
});
await fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.whenGet("/posts/1")
.thenValidateBody(schema);
To inspect the request before sending:
fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenBody({ name: "debug" })
.debug();
You can print or retrieve a snapshot of the full request configuration:
const builder = fluentRest()
.setBaseUrl("https://jsonplaceholder.typicode.com")
.givenHeader("X-Debug", "true")
.givenQueryParam("debug", "1");
builder.debug(); // Console output
const snapshot = builder.getSnapshot();
console.log("Snapshot method:", snapshot.method);
This is useful for troubleshooting test cases, comparing requests, or snapshot testing.
Apply a proxy to all requests by default:
configureDefaults({
proxy: {
host: 'proxy.example.com',
port: 8080,
auth: {
username: 'user',
password: 'pass'
}
}
});
Override the global proxy using .setProxy()
:
const response = await fluentRest()
.setProxy({
host: 'custom.proxy.com',
port: 3128,
auth: {
username: 'customUser',
password: 'customPass'
}
})
.whenGet('/posts/1');
Disable proxy even if one is globally configured:
const response = await fluentRest()
.clearProxy()
.whenGet('/health');
setProxy(...)
– per-request overrideconfigureDefaults(...)
– global default.clearProxy()
is usedThe proxy object must match Axios's format:
{
host: string;
port: number;
auth?: {
username: string;
password: string;
};
protocol?: 'http' | 'https';
}
configureDefaults()
– Global config via code.env
support – Set RA_TIMEOUT, RA_LOG_LEVEL, etc.debug()
– Print live config to terminalgetSnapshot()
– Inspect request config objectthenExtract(path)
– Pull specific data from responsecatchAndLog(fn)
– Wrap and log assertion errors with contextPackage | Purpose |
---|---|
Axios | HTTP client |
JSONPath-Plus | JSON extraction from response |
Joi | Schema validation |
Form-Data | Multipart/form-data support |
Chalk | Terminal logging colors |
MIT – Use, extend, and enjoy!
FAQs
A lightweight, fluent TypeScript API testing library inspired by Java's RestAssured. Built on top of Axios, JSONPath, and Joi for powerful request handling and response validation.
We found that fluentrest-ts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.