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
|
||||
|
||||
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+)
|
||||
**Runtime:** GJS (GNOME JavaScript)
|
||||
**Context:** Sandboxed, synchronous execution
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `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
|
||||
request // Modifiable request object
|
||||
roster // Roster API (with getVariable)
|
||||
console // Console output
|
||||
```
|
||||
All properties are read-only.
|
||||
|
||||
### 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
|
||||
response // Read-only response object
|
||||
roster // Roster API (without getVariable)
|
||||
console // Console output
|
||||
```
|
||||
Variable names must match `/^\w+$/` (alphanumeric + underscore). Values are always strings. Sensitive variables are automatically routed to/from GNOME Keyring.
|
||||
|
||||
## Request Object
|
||||
## Console
|
||||
|
||||
**Available in:** Preprocessing scripts only
|
||||
**Type:** Mutable
|
||||
`console.log(...)` and `console.error(...)` — output appears in the Preprocessing/Postprocessing results tab.
|
||||
|
||||
### Properties
|
||||
## Available Built-ins
|
||||
|
||||
#### `request.method`
|
||||
Standard JS built-ins: `Date`, `JSON`, `Math`, `String`, `Array`, `Object`, etc.
|
||||
|
||||
**Type:** `string`
|
||||
**Values:** `"GET"`, `"POST"`, `"PUT"`, `"DELETE"`
|
||||
**Description:** HTTP method for the request
|
||||
No `fetch`, `setTimeout`, `require`, or file system access.
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
// Change method from GET to POST
|
||||
request.method = "POST";
|
||||
console.log('Method changed to:', request.method);
|
||||
```
|
||||
## Type Notes
|
||||
|
||||
#### `request.url`
|
||||
|
||||
**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:
|
||||
Variables are always strings. Convert when needed:
|
||||
```javascript
|
||||
roster.setVariable('count', data.count.toString());
|
||||
const count = parseInt(roster.getVariable('count'), 10);
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
## Examples
|
||||
|
||||
- [[Scripts]] - Practical examples and workflows
|
||||
- [[Variables]] - Learn about environment variables
|
||||
- [[Sensitive-Variables]] - Secure credential storage
|
||||
### Authentication flow
|
||||
|
||||
**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/
|
||||
├── requests.json # Projects, environments, regular variables
|
||||
└── session.json # History, window state
|
||||
└── history.json # Request history
|
||||
```
|
||||
|
||||
**Flatpak:**
|
||||
```
|
||||
~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/
|
||||
├── requests.json
|
||||
└── session.json
|
||||
└── history.json
|
||||
```
|
||||
|
||||
### Data Format
|
||||
@ -104,18 +104,23 @@ Postprocessing Script → Display Response → Save to History
|
||||
**requests.json:**
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"projects": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"name": "Project Name",
|
||||
"icon": "icon-name",
|
||||
"created_at": "2025-01-01T00:00:00+00:00",
|
||||
"variable_names": ["base_url", "api_key"],
|
||||
"sensitive_variables": ["api_key"],
|
||||
"environments": [
|
||||
{
|
||||
"id": "uuid",
|
||||
"name": "Production",
|
||||
"created_at": "2025-01-01T00:00:00+00:00",
|
||||
"variables": {
|
||||
"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",
|
||||
"name": "Get Users",
|
||||
"created_at": "2025-01-01T00:00:00+00:00",
|
||||
"modified_at": "2025-01-01T00:00:00+00:00",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "{{base_url}}/users",
|
||||
"headers": {},
|
||||
"body": "",
|
||||
"preprocessing_script": "",
|
||||
"postprocessing_script": ""
|
||||
"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
|
||||
|
||||
Stored in GNOME Keyring with schema:
|
||||
|
||||
147
Export.md
147
Export.md
@ -1,12 +1,8 @@
|
||||
# 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
|
||||
|
||||
### cURL
|
||||
|
||||
Export requests as cURL commands for use in terminal or scripts.
|
||||
Variables are substituted with values from the selected environment before export.
|
||||
|
||||
**Example output:**
|
||||
```bash
|
||||
@ -16,141 +12,4 @@ curl -X POST 'https://api.example.com/users' \
|
||||
-d '{"name":"John","email":"john@example.com"}'
|
||||
```
|
||||
|
||||
### Other Formats
|
||||
|
||||
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
|
||||
Sensitive variable values are included in plain text — review before sharing.
|
||||
|
||||
249
FAQ.md
249
FAQ.md
@ -2,243 +2,66 @@
|
||||
|
||||
## 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?
|
||||
|
||||
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.
|
||||
**Is it free?**
|
||||
Yes, GPL-3.0-or-later.
|
||||
|
||||
## 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:
|
||||
- Build from source
|
||||
- Install via Flatpak
|
||||
- Use GNOME Builder
|
||||
**Is Roster on Flathub?**
|
||||
Yes. Install with `flatpak install flathub cz.bugsy.roster` or find it in GNOME Software.
|
||||
|
||||
### 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.
|
||||
|
||||
## 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.
|
||||
**Can variables be shared between projects?**
|
||||
No, variables are scoped to their project.
|
||||
|
||||
## 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.**
|
||||
|
||||
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.
|
||||
**Where are secrets stored?**
|
||||
In GNOME Keyring (`~/.local/share/keyrings/`), same as browser passwords and WiFi credentials. Visible in Seahorse under "Login" keyring.
|
||||
|
||||
## 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 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.
|
||||
**Can I use npm packages / async / file system?**
|
||||
No — scripts are sandboxed and synchronous. See [[Scripts]] for full limitations.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Roster won't start
|
||||
**Roster won't start**
|
||||
Check dependencies: `pkg-config --modversion gtk4 libadwaita-1`
|
||||
|
||||
**Check dependencies:**
|
||||
```bash
|
||||
# Verify GTK 4 and libadwaita are installed
|
||||
pkg-config --modversion gtk4 libadwaita-1
|
||||
```
|
||||
**Keyring not accessible**
|
||||
Ensure GNOME Keyring is unlocked. For Flatpak, verify `--talk-name=org.freedesktop.secrets` permission.
|
||||
|
||||
**Check logs:**
|
||||
```bash
|
||||
# Native
|
||||
roster
|
||||
**Variables not substituting**
|
||||
Check: environment is selected, variable name matches exactly (case-sensitive), syntax is `{{name}}`.
|
||||
|
||||
# Flatpak
|
||||
flatpak run cz.bugsy.roster
|
||||
```
|
||||
|
||||
### 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.
|
||||
**How do I reset 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.
|
||||
|
||||
## Contributing
|
||||
|
||||
### How can I contribute?
|
||||
|
||||
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
|
||||
Report bugs and request features: https://git.bugsy.cz/beval/roster/issues
|
||||
See [[Contributing]] for contribution guidelines.
|
||||
|
||||
@ -1,156 +1,35 @@
|
||||
# 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:
|
||||
- Your application menu (search for "Roster")
|
||||
- Command line: `roster` (or `flatpak run cz.bugsy.roster` for Flatpak)
|
||||
1. The app opens with a new request tab
|
||||
2. Set the URL (e.g. `https://api.github.com/users/octocat`) and method (`GET`)
|
||||
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:**
|
||||
```
|
||||
https://api.github.com/users/octocat
|
||||
```
|
||||
Every sent request is automatically saved to history (bottom panel). Click any entry to open it in a new tab.
|
||||
|
||||
**Set the Method:**
|
||||
- Use the dropdown menu (default is `GET`)
|
||||
## Tabs
|
||||
|
||||
**Add Headers (Optional):**
|
||||
1. Click the **"Headers"** tab
|
||||
2. Add a header:
|
||||
- Key: `User-Agent`
|
||||
- Value: `Roster/0.6.0`
|
||||
|
||||
### 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.
|
||||
| Action | Shortcut |
|
||||
|--------|----------|
|
||||
| New tab | **Ctrl+T** |
|
||||
| Close tab | **Ctrl+W** |
|
||||
| Switch tabs | **Ctrl+Tab** / **Ctrl+Shift+Tab** |
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you know the basics, explore more advanced features:
|
||||
|
||||
- [[Projects-and-Environments]] - Organize requests and manage environments
|
||||
- [[Variables]] - Use variables to avoid repetition
|
||||
- [[Sensitive-Variables]] - Store API keys securely
|
||||
- [[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
|
||||
- [[Projects-and-Environments]] — organize requests
|
||||
- [[Variables]] — avoid repeating URLs and headers
|
||||
- [[Sensitive-Variables]] — store API keys securely
|
||||
- [[Scripts]] — automate with JavaScript
|
||||
- [[Import]] — import from OpenAPI/Swagger or WSDL
|
||||
|
||||
122
History.md
122
History.md
@ -1,124 +1,22 @@
|
||||
# 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:
|
||||
- Request method, URL, headers, body
|
||||
- Response status, headers, body, timing
|
||||
- Timestamp of when request was sent
|
||||
- Environment used (if applicable)
|
||||
History appears in the **bottom panel** of the main window. Each entry shows method, URL, status code, timestamp, and response time, sorted newest first.
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
- Native: `~/.local/share/cz.bugsy.roster/history.json`
|
||||
- Flatpak: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/history.json`
|
||||
|
||||
## 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
|
||||
# Native
|
||||
rm ~/.local/share/cz.bugsy.roster/session.json
|
||||
## Privacy
|
||||
|
||||
# Flatpak
|
||||
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
|
||||
History contains full request and response data in plaintext, including headers and bodies. Clear it periodically if requests contain sensitive data.
|
||||
|
||||
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
|
||||
- JavaScript preprocessing and postprocessing scripts
|
||||
- Request history and export to cURL
|
||||
- Import from OpenAPI/Swagger (2.0 + 3.x) and WSDL
|
||||
|
||||
## 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
|
||||
- [[Export]] - Export requests to other tools
|
||||
- [[History]] - Track and replay requests
|
||||
- [[Import]] - Import from OpenAPI/Swagger and WSDL
|
||||
|
||||
### Reference
|
||||
- [[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
|
||||
|
||||
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
|
||||
- **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 from Source
|
||||
|
||||
### Build Dependencies
|
||||
- **Meson** (>= 1.0.0)
|
||||
- **Ninja**
|
||||
- **pkg-config**
|
||||
- **gettext** - For internationalization
|
||||
- **glib-compile-schemas**
|
||||
- **glib-compile-resources**
|
||||
**Dependencies:**
|
||||
|
||||
## Installation Methods
|
||||
|
||||
### Method 1: Build from Source (Native)
|
||||
|
||||
This method builds and installs Roster directly on your system.
|
||||
|
||||
#### Step 1: Install Dependencies
|
||||
- Meson >= 1.0, Ninja, pkg-config, gettext
|
||||
- GTK 4, libadwaita 1, libsoup3, libsecret, GJS, PyGObject
|
||||
|
||||
**Fedora:**
|
||||
```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
|
||||
```
|
||||
|
||||
**Arch Linux:**
|
||||
**Arch:**
|
||||
```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
|
||||
git clone https://git.bugsy.cz/beval/roster.git
|
||||
cd roster
|
||||
```
|
||||
|
||||
#### Step 3: Build
|
||||
|
||||
```bash
|
||||
meson setup builddir
|
||||
meson compile -C builddir
|
||||
```
|
||||
|
||||
#### Step 4: Install
|
||||
|
||||
```bash
|
||||
sudo meson install -C builddir
|
||||
```
|
||||
|
||||
#### Step 5: Run
|
||||
|
||||
```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
|
||||
## Build Flatpak Locally
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
#### Step 5: Run
|
||||
|
||||
```bash
|
||||
flatpak run cz.bugsy.roster
|
||||
```
|
||||
|
||||
### Method 3: GNOME Builder (For Development)
|
||||
## GNOME Builder
|
||||
|
||||
GNOME Builder provides an integrated development environment.
|
||||
|
||||
#### 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
|
||||
```
|
||||
Clone `https://git.bugsy.cz/beval/roster.git` in GNOME Builder and hit Run.
|
||||
|
||||
## 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`)
|
||||
- **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)
|
||||
## Uninstall
|
||||
|
||||
### Flatpak Installation
|
||||
```bash
|
||||
# Source build
|
||||
sudo ninja -C builddir uninstall
|
||||
|
||||
- **Binary**: Managed by Flatpak
|
||||
- **Application data**: `~/.var/app/cz.bugsy.roster/data/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
|
||||
# Flatpak
|
||||
flatpak uninstall cz.bugsy.roster
|
||||
```
|
||||
|
||||
@ -1,141 +1,28 @@
|
||||
# Projects and Environments
|
||||
|
||||
Projects help organize related HTTP requests, while environments allow you to manage different configurations (development, staging, production).
|
||||
|
||||
## 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:
|
||||
- **Saved requests** - Your HTTP requests
|
||||
- **Variables** - Shared variables across requests
|
||||
- **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)
|
||||
- **Create:** click **+** in the sidebar header
|
||||
- **Edit / Delete:** click **⋯** next to the project name
|
||||
- **Icon:** editable in the project edit dialog
|
||||
|
||||
## 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)
|
||||
2. Click **"Save"** button in header
|
||||
3. Enter request name (e.g., "Get User Profile")
|
||||
4. Select a project
|
||||
5. Click **"Save"**
|
||||
Unsaved changes show a dot (•) on the tab label.
|
||||
|
||||
### Opening a Saved Request
|
||||
## Environments and Variables
|
||||
|
||||
1. Navigate to your project
|
||||
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.
|
||||
See [[Variables]] for full documentation. Quick access: **⋯ → Manage Environments** next to the project name.
|
||||
|
||||
## 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:**
|
||||
```
|
||||
~/.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
|
||||
Sensitive variables: GNOME Keyring — see [[Sensitive-Variables]].
|
||||
|
||||
441
Scripts.md
441
Scripts.md
@ -1,393 +1,78 @@
|
||||
# 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:
|
||||
- **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)
|
||||
Open the **Scripts** tab in the request editor. Save with **Ctrl+S**.
|
||||
|
||||
## Preprocessing API
|
||||
|
||||
### Available Objects
|
||||
|
||||
#### Request Object (Modifiable)
|
||||
|
||||
```javascript
|
||||
request.method // String: "GET", "POST", "PUT", "DELETE"
|
||||
request.url // String: Full URL
|
||||
request.headers // Object: Header key-value pairs
|
||||
request.body // String: Request body
|
||||
request.method // "GET", "POST", "PUT", "DELETE"
|
||||
request.url // Full URL string
|
||||
request.headers // Header key-value object
|
||||
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.
|
||||
|
||||
#### 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
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
const token = roster.getVariable('auth_token');
|
||||
request.headers['Authorization'] = 'Bearer ' + token;
|
||||
request.headers['X-Request-Time'] = new Date().toISOString();
|
||||
console.log('Added auth header');
|
||||
```
|
||||
|
||||
#### 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
|
||||
|
||||
### Available Objects
|
||||
|
||||
#### Response Object (Read-Only)
|
||||
|
||||
```javascript
|
||||
response.body // String: Response body
|
||||
response.headers // Object: Header key-value pairs
|
||||
response.statusCode // Number: HTTP status code (200, 404, etc.)
|
||||
response.statusText // String: Status text ("OK", "Not Found", etc.)
|
||||
response.responseTime // Number: Response time in milliseconds
|
||||
response.body // string, read-only
|
||||
response.headers // object, read-only
|
||||
response.statusCode // number
|
||||
response.statusText // string
|
||||
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.
|
||||
|
||||
#### 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
|
||||
|
||||
**Example:**
|
||||
```javascript
|
||||
const data = JSON.parse(response.body);
|
||||
roster.setVariables({
|
||||
user_id: data.user.id,
|
||||
user_name: data.user.name,
|
||||
user_email: data.user.email,
|
||||
session_id: data.session.id
|
||||
});
|
||||
console.log('Extracted user:', data.user.name);
|
||||
```
|
||||
|
||||
#### Example 3: Validate and Store Response
|
||||
|
||||
```javascript
|
||||
const data = JSON.parse(response.body);
|
||||
|
||||
if (response.statusCode === 200 && data.items) {
|
||||
roster.setVariable('item_count', data.items.length.toString());
|
||||
|
||||
if (data.items.length > 0) {
|
||||
roster.setVariable('first_item_id', data.items[0].id);
|
||||
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);
|
||||
}
|
||||
user_id: data.user_id
|
||||
});
|
||||
```
|
||||
|
||||
**Request 2: Get User Profile (GET /users/{userId})**
|
||||
## Execution Order
|
||||
|
||||
Preprocessing:
|
||||
```javascript
|
||||
// Use stored token and user ID in request
|
||||
const token = roster.getVariable('access_token');
|
||||
const userId = roster.getVariable('user_id');
|
||||
1. Preprocessing script
|
||||
2. Variable substitution (`{{variable_name}}`)
|
||||
3. HTTP request
|
||||
4. Postprocessing script
|
||||
5. Response displayed and saved to history
|
||||
|
||||
// Add authentication
|
||||
request.headers['Authorization'] = 'Bearer ' + token;
|
||||
## Limitations
|
||||
|
||||
// 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
|
||||
- Synchronous only — no `async/await`, `setTimeout`, `fetch`
|
||||
- No file system, shell, or external library access
|
||||
|
||||
## 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
|
||||
try {
|
||||
const data = JSON.parse(response.body);
|
||||
@ -397,46 +82,4 @@ try {
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **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
|
||||
See [[API-Reference]] for the full API reference.
|
||||
|
||||
@ -1,153 +1,40 @@
|
||||
# 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:
|
||||
- Firefox and GNOME Web for passwords
|
||||
- Evolution for email credentials
|
||||
- Network Manager for WiFi passwords
|
||||
- SSH for key passphrases
|
||||
Sensitive variable values display as bullets (••••) in the dialog.
|
||||
|
||||
## 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):**
|
||||
```
|
||||
File: ~/.local/share/cz.bugsy.roster/requests.json
|
||||
Format: Plain text (anyone can read)
|
||||
Content: "api_key": "secret-abc123-visible-to-all"
|
||||
## Script Access
|
||||
|
||||
Scripts access sensitive variables the same way as regular ones:
|
||||
|
||||
```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):**
|
||||
```
|
||||
File: ~/.local/share/cz.bugsy.roster/requests.json
|
||||
Format: Plain text
|
||||
Content: "api_key": "" (empty placeholder)
|
||||
## Keyring Schema
|
||||
|
||||
Keyring: GNOME Keyring (encrypted)
|
||||
Format: Encrypted with your login password
|
||||
Content: "secret-abc123-visible-to-all" (encrypted at rest)
|
||||
```
|
||||
- **Schema:** `cz.bugsy.roster.EnvironmentVariable`
|
||||
- **Attributes:** `project_id`, `environment_id`, `variable_name`
|
||||
|
||||
## Usage
|
||||
|
||||
### 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
|
||||
Secrets are visible in **Passwords and Keys** (Seahorse) under the Login keyring.
|
||||
|
||||
## 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:
|
||||
|
||||
### 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
|
||||
Requires D-Bus permission `--talk-name=org.freedesktop.secrets` in the Flatpak manifest.
|
||||
|
||||
216
Variables.md
216
Variables.md
@ -1,216 +1,48 @@
|
||||
# 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
|
||||
Headers:
|
||||
Authorization: Bearer {{api_token}}
|
||||
GET {{base_url}}/users
|
||||
Authorization: Bearer {{api_token}}
|
||||
```
|
||||
|
||||
When sent with the "Production" environment:
|
||||
```
|
||||
URL: https://api.example.com/users
|
||||
Headers:
|
||||
Authorization: Bearer prod-token-abc123
|
||||
```
|
||||
## Managing Environments and Variables
|
||||
|
||||
## Environments
|
||||
Open via **⋯ → Manage Environments** next to the project name in the sidebar.
|
||||
|
||||
Environments are collections of variable values. Common environment names:
|
||||
- **Production** - Live API credentials
|
||||
- **Staging** - Pre-production testing
|
||||
- **Development** - Local development server
|
||||
- **Add environment:** click **+** next to the environment list
|
||||
- **Add variable:** click **+** at the bottom of the variable list
|
||||
- **Delete:** click **×** on the variable row or environment header
|
||||
- **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
|
||||
2. Click the "Three-Dots" button near the project name
|
||||
3. Select **"Manage Environments"**
|
||||
Undefined variables are highlighted with a warning color; the literal `{{variable_name}}` is sent as-is.
|
||||
|
||||
### Step 2: Add Environment
|
||||
|
||||
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)
|
||||
## Script Access
|
||||
|
||||
```javascript
|
||||
const baseUrl = roster.getVariable('base_url');
|
||||
const apiKey = roster.getVariable('api_key');
|
||||
// Preprocessing
|
||||
const url = roster.getVariable('base_url');
|
||||
|
||||
console.log('Using base URL:', baseUrl);
|
||||
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);
|
||||
// Preprocessing or postprocessing
|
||||
roster.setVariable('auth_token', data.access_token);
|
||||
roster.setVariable('user_id', data.user_id);
|
||||
console.log('Saved token for user:', data.user_id);
|
||||
roster.setVariables({ token: data.token, user_id: data.id });
|
||||
```
|
||||
|
||||
### Batch Updates
|
||||
## Sensitive Variables
|
||||
|
||||
```javascript
|
||||
// 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
|
||||
});
|
||||
```
|
||||
For API keys and passwords, use [[Sensitive-Variables]] — values are stored in GNOME Keyring instead of plain-text JSON.
|
||||
|
||||
Scripts automatically update variables in the currently selected environment.
|
||||
## Storage
|
||||
|
||||
## Variable Scoping
|
||||
|
||||
**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
|
||||
Regular variables: `~/.local/share/cz.bugsy.roster/requests.json` (Flatpak: `~/.var/app/cz.bugsy.roster/data/cz.bugsy.roster/requests.json`)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user