Skip to content

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.

Every extension requires two files:

  1. manifest.json - Extension metadata
  2. main.js (or custom entrypoint) - JavaScript code with extract() function
~/.config/warpdl/extstore/
└── <extension-hash>/
├── manifest.json
└── main.js

The manifest defines extension metadata and URL matching patterns.

{
"name": "my-extension",
"version": "1.0.0",
"matches": ["^https://example\\.com/.*"],
"description": "Transform example.com URLs",
"entrypoint": "main.js"
}
FieldRequiredTypeDescription
nameYesstringExtension display name
versionYesstringSemantic version (e.g., “1.0.0”)
matchesYesstring[]Array of regex patterns for URL matching
descriptionNostringHuman-readable description
entrypointNostringMain JavaScript file (default: “main.js”)
assetsNostring[]Additional files to include (e.g., helper scripts)

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/.*"
]
}

Every extension must define an extract(url) function. This is the only entry point WarpDL calls.

main.js
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;
}

WarpDL provides several built-in functions for extensions:

Print values to stdout (for debugging).

print("Processing URL:", url);
print("Match found:", fileId);

Read user input from stdin. Optionally process input with a callback function.

// Simple input
let choice = input("Select quality (1-3): ");
// With callback
input("Enter filename: ", function(filename) {
print("You entered:", filename);
return filename;
});

Import additional JavaScript modules from the extension directory.

// Import helper.js from extension directory
let helper = require("./helper.js");

Note: Modules use CommonJS format (module.exports).

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 headers
let contentType = response.headers.get("Content-Type");

Request Options:

  • method (string): HTTP method (GET, POST, etc.)
  • url (string): Request URL
  • headers (object): Request headers (key-value pairs)
  • body (string): Request body

Response Object:

  • status_code (number): HTTP status code
  • body (string): Response body (max 1MB)
  • content_length (number): Content-Length header value
  • headers (Headers): Response headers object

Headers Object Methods:

  • get(name) - Get header value
  • has(name) - Check if header exists
  • set(name, value) - Set header value
  • append(name, value) - Append to header value
  • delete(name) - Remove header
  • keys() - Get all header names
  • values() - Get all header values
  • entries() - Get [name, value] pairs
  • forEach(callback) - Iterate over headers
  • getSetCookies() - Get Set-Cookie header values

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;
}
Terminal window
warpdl ext install /path/to/extension/
Terminal window
# Show active extensions only
warpdl ext list
# Show all extensions (including inactive)
warpdl ext list --all
Terminal window
warpdl ext activate <extension-id>
warpdl ext deactivate <extension-id>
Terminal window
warpdl ext uninstall <extension-id>
  • 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

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.