roster/README.md

193 lines
5.6 KiB
Markdown

# Roster
A modern HTTP client for GNOME, built with GTK 4 and libadwaita.
## Features
- Send HTTP requests (GET, POST, PUT, DELETE)
- Configure custom headers and request bodies
- View response headers and bodies
- Track request history with persistence
- **JavaScript preprocessing and postprocessing scripts**
- **Project environments with variables**
- Beautiful GNOME-native UI
## Dependencies
- GTK 4
- libadwaita 1
- Python 3
- libsoup3 (provided by GNOME Platform)
- gjs (GNOME JavaScript) - for script execution
## Building
```bash
meson setup builddir
meson compile -C builddir
sudo meson install -C builddir
```
## Usage
Roster uses libsoup3 (from GNOME Platform) for making HTTP requests - no external dependencies required.
Run Roster from your application menu or with the `roster` command.
## Scripts
Roster supports JavaScript preprocessing and postprocessing scripts to automate request modifications and response data extraction.
### Preprocessing Scripts
**Run BEFORE the HTTP request is sent.** Use preprocessing to:
- Modify request headers, URL, body, or method
- Add dynamic values (timestamps, request IDs, signatures)
- Read environment variables
- Set/update environment variables
**Available API:**
```javascript
// Request object (modifiable)
request.method // "GET", "POST", "PUT", "DELETE"
request.url // Full URL string
request.headers // Object with header key-value pairs
request.body // Request body string
// Roster API
roster.getVariable(name) // Get variable from selected environment
roster.setVariable(name, value) // Set/update variable
roster.setVariables({key: value}) // Batch set variables
roster.project.name // Current project name
roster.project.environments // Array of environment names
// Console output
console.log(message) // Output shown in preprocessing results
```
**Example 1: Add Dynamic Authentication Header**
```javascript
const token = roster.getVariable('auth_token');
request.headers['Authorization'] = 'Bearer ' + token;
request.headers['X-Request-Time'] = new Date().toISOString();
console.log('Added auth header for token:', token);
```
**Example 2: Modify Request Based on Environment**
```javascript
const env = roster.getVariable('environment_name');
if (env === 'production') {
request.url = request.url.replace('localhost', 'api.example.com');
console.log('Switched to production URL');
}
```
**Example 3: Generate Request Signature**
```javascript
const apiKey = roster.getVariable('api_key');
const timestamp = Date.now().toString();
const requestId = Math.random().toString(36).substring(7);
request.headers['X-API-Key'] = apiKey;
request.headers['X-Timestamp'] = timestamp;
request.headers['X-Request-ID'] = requestId;
// Save for later reference
roster.setVariable('last_request_id', requestId);
console.log('Request ID:', requestId);
```
### Postprocessing Scripts
**Run AFTER receiving the HTTP response.** Use postprocessing to:
- Extract data from response body
- Parse JSON/XML responses
- Store values in environment variables for use in subsequent requests
- Validate response data
**Available API:**
```javascript
// Response object (read-only)
response.body // Response body as string
response.headers // Object with header key-value pairs
response.statusCode // HTTP status code (e.g., 200, 404)
response.statusText // Status text (e.g., "OK", "Not Found")
response.responseTime // Response time in milliseconds
// Roster API
roster.setVariable(name, value) // Set/update variable
roster.setVariables({key: value}) // Batch set variables
// Console output
console.log(message) // Output shown in script results
```
**Example 1: Extract Authentication Token**
```javascript
const data = JSON.parse(response.body);
if (data.access_token) {
roster.setVariable('auth_token', data.access_token);
console.log('Saved auth token');
}
```
**Example 2: Extract Multiple Values**
```javascript
const data = JSON.parse(response.body);
roster.setVariables({
user_id: data.user.id,
user_name: data.user.name,
session_id: data.session.id
});
console.log('Extracted user:', data.user.name);
```
**Example 3: Validate and Store Response**
```javascript
const data = JSON.parse(response.body);
if (response.statusCode === 200 && data.items) {
roster.setVariable('item_count', data.items.length.toString());
if (data.items.length > 0) {
roster.setVariable('first_item_id', data.items[0].id);
}
console.log('Found', data.items.length, 'items');
} else {
console.log('Error: Invalid response');
}
```
### Workflow Example: OAuth Token Flow
**Request 1 (Login) - Postprocessing:**
```javascript
// Extract and store tokens from login response
const data = JSON.parse(response.body);
roster.setVariables({
access_token: data.access_token,
refresh_token: data.refresh_token,
user_id: data.user_id
});
console.log('Logged in as user:', data.user_id);
```
**Request 2 (API Call) - Preprocessing:**
```javascript
// Use stored token in subsequent request
const token = roster.getVariable('access_token');
const userId = roster.getVariable('user_id');
request.headers['Authorization'] = 'Bearer ' + token;
request.url = request.url.replace('{userId}', userId);
console.log('Making authenticated request for user:', userId);
```
### Environment Variables
Variables can be:
- Manually defined in "Manage Environments"
- Automatically created by scripts using `roster.setVariable()`
- Used in requests with `{{variable_name}}` syntax
- Read in preprocessing with `roster.getVariable()`
Variables are scoped to environments within projects, allowing different values for development, staging, and production.