Rewrite and condense documentation, fix factual errors
Condense most pages to concise reference format. Add Import.md. Fix: history file is history.json not session.json, import uses URL input not file picker, getVariable() returns null not undefined.
parent
f92677d207
commit
f034dc5a9e
611
API-Reference.md
611
API-Reference.md
@ -1,575 +1,86 @@
|
|||||||
# API Reference
|
# API Reference
|
||||||
|
|
||||||
Complete JavaScript API reference for Roster preprocessing and postprocessing scripts.
|
JavaScript API available in Roster [[Scripts]].
|
||||||
|
|
||||||
## Overview
|
**Language:** JavaScript (ES5+) via GJS
|
||||||
|
**Execution:** Synchronous, sandboxed
|
||||||
|
|
||||||
Roster provides a JavaScript API accessible from [[Scripts]] for automating request modifications and response processing.
|
## Request Object (preprocessing only)
|
||||||
|
|
||||||
**Language:** JavaScript (ES5+)
|
| Property | Type | Description |
|
||||||
**Runtime:** GJS (GNOME JavaScript)
|
|----------|------|-------------|
|
||||||
**Context:** Sandboxed, synchronous execution
|
| `request.method` | string | `"GET"`, `"POST"`, `"PUT"`, `"DELETE"` |
|
||||||
|
| `request.url` | string | Full URL |
|
||||||
|
| `request.headers` | object | Header key-value pairs |
|
||||||
|
| `request.body` | string | Request body |
|
||||||
|
|
||||||
## Global Objects
|
All properties are writable.
|
||||||
|
|
||||||
### Preprocessing Script Context
|
## Response Object (postprocessing only)
|
||||||
|
|
||||||
Available in preprocessing scripts only:
|
| Property | Type | Description |
|
||||||
|
|----------|------|-------------|
|
||||||
|
| `response.body` | string | Response body |
|
||||||
|
| `response.headers` | object | Header key-value pairs |
|
||||||
|
| `response.statusCode` | number | HTTP status code |
|
||||||
|
| `response.statusText` | string | Status text (`"OK"`, ...) |
|
||||||
|
| `response.responseTime` | number | Response time in ms |
|
||||||
|
|
||||||
```javascript
|
All properties are read-only.
|
||||||
request // Modifiable request object
|
|
||||||
roster // Roster API (with getVariable)
|
|
||||||
console // Console output
|
|
||||||
```
|
|
||||||
|
|
||||||
### Postprocessing Script Context
|
## Roster API (both contexts)
|
||||||
|
|
||||||
Available in postprocessing scripts only:
|
| Method | Available in | Description |
|
||||||
|
|--------|-------------|-------------|
|
||||||
|
| `roster.getVariable(name)` | preprocessing | Returns string or `null` |
|
||||||
|
| `roster.setVariable(name, value)` | both | Creates or updates variable |
|
||||||
|
| `roster.setVariables({...})` | both | Batch set |
|
||||||
|
| `roster.project.name` | preprocessing | Current project name |
|
||||||
|
| `roster.project.environments` | preprocessing | Array of environment names |
|
||||||
|
|
||||||
```javascript
|
Variable names must match `/^\w+$/` (alphanumeric + underscore). Values are always strings. Sensitive variables are automatically routed to/from GNOME Keyring.
|
||||||
response // Read-only response object
|
|
||||||
roster // Roster API (without getVariable)
|
|
||||||
console // Console output
|
|
||||||
```
|
|
||||||
|
|
||||||
## Request Object
|
## Console
|
||||||
|
|
||||||
**Available in:** Preprocessing scripts only
|
`console.log(...)` and `console.error(...)` — output appears in the Preprocessing/Postprocessing results tab.
|
||||||
**Type:** Mutable
|
|
||||||
|
|
||||||
### Properties
|
## Available Built-ins
|
||||||
|
|
||||||
#### `request.method`
|
Standard JS built-ins: `Date`, `JSON`, `Math`, `String`, `Array`, `Object`, etc.
|
||||||
|
|
||||||
**Type:** `string`
|
No `fetch`, `setTimeout`, `require`, or file system access.
|
||||||
**Values:** `"GET"`, `"POST"`, `"PUT"`, `"DELETE"`
|
|
||||||
**Description:** HTTP method for the request
|
|
||||||
|
|
||||||
**Example:**
|
## Type Notes
|
||||||
```javascript
|
|
||||||
// Change method from GET to POST
|
|
||||||
request.method = "POST";
|
|
||||||
console.log('Method changed to:', request.method);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `request.url`
|
Variables are always strings. Convert when needed:
|
||||||
|
|
||||||
**Type:** `string`
|
|
||||||
**Description:** Complete URL for the request
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Add query parameter
|
|
||||||
request.url = request.url + '?timestamp=' + Date.now();
|
|
||||||
|
|
||||||
// Replace placeholder
|
|
||||||
const userId = roster.getVariable('user_id');
|
|
||||||
request.url = request.url.replace('{userId}', userId);
|
|
||||||
|
|
||||||
// Change domain
|
|
||||||
request.url = request.url.replace('localhost', 'api.example.com');
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `request.headers`
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
**Description:** HTTP headers as key-value pairs
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Add header
|
|
||||||
request.headers['Authorization'] = 'Bearer ' + token;
|
|
||||||
|
|
||||||
// Modify existing header
|
|
||||||
request.headers['Content-Type'] = 'application/json';
|
|
||||||
|
|
||||||
// Delete header
|
|
||||||
delete request.headers['X-Old-Header'];
|
|
||||||
|
|
||||||
// Read header
|
|
||||||
const contentType = request.headers['Content-Type'];
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `request.body`
|
|
||||||
|
|
||||||
**Type:** `string`
|
|
||||||
**Description:** Request body content
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Set body
|
|
||||||
request.body = JSON.stringify({ name: "John", age: 30 });
|
|
||||||
|
|
||||||
// Modify existing body
|
|
||||||
const data = JSON.parse(request.body);
|
|
||||||
data.timestamp = new Date().toISOString();
|
|
||||||
request.body = JSON.stringify(data);
|
|
||||||
|
|
||||||
// Clear body
|
|
||||||
request.body = "";
|
|
||||||
```
|
|
||||||
|
|
||||||
## Response Object
|
|
||||||
|
|
||||||
**Available in:** Postprocessing scripts only
|
|
||||||
**Type:** Immutable (read-only)
|
|
||||||
|
|
||||||
### Properties
|
|
||||||
|
|
||||||
#### `response.body`
|
|
||||||
|
|
||||||
**Type:** `string`
|
|
||||||
**Description:** Response body content
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Parse JSON response
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
console.log('User name:', data.name);
|
|
||||||
|
|
||||||
// Check if response contains text
|
|
||||||
if (response.body.includes('error')) {
|
|
||||||
console.error('Response contains error');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get response length
|
|
||||||
console.log('Response size:', response.body.length, 'bytes');
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `response.headers`
|
|
||||||
|
|
||||||
**Type:** `object`
|
|
||||||
**Description:** Response headers as key-value pairs (read-only)
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Read header
|
|
||||||
const contentType = response.headers['Content-Type'];
|
|
||||||
console.log('Content type:', contentType);
|
|
||||||
|
|
||||||
// Check if header exists
|
|
||||||
if (response.headers['X-Rate-Limit-Remaining']) {
|
|
||||||
const remaining = response.headers['X-Rate-Limit-Remaining'];
|
|
||||||
console.log('Rate limit remaining:', remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List all headers
|
|
||||||
for (const key in response.headers) {
|
|
||||||
console.log(key + ':', response.headers[key]);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `response.statusCode`
|
|
||||||
|
|
||||||
**Type:** `number`
|
|
||||||
**Description:** HTTP status code (200, 404, 500, etc.)
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Check if successful
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
console.log('Success!');
|
|
||||||
} else if (response.statusCode >= 400 && response.statusCode < 500) {
|
|
||||||
console.error('Client error:', response.statusCode);
|
|
||||||
} else if (response.statusCode >= 500) {
|
|
||||||
console.error('Server error:', response.statusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle specific status codes
|
|
||||||
switch (response.statusCode) {
|
|
||||||
case 200:
|
|
||||||
console.log('OK');
|
|
||||||
break;
|
|
||||||
case 201:
|
|
||||||
console.log('Created');
|
|
||||||
break;
|
|
||||||
case 401:
|
|
||||||
console.error('Unauthorized');
|
|
||||||
break;
|
|
||||||
case 404:
|
|
||||||
console.error('Not found');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.log('Status:', response.statusCode);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `response.statusText`
|
|
||||||
|
|
||||||
**Type:** `string`
|
|
||||||
**Description:** HTTP status text ("OK", "Not Found", etc.)
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
console.log('Response:', response.statusCode, response.statusText);
|
|
||||||
// Output: "Response: 200 OK"
|
|
||||||
|
|
||||||
if (response.statusText === "OK") {
|
|
||||||
// Process successful response
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `response.responseTime`
|
|
||||||
|
|
||||||
**Type:** `number`
|
|
||||||
**Description:** Response time in milliseconds
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
console.log('Response took', response.responseTime, 'ms');
|
|
||||||
|
|
||||||
if (response.responseTime > 1000) {
|
|
||||||
console.warn('Slow response:', response.responseTime, 'ms');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store for monitoring
|
|
||||||
roster.setVariable('last_response_time', response.responseTime.toString());
|
|
||||||
```
|
|
||||||
|
|
||||||
## Roster API
|
|
||||||
|
|
||||||
**Available in:** Both preprocessing and postprocessing scripts
|
|
||||||
**Namespace:** `roster`
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
#### `roster.getVariable(name)`
|
|
||||||
|
|
||||||
**Available in:** Preprocessing scripts only
|
|
||||||
**Returns:** `string` or `undefined`
|
|
||||||
**Description:** Get variable value from selected environment
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
- `name` (string): Variable name
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Get variable
|
|
||||||
const apiKey = roster.getVariable('api_key');
|
|
||||||
if (apiKey) {
|
|
||||||
request.headers['X-API-Key'] = apiKey;
|
|
||||||
} else {
|
|
||||||
console.error('API key not defined');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get with default value
|
|
||||||
const timeout = roster.getVariable('timeout') || '30';
|
|
||||||
console.log('Using timeout:', timeout);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- Returns `undefined` if variable doesn't exist
|
|
||||||
- Gets value from selected environment
|
|
||||||
- Sensitive variables are automatically decrypted
|
|
||||||
|
|
||||||
#### `roster.setVariable(name, value)`
|
|
||||||
|
|
||||||
**Available in:** Both preprocessing and postprocessing scripts
|
|
||||||
**Returns:** `undefined`
|
|
||||||
**Description:** Set or update variable in selected environment
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
- `name` (string): Variable name (must match `/^\w+$/`)
|
|
||||||
- `value` (string): Variable value
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Set variable
|
|
||||||
roster.setVariable('user_id', '12345');
|
|
||||||
console.log('Saved user ID');
|
|
||||||
|
|
||||||
// Update existing variable
|
|
||||||
const token = data.access_token;
|
|
||||||
roster.setVariable('auth_token', token);
|
|
||||||
|
|
||||||
// Create new variable (auto-created if doesn't exist)
|
|
||||||
roster.setVariable('session_id', generateSessionId());
|
|
||||||
```
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- Creates variable if it doesn't exist
|
|
||||||
- Updates value in selected environment
|
|
||||||
- Variable name must be alphanumeric + underscore
|
|
||||||
- Sensitive variables automatically routed to keyring
|
|
||||||
- Value converted to string
|
|
||||||
|
|
||||||
#### `roster.setVariables(object)`
|
|
||||||
|
|
||||||
**Available in:** Both preprocessing and postprocessing scripts
|
|
||||||
**Returns:** `undefined`
|
|
||||||
**Description:** Set or update multiple variables at once (batch operation)
|
|
||||||
|
|
||||||
**Parameters:**
|
|
||||||
- `object` (object): Key-value pairs of variable names and values
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
// Set multiple variables
|
|
||||||
roster.setVariables({
|
|
||||||
user_id: data.user.id,
|
|
||||||
user_name: data.user.name,
|
|
||||||
user_email: data.user.email,
|
|
||||||
session_id: data.session_id
|
|
||||||
});
|
|
||||||
|
|
||||||
// Extract response data
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
roster.setVariables({
|
|
||||||
access_token: data.access_token,
|
|
||||||
refresh_token: data.refresh_token,
|
|
||||||
expires_at: data.expires_at
|
|
||||||
});
|
|
||||||
console.log('Saved authentication tokens');
|
|
||||||
```
|
|
||||||
|
|
||||||
**Notes:**
|
|
||||||
- More efficient than multiple `setVariable()` calls
|
|
||||||
- Same validation rules as `setVariable()`
|
|
||||||
|
|
||||||
### Properties
|
|
||||||
|
|
||||||
#### `roster.project.name`
|
|
||||||
|
|
||||||
**Available in:** Preprocessing scripts only
|
|
||||||
**Type:** `string`
|
|
||||||
**Description:** Current project name
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
const projectName = roster.project.name;
|
|
||||||
console.log('Project:', projectName);
|
|
||||||
|
|
||||||
// Add project name to request
|
|
||||||
request.headers['X-Project'] = projectName;
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `roster.project.environments`
|
|
||||||
|
|
||||||
**Available in:** Preprocessing scripts only
|
|
||||||
**Type:** `string[]` (array of strings)
|
|
||||||
**Description:** Array of environment names in current project
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
const envs = roster.project.environments;
|
|
||||||
console.log('Available environments:', envs.join(', '));
|
|
||||||
// Output: "Available environments: Production, Staging, Development"
|
|
||||||
|
|
||||||
// Check if environment exists
|
|
||||||
if (envs.includes('Production')) {
|
|
||||||
console.log('Production environment available');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log count
|
|
||||||
console.log('Environment count:', envs.length);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Console API
|
|
||||||
|
|
||||||
**Available in:** Both preprocessing and postprocessing scripts
|
|
||||||
**Namespace:** `console`
|
|
||||||
|
|
||||||
### Methods
|
|
||||||
|
|
||||||
#### `console.log(...args)`
|
|
||||||
|
|
||||||
**Returns:** `undefined`
|
|
||||||
**Description:** Print message to script output
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
console.log('Simple message');
|
|
||||||
console.log('User ID:', userId);
|
|
||||||
console.log('Request sent to', request.url);
|
|
||||||
console.log('Response status:', response.statusCode, response.statusText);
|
|
||||||
|
|
||||||
// Multiple arguments
|
|
||||||
const name = 'John';
|
|
||||||
const age = 30;
|
|
||||||
console.log('User:', name, 'Age:', age);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Output location:**
|
|
||||||
- Preprocessing: "Preprocessing" tab in request panel
|
|
||||||
- Postprocessing: "Postprocessing" tab in request panel
|
|
||||||
|
|
||||||
#### `console.error(...args)`
|
|
||||||
|
|
||||||
**Returns:** `undefined`
|
|
||||||
**Description:** Print error message to script output
|
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```javascript
|
|
||||||
if (response.statusCode !== 200) {
|
|
||||||
console.error('Request failed with status:', response.statusCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.access_token) {
|
|
||||||
console.error('No access token in response');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('JSON parse error:', e.message);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Visual difference:**
|
|
||||||
- May be styled differently than `console.log()` in output
|
|
||||||
- Indicates errors or warnings
|
|
||||||
|
|
||||||
## Built-in JavaScript Objects
|
|
||||||
|
|
||||||
Standard JavaScript objects available in GJS:
|
|
||||||
|
|
||||||
### Date
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Current timestamp
|
|
||||||
const now = new Date();
|
|
||||||
console.log('Current time:', now.toISOString());
|
|
||||||
|
|
||||||
// Unix timestamp
|
|
||||||
const timestamp = Date.now();
|
|
||||||
console.log('Timestamp:', timestamp);
|
|
||||||
|
|
||||||
// Date arithmetic
|
|
||||||
const expiresAt = new Date(Date.now() + 3600000); // +1 hour
|
|
||||||
roster.setVariable('token_expires', expiresAt.toISOString());
|
|
||||||
```
|
|
||||||
|
|
||||||
### JSON
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Parse JSON
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
console.log('Parsed data:', data.name);
|
|
||||||
|
|
||||||
// Stringify JSON
|
|
||||||
const body = { name: "John", age: 30 };
|
|
||||||
request.body = JSON.stringify(body);
|
|
||||||
|
|
||||||
// Pretty print
|
|
||||||
request.body = JSON.stringify(body, null, 2);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Math
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Random number
|
|
||||||
const requestId = Math.floor(Math.random() * 1000000);
|
|
||||||
roster.setVariable('request_id', requestId.toString());
|
|
||||||
|
|
||||||
// Rounding
|
|
||||||
const responseTimeSeconds = Math.round(response.responseTime / 1000);
|
|
||||||
console.log('Response time:', responseTimeSeconds, 'seconds');
|
|
||||||
```
|
|
||||||
|
|
||||||
### String
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// String manipulation
|
|
||||||
const url = request.url.replace('http://', 'https://');
|
|
||||||
const uppercase = data.name.toUpperCase();
|
|
||||||
const trimmed = data.description.trim();
|
|
||||||
|
|
||||||
// String methods
|
|
||||||
if (response.body.includes('error')) {
|
|
||||||
console.error('Response contains error');
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = request.url.split('/');
|
|
||||||
const lastPart = parts[parts.length - 1];
|
|
||||||
```
|
|
||||||
|
|
||||||
### Array
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Array methods
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
const itemIds = data.items.map(item => item.id);
|
|
||||||
console.log('Item IDs:', itemIds.join(', '));
|
|
||||||
|
|
||||||
// Filter
|
|
||||||
const active = data.items.filter(item => item.active);
|
|
||||||
console.log('Active items:', active.length);
|
|
||||||
|
|
||||||
// Find
|
|
||||||
const firstItem = data.items.find(item => item.id === '123');
|
|
||||||
if (firstItem) {
|
|
||||||
console.log('Found item:', firstItem.name);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Object
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Object methods
|
|
||||||
const headers = Object.keys(response.headers);
|
|
||||||
console.log('Header count:', headers.length);
|
|
||||||
|
|
||||||
// Merge objects
|
|
||||||
const defaults = { timeout: 30, retries: 3 };
|
|
||||||
const config = Object.assign({}, defaults, userConfig);
|
|
||||||
|
|
||||||
// Check property
|
|
||||||
if (data.hasOwnProperty('access_token')) {
|
|
||||||
roster.setVariable('auth_token', data.access_token);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
Scripts should handle errors gracefully:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Try-catch for parsing
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
roster.setVariable('user_id', data.user.id);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to parse JSON:', e.message);
|
|
||||||
console.error('Response body:', response.body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check before accessing
|
|
||||||
if (data && data.user && data.user.id) {
|
|
||||||
roster.setVariable('user_id', data.user.id);
|
|
||||||
} else {
|
|
||||||
console.error('Invalid response structure');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate response status
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
// Process data
|
|
||||||
} else {
|
|
||||||
console.error('Request failed:', response.statusCode);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
Scripts run in a sandboxed, synchronous environment:
|
|
||||||
- No async operations (setTimeout, Promises, async/await)
|
|
||||||
- No external libraries or npm packages
|
|
||||||
- No file system or shell access
|
|
||||||
- No network requests (use Roster's request system)
|
|
||||||
- Only built-in JavaScript objects available
|
|
||||||
|
|
||||||
## Type Reference
|
|
||||||
|
|
||||||
**Variable names** must match `/^\w+$/` (alphanumeric + underscore only).
|
|
||||||
|
|
||||||
**Variables are always strings**. Convert numbers and booleans when setting/getting:
|
|
||||||
```javascript
|
```javascript
|
||||||
roster.setVariable('count', data.count.toString());
|
roster.setVariable('count', data.count.toString());
|
||||||
const count = parseInt(roster.getVariable('count'), 10);
|
const count = parseInt(roster.getVariable('count'), 10);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Next Steps
|
## Examples
|
||||||
|
|
||||||
- [[Scripts]] - Practical examples and workflows
|
### Authentication flow
|
||||||
- [[Variables]] - Learn about environment variables
|
|
||||||
- [[Sensitive-Variables]] - Secure credential storage
|
**POST /auth/login — postprocessing:**
|
||||||
|
```javascript
|
||||||
|
const data = JSON.parse(response.body);
|
||||||
|
roster.setVariables({
|
||||||
|
access_token: data.access_token,
|
||||||
|
refresh_token: data.refresh_token,
|
||||||
|
user_id: data.user_id
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**Authenticated request — preprocessing:**
|
||||||
|
```javascript
|
||||||
|
const token = roster.getVariable('access_token');
|
||||||
|
request.headers['Authorization'] = 'Bearer ' + token;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dynamic headers
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
request.headers['X-Request-ID'] = Math.random().toString(36).slice(2);
|
||||||
|
request.headers['X-Timestamp'] = new Date().toISOString();
|
||||||
|
```
|
||||||
|
|||||||
@ -89,14 +89,14 @@ Postprocessing Script → Display Response → Save to History
|
|||||||
```
|
```
|
||||||
~/.local/share/cz.bugsy.roster/
|
~/.local/share/cz.bugsy.roster/
|
||||||
├── requests.json # Projects, environments, regular variables
|
├── requests.json # Projects, environments, regular variables
|
||||||
└── session.json # History, window state
|
└── history.json # Request history
|
||||||
```
|
```
|
||||||
|
|
||||||
**Flatpak:**
|
**Flatpak:**
|
||||||
```
|
```
|
||||||
~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/
|
~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/
|
||||||
├── requests.json
|
├── requests.json
|
||||||
└── session.json
|
└── history.json
|
||||||
```
|
```
|
||||||
|
|
||||||
### Data Format
|
### Data Format
|
||||||
@ -104,18 +104,23 @@ Postprocessing Script → Display Response → Save to History
|
|||||||
**requests.json:**
|
**requests.json:**
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
|
"version": 1,
|
||||||
"projects": [
|
"projects": [
|
||||||
{
|
{
|
||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"name": "Project Name",
|
"name": "Project Name",
|
||||||
"icon": "icon-name",
|
"icon": "icon-name",
|
||||||
|
"created_at": "2025-01-01T00:00:00+00:00",
|
||||||
|
"variable_names": ["base_url", "api_key"],
|
||||||
|
"sensitive_variables": ["api_key"],
|
||||||
"environments": [
|
"environments": [
|
||||||
{
|
{
|
||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"name": "Production",
|
"name": "Production",
|
||||||
|
"created_at": "2025-01-01T00:00:00+00:00",
|
||||||
"variables": {
|
"variables": {
|
||||||
"base_url": "https://api.example.com",
|
"base_url": "https://api.example.com",
|
||||||
"api_key": "" // Empty if sensitive
|
"api_key": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -123,12 +128,19 @@ Postprocessing Script → Display Response → Save to History
|
|||||||
{
|
{
|
||||||
"id": "uuid",
|
"id": "uuid",
|
||||||
"name": "Get Users",
|
"name": "Get Users",
|
||||||
"method": "GET",
|
"created_at": "2025-01-01T00:00:00+00:00",
|
||||||
"url": "{{base_url}}/users",
|
"modified_at": "2025-01-01T00:00:00+00:00",
|
||||||
"headers": {},
|
"request": {
|
||||||
"body": "",
|
"method": "GET",
|
||||||
"preprocessing_script": "",
|
"url": "{{base_url}}/users",
|
||||||
"postprocessing_script": ""
|
"headers": {},
|
||||||
|
"body": "",
|
||||||
|
"syntax": "RAW"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"preprocessing": "",
|
||||||
|
"postprocessing": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -136,6 +148,8 @@ Postprocessing Script → Display Response → Save to History
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note: sensitive variable values are stored in GNOME Keyring (empty string in JSON is a placeholder).
|
||||||
|
|
||||||
### Sensitive Variables
|
### Sensitive Variables
|
||||||
|
|
||||||
Stored in GNOME Keyring with schema:
|
Stored in GNOME Keyring with schema:
|
||||||
|
|||||||
147
Export.md
147
Export.md
@ -1,12 +1,8 @@
|
|||||||
# Export
|
# Export
|
||||||
|
|
||||||
Roster can export requests to other formats for use with command-line tools or other HTTP clients.
|
Click the **Export** button (toolbar) to copy the current request as a cURL command to clipboard.
|
||||||
|
|
||||||
## Supported Formats
|
Variables are substituted with values from the selected environment before export.
|
||||||
|
|
||||||
### cURL
|
|
||||||
|
|
||||||
Export requests as cURL commands for use in terminal or scripts.
|
|
||||||
|
|
||||||
**Example output:**
|
**Example output:**
|
||||||
```bash
|
```bash
|
||||||
@ -16,141 +12,4 @@ curl -X POST 'https://api.example.com/users' \
|
|||||||
-d '{"name":"John","email":"john@example.com"}'
|
-d '{"name":"John","email":"john@example.com"}'
|
||||||
```
|
```
|
||||||
|
|
||||||
### Other Formats
|
Sensitive variable values are included in plain text — review before sharing.
|
||||||
|
|
||||||
Additional export formats (HTTPie, wget, etc.) may be added in future releases.
|
|
||||||
|
|
||||||
## How to Export
|
|
||||||
|
|
||||||
### Export Current Request
|
|
||||||
|
|
||||||
1. Configure your request in the request editor
|
|
||||||
2. Click the **Export** button in the toolbar
|
|
||||||
3. Select export format (e.g., "cURL")
|
|
||||||
4. Exported command is copied to clipboard
|
|
||||||
|
|
||||||
### Export from History
|
|
||||||
|
|
||||||
1. Open a request from [[History]]
|
|
||||||
2. Click the **Export** button
|
|
||||||
3. Select format
|
|
||||||
4. Command copied to clipboard
|
|
||||||
|
|
||||||
### Export Saved Requests
|
|
||||||
|
|
||||||
1. Open a saved request from project
|
|
||||||
2. Click the **Export** button
|
|
||||||
3. Select format
|
|
||||||
4. Command copied to clipboard
|
|
||||||
|
|
||||||
## Variable Substitution
|
|
||||||
|
|
||||||
When exporting requests that contain variables:
|
|
||||||
|
|
||||||
**Variables are substituted with current environment values:**
|
|
||||||
- `{{base_url}}` replaced with actual URL
|
|
||||||
- `{{api_key}}` replaced with actual key value
|
|
||||||
- All `{{variable}}` placeholders resolved
|
|
||||||
|
|
||||||
The exported command contains the final values, not the placeholder syntax.
|
|
||||||
|
|
||||||
### Sensitive Variables
|
|
||||||
|
|
||||||
[[Sensitive-Variables]] are exported with their actual decrypted values. Be careful when sharing exported commands containing sensitive data.
|
|
||||||
|
|
||||||
**Security note:** Exported cURL commands may contain:
|
|
||||||
- API keys in headers
|
|
||||||
- Passwords in request body
|
|
||||||
- Tokens in authorization headers
|
|
||||||
|
|
||||||
Review exported commands before sharing.
|
|
||||||
|
|
||||||
## Using Exported Commands
|
|
||||||
|
|
||||||
### cURL
|
|
||||||
|
|
||||||
Paste the exported cURL command in your terminal:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X GET 'https://api.example.com/users' \
|
|
||||||
-H 'Authorization: Bearer token123'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Scripts
|
|
||||||
|
|
||||||
Use exported commands in shell scripts:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/bin/bash
|
|
||||||
# exported_request.sh
|
|
||||||
|
|
||||||
curl -X POST 'https://api.example.com/users' \
|
|
||||||
-H 'Content-Type: application/json' \
|
|
||||||
-d '{"name":"John"}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
Include exported commands in API documentation or tutorials.
|
|
||||||
|
|
||||||
## Export Features
|
|
||||||
|
|
||||||
### Headers
|
|
||||||
|
|
||||||
All request headers are included in export:
|
|
||||||
- Custom headers
|
|
||||||
- Content-Type
|
|
||||||
- Authorization
|
|
||||||
- User-Agent
|
|
||||||
- etc.
|
|
||||||
|
|
||||||
### Request Body
|
|
||||||
|
|
||||||
Request body is included with appropriate flags:
|
|
||||||
- `-d` for POST data
|
|
||||||
- Properly escaped JSON
|
|
||||||
- Multiline bodies formatted correctly
|
|
||||||
|
|
||||||
### Method
|
|
||||||
|
|
||||||
HTTP method included with `-X` flag:
|
|
||||||
- `-X GET`
|
|
||||||
- `-X POST`
|
|
||||||
- `-X PUT`
|
|
||||||
- `-X DELETE`
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
- Only cURL format currently supported
|
|
||||||
- No batch export of multiple requests
|
|
||||||
- Exported to clipboard only (no file export)
|
|
||||||
- Scripts (preprocessing/postprocessing) are not exported
|
|
||||||
|
|
||||||
## Tips
|
|
||||||
|
|
||||||
**Test exported commands:**
|
|
||||||
Always test exported cURL commands in a safe environment before using in production.
|
|
||||||
|
|
||||||
**Redact sensitive data:**
|
|
||||||
Remove or replace sensitive values before sharing exported commands:
|
|
||||||
```bash
|
|
||||||
# Original export
|
|
||||||
curl -H 'Authorization: Bearer abc123xyz'
|
|
||||||
|
|
||||||
# Redacted for sharing
|
|
||||||
curl -H 'Authorization: Bearer YOUR_TOKEN_HERE'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Save to file:**
|
|
||||||
Redirect clipboard content to file:
|
|
||||||
```bash
|
|
||||||
# Paste from clipboard and save
|
|
||||||
pbpaste > request.sh # macOS
|
|
||||||
xclip -o > request.sh # Linux with xclip
|
|
||||||
```
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Getting-Started]] - Learn to create requests
|
|
||||||
- [[Variables]] - Use variables in requests
|
|
||||||
- [[History]] - Review past requests
|
|
||||||
|
|||||||
249
FAQ.md
249
FAQ.md
@ -2,243 +2,66 @@
|
|||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
### What is Roster?
|
**What is Roster?**
|
||||||
|
A native GNOME HTTP client for testing APIs, built with GTK 4 and libadwaita.
|
||||||
|
|
||||||
Roster is a native GNOME HTTP client for testing and debugging APIs. It provides a clean interface for sending HTTP requests, viewing responses, and automating workflows.
|
**What platforms does it support?**
|
||||||
|
Linux with GNOME 40+. Not available for Windows or macOS.
|
||||||
|
|
||||||
### Is Roster free?
|
**Is it free?**
|
||||||
|
Yes, GPL-3.0-or-later.
|
||||||
Yes! Roster is free and open-source software licensed under GPL-3.0-or-later.
|
|
||||||
|
|
||||||
### What platforms does Roster support?
|
|
||||||
|
|
||||||
Roster is designed for the GNOME desktop environment on Linux. It works on any Linux distribution with GNOME 40+.
|
|
||||||
|
|
||||||
### Can I use Roster on Windows or macOS?
|
|
||||||
|
|
||||||
Roster is specifically built for GNOME/Linux and is not currently available for Windows or macOS.
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### How do I install Roster?
|
**How do I install Roster?**
|
||||||
|
From Flathub (recommended): `flatpak install flathub cz.bugsy.roster`
|
||||||
|
Or see [[Installation]] to build from source.
|
||||||
|
|
||||||
See [[Installation]] for complete instructions. You can:
|
**Is Roster on Flathub?**
|
||||||
- Build from source
|
Yes. Install with `flatpak install flathub cz.bugsy.roster` or find it in GNOME Software.
|
||||||
- Install via Flatpak
|
|
||||||
- Use GNOME Builder
|
|
||||||
|
|
||||||
### Will Roster be on Flathub?
|
## Variables
|
||||||
|
|
||||||
Support for Flathub is planned for future releases.
|
**What's the difference between regular and sensitive variables?**
|
||||||
|
Regular variables are stored in plain-text JSON. Sensitive variables are encrypted in GNOME Keyring. Use sensitive variables for API keys, tokens, and passwords — see [[Sensitive-Variables]].
|
||||||
|
|
||||||
### What dependencies does Roster need?
|
**Can I use variables in the request body?**
|
||||||
|
Yes — `{{variable_name}}` works in URL, headers, and body.
|
||||||
|
|
||||||
GTK 4, libadwaita 1, Python 3, libsoup3, libsecret, and GJS. See [[Installation]] for details.
|
**Can variables be shared between projects?**
|
||||||
|
No, variables are scoped to their project.
|
||||||
## Variables and Environments
|
|
||||||
|
|
||||||
### What's the difference between regular and sensitive variables?
|
|
||||||
|
|
||||||
**Regular variables** are stored in plain text JSON files. Use for non-sensitive data like URLs.
|
|
||||||
|
|
||||||
**Sensitive variables** are encrypted and stored in GNOME Keyring. Use for API keys, passwords, and tokens.
|
|
||||||
|
|
||||||
See [[Sensitive-Variables]] for details.
|
|
||||||
|
|
||||||
### Can I use variables in the request body?
|
|
||||||
|
|
||||||
Yes! Use `{{variable_name}}` syntax in:
|
|
||||||
- URL
|
|
||||||
- Headers
|
|
||||||
- Request body
|
|
||||||
|
|
||||||
### How do I switch between environments?
|
|
||||||
|
|
||||||
Use the environment dropdown at the top of the request panel. Switching environments updates all variable values.
|
|
||||||
|
|
||||||
### Can variables from one project be used in another?
|
|
||||||
|
|
||||||
No. Variables are scoped to projects and cannot be shared between projects.
|
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
### Is it safe to store API keys in Roster?
|
**Is it safe to store API keys?**
|
||||||
|
Yes, if you mark them as sensitive (lock icon). Regular variables are plain text.
|
||||||
|
|
||||||
**If you use sensitive variables: Yes.**
|
**Where are secrets stored?**
|
||||||
|
In GNOME Keyring (`~/.local/share/keyrings/`), same as browser passwords and WiFi credentials. Visible in Seahorse under "Login" keyring.
|
||||||
Mark variables as sensitive (click the lock icon), and values are encrypted in GNOME Keyring.
|
|
||||||
|
|
||||||
**If you use regular variables: No.**
|
|
||||||
|
|
||||||
Regular variables are stored in plain text. Always mark secrets as sensitive!
|
|
||||||
|
|
||||||
### Where are my secrets stored?
|
|
||||||
|
|
||||||
Sensitive variables are encrypted in GNOME Keyring (`~/.local/share/keyrings/`) using your login password. Same security as browser passwords and WiFi credentials.
|
|
||||||
|
|
||||||
### Can I view my keyring secrets?
|
|
||||||
|
|
||||||
Yes! Open "Passwords and Keys" application (Seahorse), navigate to "Login" keyring, and look for entries starting with "Roster:".
|
|
||||||
|
|
||||||
### What happens if I forget to mark a variable as sensitive?
|
|
||||||
|
|
||||||
You can click the lock icon at any time to mark it as sensitive. Values will be moved from JSON to keyring automatically.
|
|
||||||
|
|
||||||
## Scripts
|
## Scripts
|
||||||
|
|
||||||
### What language do scripts use?
|
**What language?**
|
||||||
|
JavaScript (ES5+) via GJS.
|
||||||
|
|
||||||
JavaScript (ES5+), executed via GJS (GNOME JavaScript runtime).
|
**Can I use npm packages / async / file system?**
|
||||||
|
No — scripts are sandboxed and synchronous. See [[Scripts]] for full limitations.
|
||||||
### Can I use npm packages in scripts?
|
|
||||||
|
|
||||||
No. Scripts run in a sandboxed environment without access to external libraries or npm packages.
|
|
||||||
|
|
||||||
### Can scripts access the file system?
|
|
||||||
|
|
||||||
No. Scripts cannot read/write files, execute shell commands, or access system resources.
|
|
||||||
|
|
||||||
### Why can't I use async/await?
|
|
||||||
|
|
||||||
Scripts execute synchronously. No async operations (setTimeout, Promises, async/await, fetch) are available.
|
|
||||||
|
|
||||||
### Can I make HTTP requests from scripts?
|
|
||||||
|
|
||||||
No. Use Roster's request system and chain requests using variables instead.
|
|
||||||
|
|
||||||
See [[Scripts]] for complete documentation.
|
|
||||||
|
|
||||||
## Requests and Responses
|
|
||||||
|
|
||||||
### Where is request history stored?
|
|
||||||
|
|
||||||
**Native:** `~/.local/share/cz.bugsy.roster/session.json`
|
|
||||||
**Flatpak:** `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json`
|
|
||||||
|
|
||||||
### How long is history kept?
|
|
||||||
|
|
||||||
History persists across sessions until you clear it manually.
|
|
||||||
|
|
||||||
### Can I export requests?
|
|
||||||
|
|
||||||
Yes! Click the export button and choose a format:
|
|
||||||
- cURL
|
|
||||||
- More formats may be added in future versions
|
|
||||||
|
|
||||||
### Does Roster support file uploads?
|
|
||||||
|
|
||||||
Multipart form uploads are not currently supported. Planned for future releases.
|
|
||||||
|
|
||||||
### Can I test WebSocket connections?
|
|
||||||
|
|
||||||
WebSocket support is not currently available.
|
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### Roster won't start
|
**Roster won't start**
|
||||||
|
Check dependencies: `pkg-config --modversion gtk4 libadwaita-1`
|
||||||
|
|
||||||
**Check dependencies:**
|
**Keyring not accessible**
|
||||||
```bash
|
Ensure GNOME Keyring is unlocked. For Flatpak, verify `--talk-name=org.freedesktop.secrets` permission.
|
||||||
# Verify GTK 4 and libadwaita are installed
|
|
||||||
pkg-config --modversion gtk4 libadwaita-1
|
|
||||||
```
|
|
||||||
|
|
||||||
**Check logs:**
|
**Variables not substituting**
|
||||||
```bash
|
Check: environment is selected, variable name matches exactly (case-sensitive), syntax is `{{name}}`.
|
||||||
# Native
|
|
||||||
roster
|
|
||||||
|
|
||||||
# Flatpak
|
**How do I reset Roster?**
|
||||||
flatpak run cz.bugsy.roster
|
Delete `~/.local/share/cz.bugsy.roster/` (native) or `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/` (Flatpak). Keyring entries must be removed separately via Seahorse.
|
||||||
```
|
|
||||||
|
|
||||||
### Cannot access GNOME Keyring
|
|
||||||
|
|
||||||
**Ensure keyring is unlocked:**
|
|
||||||
1. Open "Passwords and Keys" (Seahorse)
|
|
||||||
2. Right-click "Login" keyring
|
|
||||||
3. Select "Unlock"
|
|
||||||
|
|
||||||
**For Flatpak, check permissions:**
|
|
||||||
```bash
|
|
||||||
flatpak info --show-permissions cz.bugsy.roster
|
|
||||||
# Should include: --talk-name=org.freedesktop.secrets
|
|
||||||
```
|
|
||||||
|
|
||||||
### Variables not substituting
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
1. Environment is selected (dropdown at top of request)
|
|
||||||
2. Variable names match exactly (case-sensitive)
|
|
||||||
3. Syntax is correct: `{{variable_name}}`
|
|
||||||
4. Variable is defined in selected environment
|
|
||||||
|
|
||||||
### Scripts not executing
|
|
||||||
|
|
||||||
**Check:**
|
|
||||||
1. Script has no syntax errors
|
|
||||||
2. Check script output panels for errors
|
|
||||||
3. GJS (gjs package) is installed
|
|
||||||
|
|
||||||
### Request failing with SSL errors
|
|
||||||
|
|
||||||
**For self-signed certificates:**
|
|
||||||
|
|
||||||
Roster uses system SSL certificates. Add your certificate to the system trust store or use development environments without SSL validation.
|
|
||||||
|
|
||||||
## Data and Privacy
|
|
||||||
|
|
||||||
### Does Roster collect any data?
|
|
||||||
|
|
||||||
No. Roster does not collect, transmit, or share any data. All information stays on your local machine.
|
|
||||||
|
|
||||||
### Can I backup my projects?
|
|
||||||
|
|
||||||
Yes! Backup these files:
|
|
||||||
- `~/.local/share/cz.bugsy.roster/requests.json` (projects and variables)
|
|
||||||
- `~/.local/share/keyrings/` (sensitive variables)
|
|
||||||
|
|
||||||
### How do I reset Roster?
|
|
||||||
|
|
||||||
Delete the data directory:
|
|
||||||
```bash
|
|
||||||
# Native
|
|
||||||
rm -rf ~/.local/share/cz.bugsy.roster/
|
|
||||||
|
|
||||||
# Flatpak
|
|
||||||
rm -rf ~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/
|
|
||||||
```
|
|
||||||
|
|
||||||
**Warning:** This deletes all projects, requests, and history!
|
|
||||||
|
|
||||||
Sensitive variables in keyring must be deleted separately via Seahorse.
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
### How can I contribute?
|
Report bugs and request features: https://git.bugsy.cz/beval/roster/issues
|
||||||
|
See [[Contributing]] for contribution guidelines.
|
||||||
Contributions welcome! See [[Contributing]] for guidelines.
|
|
||||||
|
|
||||||
### Where do I report bugs?
|
|
||||||
|
|
||||||
Report issues at: https://git.bugsy.cz/beval/roster/issues
|
|
||||||
|
|
||||||
### Can I request features?
|
|
||||||
|
|
||||||
Yes! Open an issue with the "enhancement" label.
|
|
||||||
|
|
||||||
## Comparison
|
|
||||||
|
|
||||||
### How is Roster different from Postman/Insomnia?
|
|
||||||
|
|
||||||
Roster is a lightweight, native GNOME application focused on simplicity. Unlike Postman/Insomnia (Electron-based with cloud features), Roster is Linux-only with no cloud dependencies.
|
|
||||||
|
|
||||||
### How is Roster different from HTTPie?
|
|
||||||
|
|
||||||
Roster provides a GUI with project management, while HTTPie is a command-line tool.
|
|
||||||
|
|
||||||
## Still Have Questions?
|
|
||||||
|
|
||||||
- Check the [[Home|Wiki]] for more documentation
|
|
||||||
- Open an issue: https://git.bugsy.cz/beval/roster/issues
|
|
||||||
- Read the source: https://git.bugsy.cz/beval/roster
|
|
||||||
|
|||||||
@ -1,156 +1,35 @@
|
|||||||
# Getting Started
|
# Getting Started
|
||||||
|
|
||||||
This guide walks you through sending your first HTTP request with Roster.
|
After [[Installation]], launch Roster from the application menu or run `roster` (Flatpak: `flatpak run cz.bugsy.roster`).
|
||||||
|
|
||||||
## Launch Roster
|
## Sending a Request
|
||||||
|
|
||||||
After [[Installation]], launch Roster from:
|
1. The app opens with a new request tab
|
||||||
- Your application menu (search for "Roster")
|
2. Set the URL (e.g. `https://api.github.com/users/octocat`) and method (`GET`)
|
||||||
- Command line: `roster` (or `flatpak run cz.bugsy.roster` for Flatpak)
|
3. Optionally add headers in the **Headers** tab
|
||||||
|
4. Press **Ctrl+Return** (or click **Send**)
|
||||||
|
5. The response appears in the right panel — status, headers, body with syntax highlighting
|
||||||
|
|
||||||
## Your First Request
|
## Saving a Request
|
||||||
|
|
||||||
### Step 1: Configure the Request
|
Click **Save** (or **Ctrl+S**), enter a name, and select a project. Unsaved changes show a dot (•) on the tab label.
|
||||||
|
|
||||||
Roster starts with a new request tab.
|
## History
|
||||||
|
|
||||||
**Set the URL:**
|
Every sent request is automatically saved to history (bottom panel). Click any entry to open it in a new tab.
|
||||||
```
|
|
||||||
https://api.github.com/users/octocat
|
|
||||||
```
|
|
||||||
|
|
||||||
**Set the Method:**
|
## Tabs
|
||||||
- Use the dropdown menu (default is `GET`)
|
|
||||||
|
|
||||||
**Add Headers (Optional):**
|
| Action | Shortcut |
|
||||||
1. Click the **"Headers"** tab
|
|--------|----------|
|
||||||
2. Add a header:
|
| New tab | **Ctrl+T** |
|
||||||
- Key: `User-Agent`
|
| Close tab | **Ctrl+W** |
|
||||||
- Value: `Roster/0.6.0`
|
| Switch tabs | **Ctrl+Tab** / **Ctrl+Shift+Tab** |
|
||||||
|
|
||||||
### Step 2: Send the Request
|
|
||||||
|
|
||||||
Click the **"Send"** button (or press **Ctrl+Return**)
|
|
||||||
|
|
||||||
### Step 3: View the Response
|
|
||||||
|
|
||||||
The response appears in the right panel:
|
|
||||||
|
|
||||||
**Status Line:**
|
|
||||||
```
|
|
||||||
200 OK 123 ms 1.2 KB
|
|
||||||
```
|
|
||||||
|
|
||||||
**Response Headers:**
|
|
||||||
Click the **"Headers"** tab to view all response headers.
|
|
||||||
|
|
||||||
**Response Body:**
|
|
||||||
The JSON response from GitHub API showing user information.
|
|
||||||
|
|
||||||
## Saving Requests
|
|
||||||
|
|
||||||
### Save for Later
|
|
||||||
|
|
||||||
1. Click the **"Save"** button in the header
|
|
||||||
2. Select project
|
|
||||||
2. Enter a name: `Get GitHub User`
|
|
||||||
3. Click **"Save"**
|
|
||||||
|
|
||||||
The request is now saved to your project.
|
|
||||||
|
|
||||||
### Access Saved Requests
|
|
||||||
|
|
||||||
1. Click the project
|
|
||||||
2. Your project shows saved requests
|
|
||||||
3. Click a request to open it in a new tab
|
|
||||||
|
|
||||||
## Request History
|
|
||||||
|
|
||||||
Every request you send is automatically saved to history.
|
|
||||||
|
|
||||||
**View History:**
|
|
||||||
1. Navigate to bottom history panel
|
|
||||||
2. Browse past requests
|
|
||||||
3. Click any entry to open it in a new tab
|
|
||||||
|
|
||||||
## Working with Tabs
|
|
||||||
|
|
||||||
### Multiple Tabs
|
|
||||||
|
|
||||||
Open multiple requests simultaneously:
|
|
||||||
- **Ctrl+T** - New request tab
|
|
||||||
- **Ctrl+W** - Close current tab
|
|
||||||
- **Ctrl+Tab** / **Ctrl+Shift+Tab** - Switch between tabs
|
|
||||||
|
|
||||||
### Modified Indicator
|
|
||||||
|
|
||||||
Unsaved changes are marked with a dot (•) on the tab label.
|
|
||||||
|
|
||||||
## Common Request Types
|
|
||||||
|
|
||||||
### GET Request
|
|
||||||
```
|
|
||||||
Method: GET
|
|
||||||
URL: https://api.example.com/users
|
|
||||||
Headers: (optional)
|
|
||||||
Body: (none)
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST Request
|
|
||||||
```
|
|
||||||
Method: POST
|
|
||||||
URL: https://api.example.com/users
|
|
||||||
Headers: Content-Type: application/json
|
|
||||||
Body: {"name": "John", "email": "john@example.com"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### PUT Request
|
|
||||||
```
|
|
||||||
Method: PUT
|
|
||||||
URL: https://api.example.com/users/123
|
|
||||||
Headers: Content-Type: application/json
|
|
||||||
Body: {"name": "John Updated"}
|
|
||||||
```
|
|
||||||
|
|
||||||
### DELETE Request
|
|
||||||
```
|
|
||||||
Method: DELETE
|
|
||||||
URL: https://api.example.com/users/123
|
|
||||||
Headers: (optional)
|
|
||||||
Body: (none)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Response Features
|
|
||||||
|
|
||||||
### Syntax Highlighting
|
|
||||||
|
|
||||||
Roster automatically detects and highlights JSON, XML, and HTML responses.
|
|
||||||
|
|
||||||
### Response Metrics
|
|
||||||
|
|
||||||
The status line shows status code, response time, and total size including headers:
|
|
||||||
```
|
|
||||||
200 OK 123 ms 5.4 KB
|
|
||||||
```
|
|
||||||
|
|
||||||
## Keyboard Shortcuts
|
|
||||||
|
|
||||||
Essential shortcuts to speed up your workflow:
|
|
||||||
|
|
||||||
See [[Keyboard-Shortcuts]] for the complete list.
|
|
||||||
|
|
||||||
## Next Steps
|
## Next Steps
|
||||||
|
|
||||||
Now that you know the basics, explore more advanced features:
|
- [[Projects-and-Environments]] — organize requests
|
||||||
|
- [[Variables]] — avoid repeating URLs and headers
|
||||||
- [[Projects-and-Environments]] - Organize requests and manage environments
|
- [[Sensitive-Variables]] — store API keys securely
|
||||||
- [[Variables]] - Use variables to avoid repetition
|
- [[Scripts]] — automate with JavaScript
|
||||||
- [[Sensitive-Variables]] - Store API keys securely
|
- [[Import]] — import from OpenAPI/Swagger or WSDL
|
||||||
- [[Scripts]] - Automate workflows with JavaScript
|
|
||||||
- [[Export]] - Export requests to cURL and other formats
|
|
||||||
|
|
||||||
## Tips
|
|
||||||
|
|
||||||
- Use `httpbin.org` endpoints for testing (e.g., `https://httpbin.org/get`)
|
|
||||||
- Save frequently used requests with descriptive names
|
|
||||||
- Check history panel to review and compare past responses
|
|
||||||
|
|||||||
122
History.md
122
History.md
@ -1,124 +1,22 @@
|
|||||||
# History
|
# History
|
||||||
|
|
||||||
Roster automatically saves every HTTP request you send to history, allowing you to review and replay past requests.
|
Every request you send is automatically saved to history and persists across sessions.
|
||||||
|
|
||||||
## What is History?
|
## Accessing History
|
||||||
|
|
||||||
History captures complete request and response data for every request sent:
|
History appears in the **bottom panel** of the main window. Each entry shows method, URL, status code, timestamp, and response time, sorted newest first.
|
||||||
- Request method, URL, headers, body
|
|
||||||
- Response status, headers, body, timing
|
|
||||||
- Timestamp of when request was sent
|
|
||||||
- Environment used (if applicable)
|
|
||||||
|
|
||||||
History persists across sessions and survives application restarts.
|
Click any entry to open it in a new tab — you can modify and resend it.
|
||||||
|
|
||||||
## Viewing History
|
## Storage
|
||||||
|
|
||||||
### Access History Panel
|
- Native: `~/.local/share/cz.bugsy.roster/history.json`
|
||||||
|
- Flatpak: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/history.json`
|
||||||
History appears in the bottom panel of the main window.
|
|
||||||
|
|
||||||
### History Entries
|
|
||||||
|
|
||||||
Each entry shows:
|
|
||||||
- Request method and URL
|
|
||||||
- Response status code
|
|
||||||
- Timestamp (relative or absolute)
|
|
||||||
- Response time
|
|
||||||
|
|
||||||
Entries are sorted by timestamp (most recent first).
|
|
||||||
|
|
||||||
### Open from History
|
|
||||||
|
|
||||||
Click any history entry to open it in a new tab with:
|
|
||||||
- Complete request details
|
|
||||||
- Full response
|
|
||||||
- All headers
|
|
||||||
|
|
||||||
This creates a new editable request tab - you can modify and resend.
|
|
||||||
|
|
||||||
## Replaying Requests
|
|
||||||
|
|
||||||
To replay a request from history:
|
|
||||||
|
|
||||||
1. Click the history entry
|
|
||||||
2. Request opens in new tab with original configuration
|
|
||||||
3. Click **"Send"** to execute again
|
|
||||||
|
|
||||||
The replayed request:
|
|
||||||
- Uses current environment variables (not original values)
|
|
||||||
- Can be modified before sending
|
|
||||||
- Creates a new history entry when sent
|
|
||||||
|
|
||||||
## Using History
|
|
||||||
|
|
||||||
### Compare Responses
|
|
||||||
|
|
||||||
Open multiple history entries in tabs to compare responses across time or different environments.
|
|
||||||
|
|
||||||
### Debug Issues
|
|
||||||
|
|
||||||
Review past requests to:
|
|
||||||
- See what was actually sent
|
|
||||||
- Check response timing trends
|
|
||||||
- Verify header values
|
|
||||||
- Examine error responses
|
|
||||||
|
|
||||||
### Create New Requests
|
|
||||||
|
|
||||||
Use history entries as templates:
|
|
||||||
1. Open history entry
|
|
||||||
2. Modify URL, headers, or body
|
|
||||||
3. Save as new request
|
|
||||||
|
|
||||||
## History Storage
|
|
||||||
|
|
||||||
**Native:**
|
|
||||||
```
|
|
||||||
~/.local/share/cz.bugsy.roster/session.json
|
|
||||||
```
|
|
||||||
|
|
||||||
**Flatpak:**
|
|
||||||
```
|
|
||||||
~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json
|
|
||||||
```
|
|
||||||
|
|
||||||
History is stored in JSON format with full request/response data.
|
|
||||||
|
|
||||||
## Clearing History
|
## Clearing History
|
||||||
|
|
||||||
Currently, history can be cleared by deleting the `session.json` file:
|
No built-in UI — delete `history.json` and restart the app.
|
||||||
|
|
||||||
```bash
|
## Privacy
|
||||||
# Native
|
|
||||||
rm ~/.local/share/cz.bugsy.roster/session.json
|
|
||||||
|
|
||||||
# Flatpak
|
History contains full request and response data in plaintext, including headers and bodies. Clear it periodically if requests contain sensitive data.
|
||||||
rm ~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Then restart Roster.
|
|
||||||
|
|
||||||
## Privacy Note
|
|
||||||
|
|
||||||
History contains complete request and response data, including:
|
|
||||||
- URLs and query parameters
|
|
||||||
- Request/response headers
|
|
||||||
- Request/response bodies
|
|
||||||
|
|
||||||
If requests contain sensitive data:
|
|
||||||
- Use [[Sensitive-Variables]] for credentials
|
|
||||||
- Be aware history file contains plaintext data
|
|
||||||
- Clear history periodically if needed
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
- History is stored locally only (no cloud sync)
|
|
||||||
- No built-in UI to clear history (must delete file manually)
|
|
||||||
- No search/filter functionality (planned for future releases)
|
|
||||||
- No export functionality for history entries
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Getting-Started]] - Learn to send requests
|
|
||||||
- [[Export]] - Export requests to other tools
|
|
||||||
|
|||||||
2
Home.md
2
Home.md
@ -11,6 +11,7 @@ Roster is a native GNOME application for testing and debugging HTTP APIs with su
|
|||||||
- Secure credential storage using GNOME Keyring
|
- Secure credential storage using GNOME Keyring
|
||||||
- JavaScript preprocessing and postprocessing scripts
|
- JavaScript preprocessing and postprocessing scripts
|
||||||
- Request history and export to cURL
|
- Request history and export to cURL
|
||||||
|
- Import from OpenAPI/Swagger (2.0 + 3.x) and WSDL
|
||||||
|
|
||||||
## Quick Links
|
## Quick Links
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ Roster is a native GNOME application for testing and debugging HTTP APIs with su
|
|||||||
- [[Scripts]] - Preprocessing and postprocessing automation
|
- [[Scripts]] - Preprocessing and postprocessing automation
|
||||||
- [[Export]] - Export requests to other tools
|
- [[Export]] - Export requests to other tools
|
||||||
- [[History]] - Track and replay requests
|
- [[History]] - Track and replay requests
|
||||||
|
- [[Import]] - Import from OpenAPI/Swagger and WSDL
|
||||||
|
|
||||||
### Reference
|
### Reference
|
||||||
- [[API-Reference]] - Complete JavaScript API documentation
|
- [[API-Reference]] - Complete JavaScript API documentation
|
||||||
|
|||||||
62
Import.md
Normal file
62
Import.md
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# Import
|
||||||
|
|
||||||
|
Roster can import API definitions from OpenAPI/Swagger and WSDL endpoints, automatically creating saved requests for all discovered operations.
|
||||||
|
|
||||||
|
## Supported Formats
|
||||||
|
|
||||||
|
### OpenAPI / Swagger
|
||||||
|
|
||||||
|
- **OpenAPI 2.0** (Swagger) — JSON or YAML
|
||||||
|
- **OpenAPI 3.x** — JSON or YAML
|
||||||
|
|
||||||
|
Imports all defined API operations as separate saved requests, including:
|
||||||
|
- HTTP method and path
|
||||||
|
- Base URL from `host`/`servers` field
|
||||||
|
- Request headers (`Content-Type`, `Accept`)
|
||||||
|
- JSON body template generated from the request schema
|
||||||
|
|
||||||
|
### WSDL (Web Services Description Language)
|
||||||
|
|
||||||
|
- **WSDL 1.1**
|
||||||
|
- **WSDL 2.0**
|
||||||
|
|
||||||
|
Imports all defined operations as SOAP requests, including:
|
||||||
|
- Endpoint URL from the WSDL binding
|
||||||
|
- `Content-Type: text/xml` header
|
||||||
|
- XML body template generated from the input message schema
|
||||||
|
|
||||||
|
## How to Import
|
||||||
|
|
||||||
|
### OpenAPI / Swagger
|
||||||
|
|
||||||
|
1. Click the **Import** button (papyrus icon) in the sidebar toolbar
|
||||||
|
2. Select **"Import from OpenAPI / Swagger"**
|
||||||
|
3. Enter the **Spec URL** of the OpenAPI/Swagger definition (must start with `http://` or `https://`)
|
||||||
|
4. Click **Fetch** — Roster downloads and parses the spec
|
||||||
|
5. Select the operations you want to import (or select all)
|
||||||
|
6. Choose or create a **project** to import into
|
||||||
|
7. Click **"Import"**
|
||||||
|
|
||||||
|
### WSDL
|
||||||
|
|
||||||
|
1. Click the **Import** button (papyrus icon) in the sidebar toolbar
|
||||||
|
2. Select **"Import from WSDL"**
|
||||||
|
3. Enter the **WSDL URL** of the service description (WSDL 1.1 or 2.0)
|
||||||
|
4. Click **Fetch WSDL** — Roster downloads and parses the service description
|
||||||
|
5. Select the operations you want to import (or select all)
|
||||||
|
6. Choose or create a **project** to import into
|
||||||
|
7. Click **"Import"**
|
||||||
|
|
||||||
|
The imported requests are saved to the selected project and ready to send.
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Imported requests use placeholder values from the schema (e.g., empty strings for required fields). Fill in actual values before sending.
|
||||||
|
- Variable substitution works in imported requests — add `{{variable_name}}` to the URL or body after importing.
|
||||||
|
- For OpenAPI imports with `{{server}}` or similar base URL variables, set up an environment with the actual server URL.
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
- [[Projects-and-Environments]] - Organize imported requests into projects
|
||||||
|
- [[Variables]] - Add environment variables to imported requests
|
||||||
|
- [[Getting-Started]] - Learn how to send requests
|
||||||
173
Installation.md
173
Installation.md
@ -1,34 +1,19 @@
|
|||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
This guide covers how to build and install Roster from source.
|
## Flathub (recommended)
|
||||||
|
|
||||||
## Dependencies
|
```bash
|
||||||
|
flatpak install flathub cz.bugsy.roster
|
||||||
|
```
|
||||||
|
|
||||||
Roster requires the following dependencies:
|
Or search for "Roster" in GNOME Software.
|
||||||
|
|
||||||
### Runtime Dependencies
|
## Build from Source
|
||||||
- **GTK 4** (>= 4.0)
|
|
||||||
- **libadwaita 1** (>= 1.0)
|
|
||||||
- **Python 3** (>= 3.8)
|
|
||||||
- **libsoup3** - HTTP client library (provided by GNOME Platform)
|
|
||||||
- **libsecret** - Secure credential storage (provided by GNOME Platform)
|
|
||||||
- **GJS** - GNOME JavaScript runtime for script execution
|
|
||||||
|
|
||||||
### Build Dependencies
|
**Dependencies:**
|
||||||
- **Meson** (>= 1.0.0)
|
|
||||||
- **Ninja**
|
|
||||||
- **pkg-config**
|
|
||||||
- **gettext** - For internationalization
|
|
||||||
- **glib-compile-schemas**
|
|
||||||
- **glib-compile-resources**
|
|
||||||
|
|
||||||
## Installation Methods
|
- Meson >= 1.0, Ninja, pkg-config, gettext
|
||||||
|
- GTK 4, libadwaita 1, libsoup3, libsecret, GJS, PyGObject
|
||||||
### Method 1: Build from Source (Native)
|
|
||||||
|
|
||||||
This method builds and installs Roster directly on your system.
|
|
||||||
|
|
||||||
#### Step 1: Install Dependencies
|
|
||||||
|
|
||||||
**Fedora:**
|
**Fedora:**
|
||||||
```bash
|
```bash
|
||||||
@ -40,152 +25,44 @@ sudo dnf install meson ninja-build gtk4-devel libadwaita-devel libsoup3-devel li
|
|||||||
sudo apt install meson ninja-build libgtk-4-dev libadwaita-1-dev libsoup-3.0-dev libsecret-1-dev gjs python3 gettext desktop-file-utils appstream
|
sudo apt install meson ninja-build libgtk-4-dev libadwaita-1-dev libsoup-3.0-dev libsecret-1-dev gjs python3 gettext desktop-file-utils appstream
|
||||||
```
|
```
|
||||||
|
|
||||||
**Arch Linux:**
|
**Arch:**
|
||||||
```bash
|
```bash
|
||||||
sudo pacman -S meson ninja gtk4 libadwaita libsoup3 libsecret gjs python3 gettext
|
sudo pacman -S meson ninja gtk4 libadwaita libsoup3 libsecret gjs python gettext
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 2: Clone Repository
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://git.bugsy.cz/beval/roster.git
|
git clone https://git.bugsy.cz/beval/roster.git
|
||||||
cd roster
|
cd roster
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 3: Build
|
|
||||||
|
|
||||||
```bash
|
|
||||||
meson setup builddir
|
meson setup builddir
|
||||||
meson compile -C builddir
|
meson compile -C builddir
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 4: Install
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo meson install -C builddir
|
sudo meson install -C builddir
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 5: Run
|
## Build Flatpak Locally
|
||||||
|
|
||||||
```bash
|
|
||||||
roster
|
|
||||||
```
|
|
||||||
|
|
||||||
Or launch from your application menu.
|
|
||||||
|
|
||||||
### Method 2: Build with Flatpak (Recommended)
|
|
||||||
|
|
||||||
Flatpak provides a sandboxed environment with all dependencies included.
|
|
||||||
|
|
||||||
#### Step 1: Install Flatpak Builder
|
|
||||||
|
|
||||||
**Fedora:**
|
|
||||||
```bash
|
|
||||||
sudo dnf install flatpak-builder
|
|
||||||
```
|
|
||||||
|
|
||||||
**Ubuntu/Debian:**
|
|
||||||
```bash
|
|
||||||
sudo apt install flatpak-builder
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 2: Add Flathub Remote
|
|
||||||
|
|
||||||
```bash
|
|
||||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 3: Install GNOME SDK
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
flatpak install flathub org.gnome.Platform//49 org.gnome.Sdk//49
|
flatpak install flathub org.gnome.Platform//49 org.gnome.Sdk//49
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 4: Build Flatpak
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://git.bugsy.cz/beval/roster.git
|
|
||||||
cd roster
|
|
||||||
flatpak-builder --user --install --force-clean build-dir cz.bugsy.roster.json
|
flatpak-builder --user --install --force-clean build-dir cz.bugsy.roster.json
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 5: Run
|
|
||||||
|
|
||||||
```bash
|
|
||||||
flatpak run cz.bugsy.roster
|
flatpak run cz.bugsy.roster
|
||||||
```
|
```
|
||||||
|
|
||||||
### Method 3: GNOME Builder (For Development)
|
## GNOME Builder
|
||||||
|
|
||||||
GNOME Builder provides an integrated development environment.
|
Clone `https://git.bugsy.cz/beval/roster.git` in GNOME Builder and hit Run.
|
||||||
|
|
||||||
#### Step 1: Install GNOME Builder
|
|
||||||
|
|
||||||
```bash
|
|
||||||
flatpak install flathub org.gnome.Builder
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Step 2: Open Project
|
|
||||||
|
|
||||||
1. Launch GNOME Builder
|
|
||||||
2. Click "Clone Repository"
|
|
||||||
3. Enter: `https://git.bugsy.cz/beval/roster.git`
|
|
||||||
4. Click "Clone"
|
|
||||||
|
|
||||||
#### Step 3: Build and Run
|
|
||||||
|
|
||||||
1. Click the "Build" button (hammer icon)
|
|
||||||
2. Click the "Run" button (play icon)
|
|
||||||
|
|
||||||
## Uninstallation
|
|
||||||
|
|
||||||
### Native Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd roster/builddir
|
|
||||||
sudo ninja uninstall
|
|
||||||
```
|
|
||||||
|
|
||||||
### Flatpak Installation
|
|
||||||
|
|
||||||
```bash
|
|
||||||
flatpak uninstall cz.bugsy.roster
|
|
||||||
```
|
|
||||||
|
|
||||||
## File Locations
|
## File Locations
|
||||||
|
|
||||||
### Native Installation
|
| | Native | Flatpak |
|
||||||
|
|---|---|---|
|
||||||
|
| Data | `~/.local/share/cz.bugsy.roster/` | `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/` |
|
||||||
|
| Sensitive vars | GNOME Keyring | GNOME Keyring |
|
||||||
|
|
||||||
- **Binary**: `/usr/local/bin/roster` (or `/usr/bin/roster`)
|
## Uninstall
|
||||||
- **Application data**: `~/.local/share/cz.bugsy.roster/`
|
|
||||||
- **Requests/Projects**: `~/.local/share/cz.bugsy.roster/requests.json`
|
|
||||||
- **Session state**: `~/.local/share/cz.bugsy.roster/session.json`
|
|
||||||
- **Sensitive variables**: GNOME Keyring (encrypted)
|
|
||||||
|
|
||||||
### Flatpak Installation
|
```bash
|
||||||
|
# Source build
|
||||||
|
sudo ninja -C builddir uninstall
|
||||||
|
|
||||||
- **Binary**: Managed by Flatpak
|
# Flatpak
|
||||||
- **Application data**: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/`
|
flatpak uninstall cz.bugsy.roster
|
||||||
- **Requests/Projects**: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/requests.json`
|
```
|
||||||
- **Session state**: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/session.json`
|
|
||||||
- **Sensitive variables**: GNOME Keyring (encrypted)
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
**Build errors:**
|
|
||||||
- "meson: command not found" → Install Meson
|
|
||||||
- "Package not found" errors → Install missing development packages
|
|
||||||
|
|
||||||
**Runtime errors:**
|
|
||||||
- "Failed to access Secret Service" → Ensure GNOME Keyring is unlocked
|
|
||||||
- "Module 'gi' not found" → Install PyGObject
|
|
||||||
|
|
||||||
**Flatpak:**
|
|
||||||
- "Nothing matches org.gnome.Platform" → Add Flathub remote and install GNOME SDK
|
|
||||||
- No network access → Verify `--share=network` permission
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Getting-Started]] - Learn how to use Roster
|
|
||||||
- [[Projects-and-Environments]] - Organize your API testing
|
|
||||||
- [[Variables]] - Use variables in requests
|
|
||||||
|
|||||||
@ -1,141 +1,28 @@
|
|||||||
# Projects and Environments
|
# Projects and Environments
|
||||||
|
|
||||||
Projects help organize related HTTP requests, while environments allow you to manage different configurations (development, staging, production).
|
|
||||||
|
|
||||||
## Projects
|
## Projects
|
||||||
|
|
||||||
### What is a Project?
|
A project groups saved requests, variables, and environments together. Projects appear in the left sidebar.
|
||||||
|
|
||||||
A project is a container for:
|
- **Create:** click **+** in the sidebar header
|
||||||
- **Saved requests** - Your HTTP requests
|
- **Edit / Delete:** click **⋯** next to the project name
|
||||||
- **Variables** - Shared variables across requests
|
- **Icon:** editable in the project edit dialog
|
||||||
- **Environments** - Different configurations (dev, prod, etc.)
|
|
||||||
|
|
||||||
Example projects:
|
|
||||||
- "GitHub API"
|
|
||||||
- "My App Backend"
|
|
||||||
- "Payment Integration"
|
|
||||||
- "Authentication Service"
|
|
||||||
|
|
||||||
### Creating a Project
|
|
||||||
|
|
||||||
1. Click the "+" icon in top-left
|
|
||||||
2. Enter project name
|
|
||||||
3. Click **"Create"**
|
|
||||||
|
|
||||||
A default "Default" environment is automatically created.
|
|
||||||
|
|
||||||
### Accessing Projects
|
|
||||||
|
|
||||||
Projects appear in the sidebar on the left side:
|
|
||||||
- Click a project to expand/collapse
|
|
||||||
- Shows saved requests within the project
|
|
||||||
- Active project highlighted
|
|
||||||
|
|
||||||
### Editing a Project
|
|
||||||
|
|
||||||
1. Click the "three-dots" symbol near the project name in sidebar
|
|
||||||
2. Select **"Edit Project"**
|
|
||||||
3. Enter new name or click icon to choose from grid
|
|
||||||
4. Click **"Save"**
|
|
||||||
|
|
||||||
### Deleting a Project
|
|
||||||
|
|
||||||
1. Right-click the project in sidebar
|
|
||||||
2. Select **"Delete"**
|
|
||||||
3. Confirm deletion
|
|
||||||
|
|
||||||
**Warning:** This deletes all requests, environments, and variables in the project!
|
|
||||||
|
|
||||||
## Environments
|
|
||||||
|
|
||||||
### What is an Environment?
|
|
||||||
|
|
||||||
An environment is a set of variable values. Common environments:
|
|
||||||
- **Production** - Live API with real credentials
|
|
||||||
- **Staging** - Pre-production testing
|
|
||||||
- **Development** - Local development server
|
|
||||||
- **Testing** - Automated test environment
|
|
||||||
|
|
||||||
### Managing Environments
|
|
||||||
|
|
||||||
See [[Variables]] for complete environment and variable management documentation.
|
|
||||||
|
|
||||||
**Quick access:**
|
|
||||||
1. Select a project
|
|
||||||
2. Click the "three-dots" symbol near the project name in sidebar
|
|
||||||
3. Click **"Manage Environments"
|
|
||||||
3. Manage environments and variables in dialog
|
|
||||||
|
|
||||||
### Default Environment
|
|
||||||
|
|
||||||
Each project starts with a "Default" environment. You can:
|
|
||||||
- Rename it
|
|
||||||
- Add more environments
|
|
||||||
- Delete it (if you have at least one other environment)
|
|
||||||
|
|
||||||
## Saved Requests
|
## Saved Requests
|
||||||
|
|
||||||
### Saving a Request
|
- **Save:** **Ctrl+S**, enter name and select project
|
||||||
|
- **Open:** click request name in the sidebar → opens in a new tab
|
||||||
|
- **Delete:** click **×** next to the request name in sidebar
|
||||||
|
|
||||||
1. Configure your request (URL, method, headers, body)
|
Unsaved changes show a dot (•) on the tab label.
|
||||||
2. Click **"Save"** button in header
|
|
||||||
3. Enter request name (e.g., "Get User Profile")
|
|
||||||
4. Select a project
|
|
||||||
5. Click **"Save"**
|
|
||||||
|
|
||||||
### Opening a Saved Request
|
## Environments and Variables
|
||||||
|
|
||||||
1. Navigate to your project
|
See [[Variables]] for full documentation. Quick access: **⋯ → Manage Environments** next to the project name.
|
||||||
2. Click on a saved request
|
|
||||||
3. Request opens in a new tab
|
|
||||||
|
|
||||||
### Editing a Saved Request
|
|
||||||
|
|
||||||
1. Open the request
|
|
||||||
2. Make changes
|
|
||||||
3. Click **"Save"** (or Ctrl+S)
|
|
||||||
4. Select Project and enter request name
|
|
||||||
5. Click Save
|
|
||||||
|
|
||||||
**Modified indicator:** Unsaved changes show a dot (•) on the tab label.
|
|
||||||
|
|
||||||
### Deleting a Saved Request
|
|
||||||
|
|
||||||
1. Click "x" icon near the request name in sidebar
|
|
||||||
2. Confirm deletion
|
|
||||||
|
|
||||||
Requests can have preprocessing and postprocessing scripts attached. See [[Scripts]] for details.
|
|
||||||
|
|
||||||
## Data Storage
|
## Data Storage
|
||||||
|
|
||||||
### File Location
|
Projects and variables: `~/.local/share/cz.bugsy.roster/requests.json`
|
||||||
|
(Flatpak: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/requests.json`)
|
||||||
|
|
||||||
**Native:**
|
Sensitive variables: GNOME Keyring — see [[Sensitive-Variables]].
|
||||||
```
|
|
||||||
~/.local/share/cz.bugsy.roster/requests.json
|
|
||||||
```
|
|
||||||
|
|
||||||
**Flatpak:**
|
|
||||||
```
|
|
||||||
~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/requests.json
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sensitive Variables
|
|
||||||
|
|
||||||
Regular variables stored in JSON.
|
|
||||||
Sensitive variables stored in GNOME Keyring (encrypted).
|
|
||||||
|
|
||||||
See [[Sensitive-Variables]] for details.
|
|
||||||
|
|
||||||
### Backup
|
|
||||||
|
|
||||||
To backup your projects:
|
|
||||||
1. Copy the `requests.json` file
|
|
||||||
2. For sensitive variables: backup your GNOME Keyring (see [[Sensitive-Variables]])
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Variables]] - Learn about variables and environments
|
|
||||||
- [[Sensitive-Variables]] - Secure credential storage
|
|
||||||
- [[Scripts]] - Automate workflows
|
|
||||||
|
|||||||
441
Scripts.md
441
Scripts.md
@ -1,393 +1,78 @@
|
|||||||
# Scripts
|
# Scripts
|
||||||
|
|
||||||
Roster supports JavaScript preprocessing and postprocessing scripts to automate request modifications and response data extraction.
|
Roster supports JavaScript preprocessing and postprocessing scripts via **GJS** (GNOME JavaScript).
|
||||||
|
|
||||||
## Overview
|
**Preprocessing** — runs before the request is sent; can modify `request`.
|
||||||
|
**Postprocessing** — runs after the response; can read `response` and set variables.
|
||||||
|
|
||||||
Scripts allow you to:
|
Open the **Scripts** tab in the request editor. Save with **Ctrl+S**.
|
||||||
- **Modify requests** before they're sent (preprocessing)
|
|
||||||
- **Extract data** from responses after they're received (postprocessing)
|
|
||||||
- **Chain requests** together by passing data between them
|
|
||||||
- **Automate workflows** like authentication flows
|
|
||||||
|
|
||||||
Scripts are executed using **GJS** (GNOME JavaScript), the same JavaScript runtime used throughout GNOME.
|
|
||||||
|
|
||||||
## Script Types
|
|
||||||
|
|
||||||
### Preprocessing Scripts
|
|
||||||
|
|
||||||
**Run BEFORE the HTTP request is sent.**
|
|
||||||
|
|
||||||
Use cases:
|
|
||||||
- Modify request headers, URL, body, or method
|
|
||||||
- Add dynamic values (timestamps, request IDs, signatures)
|
|
||||||
- Read environment variables
|
|
||||||
- Set/update environment variables
|
|
||||||
- Add authentication headers
|
|
||||||
|
|
||||||
### Postprocessing Scripts
|
|
||||||
|
|
||||||
**Run AFTER receiving the HTTP response.**
|
|
||||||
|
|
||||||
Use cases:
|
|
||||||
- Extract data from response body
|
|
||||||
- Parse JSON/XML responses
|
|
||||||
- Store values in environment variables for use in subsequent requests
|
|
||||||
- Validate response data
|
|
||||||
- Chain requests together
|
|
||||||
|
|
||||||
## Adding Scripts to Requests
|
|
||||||
|
|
||||||
### Step 1: Open Script Editor
|
|
||||||
|
|
||||||
Use the Scripts tab in the request editor
|
|
||||||
|
|
||||||
The script editor tab contains two panels:
|
|
||||||
- **Preprocessing** panel
|
|
||||||
- **Postprocessing** panel
|
|
||||||
|
|
||||||
### Step 2: Write Your Script
|
|
||||||
|
|
||||||
1. Select the appropriate panel
|
|
||||||
2. Write JavaScript code
|
|
||||||
3. Click **"Save"** or **Ctrl+S**
|
|
||||||
|
|
||||||
### Step 3: Run Request with Scripts
|
|
||||||
|
|
||||||
1. Open the request
|
|
||||||
2. Click **"Send"**
|
|
||||||
3. Preprocessing script runs first (if present)
|
|
||||||
4. HTTP request sent
|
|
||||||
5. Postprocessing script runs after response received (if present)
|
|
||||||
|
|
||||||
## Preprocessing API
|
## Preprocessing API
|
||||||
|
|
||||||
### Available Objects
|
|
||||||
|
|
||||||
#### Request Object (Modifiable)
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
request.method // String: "GET", "POST", "PUT", "DELETE"
|
request.method // "GET", "POST", "PUT", "DELETE"
|
||||||
request.url // String: Full URL
|
request.url // Full URL string
|
||||||
request.headers // Object: Header key-value pairs
|
request.headers // Header key-value object
|
||||||
request.body // String: Request body
|
request.body // Request body string
|
||||||
|
|
||||||
|
roster.getVariable(name)
|
||||||
|
roster.setVariable(name, value)
|
||||||
|
roster.setVariables({key: value})
|
||||||
|
roster.project.name
|
||||||
|
roster.project.environments // string[]
|
||||||
|
|
||||||
|
console.log(...) / console.error(...)
|
||||||
```
|
```
|
||||||
|
|
||||||
All properties can be modified.
|
**Example:**
|
||||||
|
|
||||||
#### Roster API
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Variables
|
|
||||||
roster.getVariable(name) // Get variable from selected environment
|
|
||||||
roster.setVariable(name, value) // Set/update variable
|
|
||||||
roster.setVariables({key: value}) // Batch set variables
|
|
||||||
|
|
||||||
// Project Information
|
|
||||||
roster.project.name // Current project name
|
|
||||||
roster.project.environments // Array of environment names
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Console Output
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
console.log(message) // Output shown in preprocessing results tab
|
|
||||||
console.error(message) // Error output
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
#### Example 1: Add Dynamic Authentication Header
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const token = roster.getVariable('auth_token');
|
const token = roster.getVariable('auth_token');
|
||||||
request.headers['Authorization'] = 'Bearer ' + token;
|
request.headers['Authorization'] = 'Bearer ' + token;
|
||||||
request.headers['X-Request-Time'] = new Date().toISOString();
|
request.headers['X-Request-Time'] = new Date().toISOString();
|
||||||
console.log('Added auth header');
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 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');
|
|
||||||
} else {
|
|
||||||
console.log('Using development 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);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 4: Add HMAC Signature
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Note: GJS doesn't have crypto module, this is pseudocode
|
|
||||||
const apiKey = roster.getVariable('api_key');
|
|
||||||
const secretKey = roster.getVariable('secret_key');
|
|
||||||
const timestamp = Date.now().toString();
|
|
||||||
|
|
||||||
// You would use a crypto library here
|
|
||||||
const signature = generateHMAC(request.body + timestamp, secretKey);
|
|
||||||
|
|
||||||
request.headers['X-API-Key'] = apiKey;
|
|
||||||
request.headers['X-Timestamp'] = timestamp;
|
|
||||||
request.headers['X-Signature'] = signature;
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 5: Modify Request Body
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Parse existing body
|
|
||||||
const body = JSON.parse(request.body);
|
|
||||||
|
|
||||||
// Add dynamic fields
|
|
||||||
body.timestamp = new Date().toISOString();
|
|
||||||
body.requestId = Math.random().toString(36).substring(7);
|
|
||||||
body.version = '2.0';
|
|
||||||
|
|
||||||
// Update request body
|
|
||||||
request.body = JSON.stringify(body, null, 2);
|
|
||||||
console.log('Modified request body');
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Postprocessing API
|
## Postprocessing API
|
||||||
|
|
||||||
### Available Objects
|
|
||||||
|
|
||||||
#### Response Object (Read-Only)
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
response.body // String: Response body
|
response.body // string, read-only
|
||||||
response.headers // Object: Header key-value pairs
|
response.headers // object, read-only
|
||||||
response.statusCode // Number: HTTP status code (200, 404, etc.)
|
response.statusCode // number
|
||||||
response.statusText // String: Status text ("OK", "Not Found", etc.)
|
response.statusText // string
|
||||||
response.responseTime // Number: Response time in milliseconds
|
response.responseTime // number (ms)
|
||||||
|
|
||||||
|
roster.setVariable(name, value)
|
||||||
|
roster.setVariables({key: value})
|
||||||
|
// roster.getVariable() is NOT available here
|
||||||
|
|
||||||
|
console.log(...) / console.error(...)
|
||||||
```
|
```
|
||||||
|
|
||||||
All properties are read-only.
|
**Example:**
|
||||||
|
|
||||||
#### Roster API
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Variables
|
|
||||||
roster.setVariable(name, value) // Set/update variable
|
|
||||||
roster.setVariables({key: value}) // Batch set variables
|
|
||||||
```
|
|
||||||
|
|
||||||
Note: `roster.getVariable()` is NOT available in postprocessing.
|
|
||||||
|
|
||||||
#### Console Output
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
console.log(message) // Output shown in postprocessing results tab
|
|
||||||
console.error(message) // Error output
|
|
||||||
```
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
#### 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');
|
|
||||||
} else {
|
|
||||||
console.error('No access token in response');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 2: Extract Multiple Values
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const data = JSON.parse(response.body);
|
const data = JSON.parse(response.body);
|
||||||
roster.setVariables({
|
roster.setVariables({
|
||||||
user_id: data.user.id,
|
access_token: data.access_token,
|
||||||
user_name: data.user.name,
|
user_id: data.user_id
|
||||||
user_email: data.user.email,
|
|
||||||
session_id: data.session.id
|
|
||||||
});
|
});
|
||||||
console.log('Extracted user:', data.user.name);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example 3: Validate and Store Response
|
## Execution Order
|
||||||
|
|
||||||
```javascript
|
1. Preprocessing script
|
||||||
const data = JSON.parse(response.body);
|
2. Variable substitution (`{{variable_name}}`)
|
||||||
|
3. HTTP request
|
||||||
|
4. Postprocessing script
|
||||||
|
5. Response displayed and saved to history
|
||||||
|
|
||||||
if (response.statusCode === 200 && data.items) {
|
## Limitations
|
||||||
roster.setVariable('item_count', data.items.length.toString());
|
|
||||||
|
|
||||||
if (data.items.length > 0) {
|
- Synchronous only — no `async/await`, `setTimeout`, `fetch`
|
||||||
roster.setVariable('first_item_id', data.items[0].id);
|
- No file system, shell, or external library access
|
||||||
roster.setVariable('first_item_name', data.items[0].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Found', data.items.length, 'items');
|
|
||||||
} else {
|
|
||||||
console.error('Error: Invalid response or no items');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 4: Extract Pagination Token
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
|
|
||||||
if (data.next_page_token) {
|
|
||||||
roster.setVariable('next_page', data.next_page_token);
|
|
||||||
console.log('Next page token saved');
|
|
||||||
} else {
|
|
||||||
roster.setVariable('next_page', '');
|
|
||||||
console.log('No more pages');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Example 5: Parse Response Headers
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Extract rate limit information from headers
|
|
||||||
const rateLimit = response.headers['X-RateLimit-Limit'];
|
|
||||||
const rateRemaining = response.headers['X-RateLimit-Remaining'];
|
|
||||||
const rateReset = response.headers['X-RateLimit-Reset'];
|
|
||||||
|
|
||||||
if (rateLimit && rateRemaining && rateReset) {
|
|
||||||
roster.setVariables({
|
|
||||||
rate_limit: rateLimit,
|
|
||||||
rate_remaining: rateRemaining,
|
|
||||||
rate_reset: rateReset
|
|
||||||
});
|
|
||||||
console.log('Rate limit:', rateRemaining, '/', rateLimit);
|
|
||||||
} else {
|
|
||||||
console.log('No rate limit headers');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Complete Workflows
|
|
||||||
|
|
||||||
### Workflow 1: OAuth Token Flow
|
|
||||||
|
|
||||||
**Request 1: Login (POST /auth/login)**
|
|
||||||
|
|
||||||
Postprocessing:
|
|
||||||
```javascript
|
|
||||||
// Extract and store tokens from login response
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
|
|
||||||
if (response.statusCode === 200) {
|
|
||||||
roster.setVariables({
|
|
||||||
access_token: data.access_token,
|
|
||||||
refresh_token: data.refresh_token,
|
|
||||||
user_id: data.user_id,
|
|
||||||
expires_at: data.expires_at
|
|
||||||
});
|
|
||||||
console.log('Logged in as user:', data.user_id);
|
|
||||||
} else {
|
|
||||||
console.error('Login failed:', response.statusText);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**Request 2: Get User Profile (GET /users/{userId})**
|
|
||||||
|
|
||||||
Preprocessing:
|
|
||||||
```javascript
|
|
||||||
// Use stored token and user ID in request
|
|
||||||
const token = roster.getVariable('access_token');
|
|
||||||
const userId = roster.getVariable('user_id');
|
|
||||||
|
|
||||||
// Add authentication
|
|
||||||
request.headers['Authorization'] = 'Bearer ' + token;
|
|
||||||
|
|
||||||
// Substitute user ID in URL
|
|
||||||
request.url = request.url.replace('{userId}', userId);
|
|
||||||
|
|
||||||
console.log('Making authenticated request for user:', userId);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Workflow 2: Paginated API Requests
|
|
||||||
|
|
||||||
**Request: Get Items with Pagination**
|
|
||||||
|
|
||||||
Preprocessing:
|
|
||||||
```javascript
|
|
||||||
const nextPage = roster.getVariable('next_page');
|
|
||||||
|
|
||||||
if (nextPage) {
|
|
||||||
request.url = request.url + '?page_token=' + nextPage;
|
|
||||||
console.log('Fetching next page');
|
|
||||||
} else {
|
|
||||||
console.log('Fetching first page');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Postprocessing:
|
|
||||||
```javascript
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
|
|
||||||
// Store items count
|
|
||||||
roster.setVariable('items_count', data.items.length.toString());
|
|
||||||
|
|
||||||
// Store next page token for subsequent request
|
|
||||||
if (data.next_page_token) {
|
|
||||||
roster.setVariable('next_page', data.next_page_token);
|
|
||||||
console.log('Page loaded. More pages available.');
|
|
||||||
} else {
|
|
||||||
roster.setVariable('next_page', '');
|
|
||||||
console.log('Page loaded. No more pages.');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Workflow 3: Dynamic API Versioning
|
|
||||||
|
|
||||||
**Preprocessing:**
|
|
||||||
```javascript
|
|
||||||
const apiVersion = roster.getVariable('api_version') || 'v1';
|
|
||||||
request.url = request.url.replace('/api/', '/api/' + apiVersion + '/');
|
|
||||||
request.headers['X-API-Version'] = apiVersion;
|
|
||||||
console.log('Using API version:', apiVersion);
|
|
||||||
```
|
|
||||||
|
|
||||||
**Postprocessing:**
|
|
||||||
```javascript
|
|
||||||
// Check if server suggests upgrading API version
|
|
||||||
const suggestedVersion = response.headers['X-Suggested-API-Version'];
|
|
||||||
|
|
||||||
if (suggestedVersion) {
|
|
||||||
console.log('Server suggests API version:', suggestedVersion);
|
|
||||||
roster.setVariable('suggested_api_version', suggestedVersion);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Script Execution Flow
|
|
||||||
|
|
||||||
When sending a request with scripts:
|
|
||||||
1. Execute preprocessing script (if present) - can modify request
|
|
||||||
2. Apply variable substitution (`{{variable_name}}`)
|
|
||||||
3. Send HTTP request
|
|
||||||
4. Execute postprocessing script (if present) - can read response, set variables
|
|
||||||
5. Display response and save to history
|
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
If a script throws an error, the error is shown in the script output panel. The request still executes (preprocessing) or response still displays (postprocessing). Variable changes before the error are preserved.
|
Script errors are shown in the output panel; the request still executes.
|
||||||
|
|
||||||
Always use try-catch for JSON parsing:
|
|
||||||
```javascript
|
```javascript
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(response.body);
|
const data = JSON.parse(response.body);
|
||||||
@ -397,46 +82,4 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Best Practices
|
See [[API-Reference]] for the full API reference.
|
||||||
|
|
||||||
- **Keep scripts simple** - One clear purpose per script
|
|
||||||
- **Handle errors** - Use try-catch for JSON parsing and check status codes
|
|
||||||
- **Use logging** - Track execution with console.log for debugging
|
|
||||||
- **Never log secrets** - Log confirmations, not actual token/key values
|
|
||||||
|
|
||||||
## Limitations
|
|
||||||
|
|
||||||
### No External Libraries
|
|
||||||
|
|
||||||
GJS environment is sandboxed:
|
|
||||||
- Cannot import npm packages
|
|
||||||
- Cannot require() external modules
|
|
||||||
- Standard JavaScript built-ins available
|
|
||||||
|
|
||||||
### No Asynchronous Operations
|
|
||||||
|
|
||||||
Scripts execute synchronously:
|
|
||||||
- No setTimeout/setInterval
|
|
||||||
- No async/await
|
|
||||||
- No fetch() or XMLHttpRequest
|
|
||||||
- Use Roster's request system instead
|
|
||||||
|
|
||||||
### Security Restrictions
|
|
||||||
|
|
||||||
Scripts cannot:
|
|
||||||
- Access file system directly
|
|
||||||
- Make network requests (other than the main request)
|
|
||||||
- Execute shell commands
|
|
||||||
- Access system resources
|
|
||||||
|
|
||||||
## Debugging Scripts
|
|
||||||
|
|
||||||
- Use console.log liberally to track script execution
|
|
||||||
- Check Preprocessing/Postprocessing panels for output and errors
|
|
||||||
- Start with simple test scripts and build up complexity
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[API-Reference]] - Complete API documentation
|
|
||||||
- [[Variables]] - Learn about environment variables
|
|
||||||
- [[Sensitive-Variables]] - Secure storage for tokens and keys
|
|
||||||
|
|||||||
@ -1,153 +1,40 @@
|
|||||||
# Sensitive Variables
|
# Sensitive Variables
|
||||||
|
|
||||||
Sensitive variables provide secure storage for API keys, passwords, and tokens using GNOME Keyring encryption instead of plain text files.
|
Sensitive variables store their values in **GNOME Keyring** (encrypted) instead of plain-text JSON. Use them for API keys, passwords, and tokens.
|
||||||
|
|
||||||
## Overview
|
## Marking a Variable as Sensitive
|
||||||
|
|
||||||
Regular [[Variables]] are stored in plain text JSON files at `~/.local/share/cz.bugsy.roster/requests.json`. This is fine for non-sensitive data like base URLs or timeout values, but **dangerous for secrets**.
|
In the Environments dialog, click the **lock icon** on a variable row. The icon toggles between locked (keyring) and unlocked (JSON). Existing values are automatically migrated when you toggle.
|
||||||
|
|
||||||
**Sensitive variables** solve this by storing values encrypted in GNOME Keyring, the same secure storage used by:
|
Sensitive variable values display as bullets (••••) in the dialog.
|
||||||
- Firefox and GNOME Web for passwords
|
|
||||||
- Evolution for email credentials
|
|
||||||
- Network Manager for WiFi passwords
|
|
||||||
- SSH for key passphrases
|
|
||||||
|
|
||||||
## How It Works
|
## Usage in Requests
|
||||||
|
|
||||||
### Storage Comparison
|
Works exactly like regular variables — use `{{variable_name}}` syntax. Roster retrieves and decrypts the value transparently before sending.
|
||||||
|
|
||||||
**Regular Variable (Insecure):**
|
## Script Access
|
||||||
```
|
|
||||||
File: ~/.local/share/cz.bugsy.roster/requests.json
|
Scripts access sensitive variables the same way as regular ones:
|
||||||
Format: Plain text (anyone can read)
|
|
||||||
Content: "api_key": "secret-abc123-visible-to-all"
|
```javascript
|
||||||
|
// Preprocessing
|
||||||
|
const key = roster.getVariable('api_key'); // decrypted automatically
|
||||||
|
|
||||||
|
// Postprocessing — if 'access_token' is marked sensitive, it goes to keyring
|
||||||
|
roster.setVariable('access_token', data.access_token);
|
||||||
```
|
```
|
||||||
|
|
||||||
**Sensitive Variable (Secure):**
|
## Keyring Schema
|
||||||
```
|
|
||||||
File: ~/.local/share/cz.bugsy.roster/requests.json
|
|
||||||
Format: Plain text
|
|
||||||
Content: "api_key": "" (empty placeholder)
|
|
||||||
|
|
||||||
Keyring: GNOME Keyring (encrypted)
|
- **Schema:** `cz.bugsy.roster.EnvironmentVariable`
|
||||||
Format: Encrypted with your login password
|
- **Attributes:** `project_id`, `environment_id`, `variable_name`
|
||||||
Content: "secret-abc123-visible-to-all" (encrypted at rest)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
Secrets are visible in **Passwords and Keys** (Seahorse) under the Login keyring.
|
||||||
|
|
||||||
### Mark Variable as Sensitive
|
|
||||||
|
|
||||||
Open the Environments dialog for your project.
|
|
||||||
|
|
||||||
Each variable row has a **lock icon** to toggle between secure/insecure storage.
|
|
||||||
|
|
||||||
**Before entering secrets (recommended):**
|
|
||||||
1. Create variable (e.g., `api_key`)
|
|
||||||
2. Click the **lock icon** - it changes to locked state
|
|
||||||
3. Variable name becomes bold and colored
|
|
||||||
4. Enter your secret value
|
|
||||||
|
|
||||||
**After entering secrets (migration):**
|
|
||||||
1. Click the lock icon on existing variable
|
|
||||||
2. Values automatically move from JSON to keyring
|
|
||||||
|
|
||||||
### Enter Secret Values
|
|
||||||
|
|
||||||
Values in sensitive variables:
|
|
||||||
- Display as bullets (••••••) instead of characters
|
|
||||||
- Automatically save to GNOME Keyring (encrypted)
|
|
||||||
|
|
||||||
### Use in Requests
|
|
||||||
|
|
||||||
Sensitive variables work exactly like regular variables:
|
|
||||||
|
|
||||||
```
|
|
||||||
GET {{base_url}}/users
|
|
||||||
Authorization: Bearer {{api_key}}
|
|
||||||
```
|
|
||||||
|
|
||||||
When you send the request:
|
|
||||||
1. Roster retrieves `api_key` from GNOME Keyring
|
|
||||||
2. Decrypts it using your login password
|
|
||||||
3. Substitutes it into the request
|
|
||||||
4. Sends the request with the real value
|
|
||||||
|
|
||||||
## Viewing Secrets in Keyring
|
|
||||||
|
|
||||||
Open "Passwords and Keys" (Seahorse) and navigate to "Login" keyring. Look for entries labeled `Roster: ProjectName/EnvironmentName/VariableName`.
|
|
||||||
|
|
||||||
You can view, edit, or delete secrets from Seahorse (requires authentication).
|
|
||||||
|
|
||||||
## Making Variables Non-Sensitive
|
|
||||||
|
|
||||||
If you marked a variable as sensitive by mistake:
|
|
||||||
|
|
||||||
1. Click the lock icon again
|
|
||||||
2. Icon changes from locked to unlocked
|
|
||||||
3. Values move from keyring back to JSON
|
|
||||||
4. You can now see values in plain text
|
|
||||||
|
|
||||||
**Warning:** Only do this for non-sensitive data! Once moved to JSON, the values are visible to anyone who can read your files.
|
|
||||||
|
|
||||||
## Security
|
|
||||||
|
|
||||||
- Encrypted at rest with your GNOME login password
|
|
||||||
- Keyring unlocks automatically on login
|
|
||||||
- Only accessible by your user account
|
|
||||||
- Flatpak requires explicit permission
|
|
||||||
|
|
||||||
## Automatic Cleanup
|
## Automatic Cleanup
|
||||||
|
|
||||||
Roster automatically removes keyring secrets when you delete variables, environments, or projects. Renamed variables are also automatically updated in the keyring.
|
Roster removes keyring entries when you delete or rename variables, environments, or projects.
|
||||||
|
|
||||||
## Script Integration
|
## Flatpak
|
||||||
|
|
||||||
Scripts can access sensitive variables transparently:
|
Requires D-Bus permission `--talk-name=org.freedesktop.secrets` in the Flatpak manifest.
|
||||||
|
|
||||||
### Reading Sensitive Variables
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Preprocessing script
|
|
||||||
const apiKey = roster.getVariable('api_key'); // Retrieved from keyring
|
|
||||||
request.headers['X-API-Key'] = apiKey;
|
|
||||||
console.log('Using API key'); // DON'T log the actual value!
|
|
||||||
```
|
|
||||||
|
|
||||||
### Writing Sensitive Variables
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Postprocessing script
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
|
|
||||||
// If 'access_token' is marked as sensitive, it goes to keyring
|
|
||||||
roster.setVariable('access_token', data.access_token);
|
|
||||||
console.log('Saved access token to keyring');
|
|
||||||
```
|
|
||||||
|
|
||||||
Scripts don't need to know whether variables are sensitive - storage is handled automatically.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
**Keyring not unlocked:**
|
|
||||||
- Ensure you're logged into GNOME (keyring unlocks automatically)
|
|
||||||
- Manual unlock: Open Seahorse, right-click "Login", select "Unlock"
|
|
||||||
|
|
||||||
**Flatpak permission denied:**
|
|
||||||
- Verify `cz.bugsy.roster.json` includes `--talk-name=org.freedesktop.secrets`
|
|
||||||
- Check: `flatpak info --show-permissions cz.bugsy.roster`
|
|
||||||
|
|
||||||
**Secrets missing after reinstall:**
|
|
||||||
- Keyring persists across installs - check Seahorse under "Login" keyring
|
|
||||||
|
|
||||||
## Platform Notes
|
|
||||||
|
|
||||||
Both native and Flatpak installations use the same system keyring. Secrets work across install methods.
|
|
||||||
|
|
||||||
Flatpak requires D-Bus permission: `--talk-name=org.freedesktop.secrets`
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Variables]] - Learn about regular variables
|
|
||||||
- [[Scripts]] - Use variables in automation scripts
|
|
||||||
- [[API-Reference]] - Complete JavaScript API documentation
|
|
||||||
|
|||||||
216
Variables.md
216
Variables.md
@ -1,216 +1,48 @@
|
|||||||
# Variables
|
# Variables
|
||||||
|
|
||||||
Variables allow you to reuse values across multiple requests and switch between different environments (development, staging, production) with ease.
|
Variables let you reuse values across requests and switch between environments (dev, staging, prod) with one click.
|
||||||
|
|
||||||
## What are Variables?
|
## Syntax
|
||||||
|
|
||||||
Variables are placeholder values that you can reference in your requests using the `{{variable_name}}` syntax. When you send a request, Roster automatically replaces these placeholders with the actual values from your selected environment.
|
Use `{{variable_name}}` in URL, headers, or body. When sending, Roster replaces placeholders with values from the selected environment.
|
||||||
|
|
||||||
**Example:**
|
|
||||||
```
|
```
|
||||||
URL: {{base_url}}/users
|
GET {{base_url}}/users
|
||||||
Headers:
|
Authorization: Bearer {{api_token}}
|
||||||
Authorization: Bearer {{api_token}}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
When sent with the "Production" environment:
|
## Managing Environments and Variables
|
||||||
```
|
|
||||||
URL: https://api.example.com/users
|
|
||||||
Headers:
|
|
||||||
Authorization: Bearer prod-token-abc123
|
|
||||||
```
|
|
||||||
|
|
||||||
## Environments
|
Open via **⋯ → Manage Environments** next to the project name in the sidebar.
|
||||||
|
|
||||||
Environments are collections of variable values. Common environment names:
|
- **Add environment:** click **+** next to the environment list
|
||||||
- **Production** - Live API credentials
|
- **Add variable:** click **+** at the bottom of the variable list
|
||||||
- **Staging** - Pre-production testing
|
- **Delete:** click **×** on the variable row or environment header
|
||||||
- **Development** - Local development server
|
- **Rename:** click the name inline
|
||||||
|
|
||||||
Each project can have multiple environments, and each environment has its own set of variable values.
|
Values are entered in the table cells per environment. Close the dialog to save.
|
||||||
|
|
||||||
## Creating Environments
|
## Selecting an Environment
|
||||||
|
|
||||||
### Step 1: Open Environments Dialog
|
Use the environment dropdown at the top of the request panel. All `{{...}}` placeholders resolve to values from the selected environment.
|
||||||
|
|
||||||
1. Select a project from the sidebar
|
Undefined variables are highlighted with a warning color; the literal `{{variable_name}}` is sent as-is.
|
||||||
2. Click the "Three-Dots" button near the project name
|
|
||||||
3. Select **"Manage Environments"**
|
|
||||||
|
|
||||||
### Step 2: Add Environment
|
## Script Access
|
||||||
|
|
||||||
1. Click **+** button near Environments
|
|
||||||
2. Enter name (e.g., "Production", "Development")
|
|
||||||
3. Click **"Add"**
|
|
||||||
|
|
||||||
The environment appears as a new column in the table.
|
|
||||||
|
|
||||||
### Step 3: Add Variables
|
|
||||||
|
|
||||||
1. Click the **"+"** button at the bottom of the variable list
|
|
||||||
2. Enter variable name (e.g., `base_url`)
|
|
||||||
3. Click **"Add"**
|
|
||||||
|
|
||||||
The variable appears as a new row in the table.
|
|
||||||
|
|
||||||
### Step 4: Set Values
|
|
||||||
|
|
||||||
Click in the cells to enter values for each environment:
|
|
||||||
|
|
||||||
| Variable | Production | Development |
|
|
||||||
|----------|-----------|-------------|
|
|
||||||
| base_url | `https://api.example.com` | `http://localhost:3000` |
|
|
||||||
| timeout | `30` | `60` |
|
|
||||||
|
|
||||||
Close Manage Environments table to save.
|
|
||||||
|
|
||||||
## Using Variables in Requests
|
|
||||||
|
|
||||||
### Variable Syntax
|
|
||||||
|
|
||||||
Use double curly braces: `{{variable_name}}`
|
|
||||||
|
|
||||||
Variables work in:
|
|
||||||
- **URL**: `{{base_url}}/users`
|
|
||||||
- **Headers**: `Authorization: Bearer {{token}}`
|
|
||||||
- **Request Body**: `{"api_key": "{{api_key}}"}`
|
|
||||||
|
|
||||||
### Select Environment
|
|
||||||
|
|
||||||
1. Open a request tab
|
|
||||||
2. Use the **environment dropdown** (top of request panel)
|
|
||||||
3. Select environment (e.g., "Production")
|
|
||||||
4. All variables in the request will use values from this environment
|
|
||||||
|
|
||||||
### Visual Indicators
|
|
||||||
|
|
||||||
**Defined variables** - Normal appearance
|
|
||||||
|
|
||||||
**Undefined variables** - Highlighted with a warning color
|
|
||||||
- Variable name exists in `{{...}}` syntax
|
|
||||||
- But not defined in current environment
|
|
||||||
|
|
||||||
## Managing Variables
|
|
||||||
|
|
||||||
### Rename Variable
|
|
||||||
|
|
||||||
1. Open **Manage Environments** dialog
|
|
||||||
2. Click on variable name
|
|
||||||
3. Edit the name
|
|
||||||
|
|
||||||
The variable is renamed across all environments automatically.
|
|
||||||
|
|
||||||
### Delete Variable
|
|
||||||
|
|
||||||
1. Open **Environments** dialog
|
|
||||||
2. Click the **x** next to variable name
|
|
||||||
3. Confirm deletion
|
|
||||||
|
|
||||||
The variable is removed from all environments.
|
|
||||||
|
|
||||||
### Rename Environment
|
|
||||||
|
|
||||||
1. Open **Environments** dialog
|
|
||||||
2. Click the **edit icon** on environment column header
|
|
||||||
3. Enter new name
|
|
||||||
4. Click **"Save"**
|
|
||||||
|
|
||||||
### Delete Environment
|
|
||||||
|
|
||||||
1. Open **Environments** dialog
|
|
||||||
2. Click the **trash icon** on environment column header
|
|
||||||
3. Confirm deletion
|
|
||||||
|
|
||||||
All variable values for that environment are deleted.
|
|
||||||
|
|
||||||
**Note:** Each project must have at least one environment.
|
|
||||||
|
|
||||||
## Common Variable Patterns
|
|
||||||
|
|
||||||
Common variables to define across environments:
|
|
||||||
- `base_url` - API base URL (e.g., `https://api.example.com` vs `http://localhost:3000`)
|
|
||||||
- `api_version` - API version (e.g., `v2` vs `v2-beta`)
|
|
||||||
- `timeout` - Request timeout values
|
|
||||||
- `env` - Environment identifier for headers
|
|
||||||
- `test_user_id` - Test data IDs
|
|
||||||
|
|
||||||
## Script Integration
|
|
||||||
|
|
||||||
Variables can be accessed and modified from [[Scripts]]:
|
|
||||||
|
|
||||||
### Reading Variables (Preprocessing)
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const baseUrl = roster.getVariable('base_url');
|
// Preprocessing
|
||||||
const apiKey = roster.getVariable('api_key');
|
const url = roster.getVariable('base_url');
|
||||||
|
|
||||||
console.log('Using base URL:', baseUrl);
|
// Preprocessing or postprocessing
|
||||||
request.headers['X-API-Key'] = apiKey;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Writing Variables (Postprocessing)
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
// Extract token from response and save for next request
|
|
||||||
const data = JSON.parse(response.body);
|
|
||||||
roster.setVariable('auth_token', data.access_token);
|
roster.setVariable('auth_token', data.access_token);
|
||||||
roster.setVariable('user_id', data.user_id);
|
roster.setVariables({ token: data.token, user_id: data.id });
|
||||||
console.log('Saved token for user:', data.user_id);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Batch Updates
|
## Sensitive Variables
|
||||||
|
|
||||||
```javascript
|
For API keys and passwords, use [[Sensitive-Variables]] — values are stored in GNOME Keyring instead of plain-text JSON.
|
||||||
// Update multiple variables at once
|
|
||||||
roster.setVariables({
|
|
||||||
access_token: data.access_token,
|
|
||||||
refresh_token: data.refresh_token,
|
|
||||||
user_id: data.user.id,
|
|
||||||
user_name: data.user.name
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Scripts automatically update variables in the currently selected environment.
|
## Storage
|
||||||
|
|
||||||
## Variable Scoping
|
Regular variables: `~/.local/share/cz.bugsy.roster/requests.json` (Flatpak: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/requests.json`)
|
||||||
|
|
||||||
**Project Level:**
|
|
||||||
- Variables are defined at the project level
|
|
||||||
- All requests in the project can access these variables
|
|
||||||
|
|
||||||
**Environment Level:**
|
|
||||||
- Variable values are specific to each environment
|
|
||||||
- Switching environments switches all values at once
|
|
||||||
|
|
||||||
**Not Global:**
|
|
||||||
- Variables from one project cannot be used in another project
|
|
||||||
- Each project has its own isolated set of variables
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
- **Keep environments consistent** - All environments should have the same variable names with different values
|
|
||||||
- **Use sensitive variables for secrets** - Never store API keys, passwords, or tokens in regular variables (they're plain text). Use [[Sensitive-Variables]] instead
|
|
||||||
|
|
||||||
## Undefined Variables
|
|
||||||
|
|
||||||
When `{{variable_name}}` is not defined in the current environment:
|
|
||||||
- Entry field is highlighted with warning color
|
|
||||||
- The literal text `{{variable_name}}` is sent in the request
|
|
||||||
|
|
||||||
To fix, add the variable in the Environments dialog.
|
|
||||||
|
|
||||||
## Environment Switching
|
|
||||||
|
|
||||||
Use the environment dropdown to test the same request against different targets. For example, `GET {{base_url}}/users` will hit `localhost:3000/users` in Development or `api.example.com/users` in Production.
|
|
||||||
|
|
||||||
## Advanced Topics
|
|
||||||
|
|
||||||
- **Variables in JSON body** - Use `{{variable}}` syntax. Remove quotes for numeric values
|
|
||||||
- **Nested variables** - Variables can reference other variables (e.g., `{{base_url}}/{{api_version}}`)
|
|
||||||
- **Script-created variables** - Scripts can create variables with `roster.setVariable()`
|
|
||||||
|
|
||||||
## Next Steps
|
|
||||||
|
|
||||||
- [[Sensitive-Variables]] - Store API keys and secrets securely
|
|
||||||
- [[Scripts]] - Automate variable management with JavaScript
|
|
||||||
- [[API-Reference]] - Complete API for working with variables
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user