Extension API
WarpDL extensions are JavaScript modules executed using the Goja runtime. Extensions transform URLs before downloads begin, enabling support for custom hosting services and URL schemes.
Extension Structure
Section titled “Extension Structure”Every extension requires two files:
- manifest.json - Extension metadata
- main.js (or custom entrypoint) - JavaScript code with
extract()function
Directory Layout
Section titled “Directory Layout”~/.config/warpdl/extstore/└── <extension-hash>/ ├── manifest.json └── main.jsmanifest.json
Section titled “manifest.json”The manifest defines extension metadata and URL matching patterns.
Schema
Section titled “Schema”{ "name": "my-extension", "version": "1.0.0", "matches": ["^https://example\\.com/.*"], "description": "Transform example.com URLs", "entrypoint": "main.js"}Fields
Section titled “Fields”| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | Extension display name |
version | Yes | string | Semantic version (e.g., “1.0.0”) |
matches | Yes | string[] | Array of regex patterns for URL matching |
description | No | string | Human-readable description |
entrypoint | No | string | Main JavaScript file (default: “main.js”) |
assets | No | string[] | Additional files to include (e.g., helper scripts) |
URL Matching
Section titled “URL Matching”The matches field contains JavaScript regex patterns. WarpDL tests each pattern against download URLs using RegExp.MatchString().
{ "matches": [ "^https://drive\\.google\\.com/.*", "^https://.*\\.googleapis\\.com/.*" ]}JavaScript API
Section titled “JavaScript API”Required Function: extract()
Section titled “Required Function: extract()”Every extension must define an extract(url) function. This is the only entry point WarpDL calls.
function extract(url) { // Transform the URL and return the direct download link return transformedUrl;}Parameters:
url(string): The original URL to transform
Returns:
string: Transformed URL for downloading- Return
"end"to signal interaction failure/cancellation
Example:
function extract(url) { // Force HTTPS if (url.startsWith("http://")) { return url.replace("http://", "https://"); }
// Extract direct link from hosting service let match = url.match(/example\.com\/file\/(\w+)/); if (match) { return "https://cdn.example.com/dl/" + match[1]; }
return url;}Built-in Functions
Section titled “Built-in Functions”WarpDL provides several built-in functions for extensions:
print(…args)
Section titled “print(…args)”Print values to stdout (for debugging).
print("Processing URL:", url);print("Match found:", fileId);input(prompt, [callback])
Section titled “input(prompt, [callback])”Read user input from stdin. Optionally process input with a callback function.
// Simple inputlet choice = input("Select quality (1-3): ");
// With callbackinput("Enter filename: ", function(filename) { print("You entered:", filename); return filename;});require(modulePath)
Section titled “require(modulePath)”Import additional JavaScript modules from the extension directory.
// Import helper.js from extension directorylet helper = require("./helper.js");Note: Modules use CommonJS format (module.exports).
request(options)
Section titled “request(options)”Make HTTP requests (limited to 1MB response size).
let response = request({ method: "GET", url: "https://api.example.com/file-info", headers: { "User-Agent": "WarpDL Extension", "Authorization": "Bearer token" }, body: "" // Optional request body});
print("Status:", response.status_code);print("Body:", response.body);print("Content-Length:", response.content_length);
// Access response headerslet contentType = response.headers.get("Content-Type");Request Options:
method(string): HTTP method (GET, POST, etc.)url(string): Request URLheaders(object): Request headers (key-value pairs)body(string): Request body
Response Object:
status_code(number): HTTP status codebody(string): Response body (max 1MB)content_length(number): Content-Length header valueheaders(Headers): Response headers object
Headers Object Methods:
get(name)- Get header valuehas(name)- Check if header existsset(name, value)- Set header valueappend(name, value)- Append to header valuedelete(name)- Remove headerkeys()- Get all header namesvalues()- Get all header valuesentries()- Get [name, value] pairsforEach(callback)- Iterate over headersgetSetCookies()- Get Set-Cookie header values
Complete Example
Section titled “Complete Example”This extension transforms Google Drive sharing URLs into direct download links:
manifest.json:
{ "name": "gdrive-extractor", "version": "1.0.0", "matches": ["^https://drive\\.google\\.com/file/d/.*"], "description": "Extract direct download links from Google Drive"}main.js:
function extract(url) { // Extract file ID from sharing URL let match = url.match(/\/file\/d\/([a-zA-Z0-9_-]+)/);
if (!match) { print("Error: Invalid Google Drive URL"); return "end"; // Signal failure }
let fileId = match[1];
// Construct direct download URL let directUrl = "https://drive.google.com/uc?export=download&id=" + fileId;
print("Extracted file ID:", fileId); return directUrl;}Extension Management
Section titled “Extension Management”Install Extension
Section titled “Install Extension”warpdl ext install /path/to/extension/List Extensions
Section titled “List Extensions”# Show active extensions onlywarpdl ext list
# Show all extensions (including inactive)warpdl ext list --allActivate/Deactivate
Section titled “Activate/Deactivate”warpdl ext activate <extension-id>warpdl ext deactivate <extension-id>Uninstall
Section titled “Uninstall”warpdl ext uninstall <extension-id>Limitations
Section titled “Limitations”- Execution: Synchronous only (no async/await, Promises)
- Network: HTTP requests limited to 1MB response size
- File System: No direct file system access (use
require()for local modules) - Isolation: Each extension runs in a separate JavaScript runtime
- URL Transformation: Extensions can only transform URLs via
extract()- no download hooks or progress callbacks
Error Handling
Section titled “Error Handling”If extract() returns "end", WarpDL treats it as an interaction failure and stops processing:
function extract(url) { let apiResponse = request({ method: "GET", url: "https://api.example.com/resolve?url=" + url });
if (apiResponse.status_code !== 200) { print("API error:", apiResponse.status_code); return "end"; // Stop processing }
return apiResponse.body;}Throwing errors or runtime exceptions will also terminate extension execution and display the error to the user.