Skip to main content

JavaScript API Reference

pink-js-engine provides a WebKit-based JavaScript runtime environment that supports five script types: Request, Response, Schedule, Generic, and Network.

All script types share a set of global APIs, while each type has its own exclusive global variables. After script execution, $done() must be called to notify the engine.


Global APIs

The following APIs are available in all script types.

$httpClient

HTTP client for making requests. Supports get, post, put, delete, head, options, patch methods, as well as a generic request method.

Convenience Methods

$httpClient.get(options, callback)
$httpClient.post(options, callback)
$httpClient.put(options, callback)
$httpClient.delete(options, callback)
$httpClient.head(options, callback)
$httpClient.options(options, callback)
$httpClient.patch(options, callback)

Generic Method

$httpClient.request(method, options, callback)
  • method — HTTP method string, e.g. "GET", "POST", etc.

Parameters

options — Can be a URL string, or an object with the following fields:

FieldTypeDescription
urlstringRequest URL (required)
headersobjectRequest header key-value pairs
bodystring | Uint8Array | objectRequest body. Objects are automatically serialized to JSON
binary-modebooleanWhen true, the response body is returned as Uint8Array
timeoutnumberTimeout in seconds
policystringProxy policy name
auto-redirectbooleanWhether to automatically follow redirects
auto-cookiebooleanWhether to automatically manage cookies

callbackfunction(error, response, data)

ParameterTypeDescription
errorError | undefinedError object on failure, undefined on success
responseobject | undefinedContains status (HTTP status code) and headers (response header object)
datastring | Uint8Array | undefinedResponse body. String by default, Uint8Array in binary-mode

Example

// Simple GET request
$httpClient.get("https://example.com/api", function(error, response, data) {
if (error) {
console.log("Request failed: " + error);
$done();
return;
}
console.log("Status code: " + response.status);
console.log("Response body: " + data);
$done();
});

// POST request with options
$httpClient.post({
url: "https://example.com/api",
headers: { "Content-Type": "application/json" },
body: { key: "value" },
timeout: 10
}, function(error, response, data) {
console.log(data);
$done();
});

// Binary mode
$httpClient.get({
url: "https://example.com/image.png",
"binary-mode": true
}, function(error, response, data) {
// data is Uint8Array
console.log("Size: " + data.length);
$done();
});

// Generic method
$httpClient.request("PATCH", {
url: "https://example.com/api/resource",
body: "updated"
}, function(error, response, data) {
$done();
});

$persistentStore

Persistent key-value storage. Data is preserved across multiple script executions.

Methods

$persistentStore.write(data, key)

Writes a string value to storage.

ParameterTypeDescription
datastringThe value to store
keystringThe storage key

Returns: booleantrue on success, false on failure.

$persistentStore.read(key)

Reads a value from storage.

ParameterTypeDescription
keystringThe storage key

Returns: string | null — The value for the key, or null if it does not exist.

Example

// Write
$persistentStore.write("hello", "greeting");

// Read
const value = $persistentStore.read("greeting");
console.log(value); // "hello"

// Check existence
if ($persistentStore.read("counter") === null) {
$persistentStore.write("0", "counter");
}

$notification

Sends system notifications.

Methods

$notification.post(title, subtitle, body, options)
ParameterTypeDescription
titlestringNotification title
subtitlestringNotification subtitle
bodystringNotification body
optionsobjectOptional, additional options

Example

$notification.post("Script Complete", "Subtitle", "Task executed successfully");

$notification.post("Warning", "", "Abnormal traffic detected", { url: "https://example.com" });

$utils

Utility function collection.

Methods

$utils.geoip(ip)

Queries the geographic country code of an IP address.

ParameterTypeDescription
ipstringIP address

Returns: string | null — ISO 3166-1 country code (e.g. "US", "CN"), or null on failure.

$utils.ipasn(ip)

Queries the Autonomous System Number (ASN) of an IP address.

ParameterTypeDescription
ipstringIP address

Returns: number | null — ASN number, or null on failure.

$utils.ipaso(ip)

Queries the Autonomous System Organization (ASO) name of an IP address.

ParameterTypeDescription
ipstringIP address

Returns: string | null — Organization name, or null on failure.

$utils.ungzip(data)

Decompresses gzip data.

ParameterTypeDescription
dataUint8ArrayGzip compressed data

Returns: Uint8Array | null — Decompressed data, or null on failure.

Example

const country = $utils.geoip("8.8.8.8");
console.log(country); // "US"

const asn = $utils.ipasn("1.1.1.1");
console.log(asn); // 13335

const aso = $utils.ipaso("1.1.1.1");
console.log(aso); // "Cloudflare, Inc."

// Decompress gzip data
const decompressed = $utils.ungzip(compressedData);

$environment

System environment information (read-only).

PropertyTypeDescription
systemstringSystem identifier, always "iOS"
languagestringSystem language

Example

console.log($environment.system);   // "iOS"
console.log($environment.language); // "zh-Hans"

$script

Current script metadata (read-only).

PropertyTypeDescription
namestringScript name
startTimenumberUnix timestamp (seconds) when the script started
typestring | undefinedScript type: "request", "response", "cron", or undefined

Example

console.log($script.name);      // "my-script"
console.log($script.startTime); // 1700000000.123
console.log($script.type); // "request"

$network

Current device network information (read-only).

$network = {
"cellular-data": {
carrier: string, // Carrier name
radio: string // Radio technology (e.g. "LTE", "5G")
},
wifi: {
ssid: string, // Wi-Fi network name
bssid: string // Wi-Fi BSSID
},
v4: {
primaryAddress: string, // IPv4 address
primaryRouter: string, // Gateway address
primaryInterface: string // Network interface name
},
v6: {
primaryAddress: string, // IPv6 address
primaryInterface: string // Network interface name
},
dns: string[] // DNS server list
}

Example

console.log($network.wifi.ssid);
console.log($network.v4.primaryAddress);
console.log($network.dns);

Egern

Egern application information (read-only).

PropertyTypeDescription
versionstringEgern version number
argumentsobjectScript configuration parameter key-value pairs

Example

console.log(Egern.version);
console.log(Egern.arguments); // { "key1": "value1", "key2": "value2" }

$argument

Surge-compatible argument (read-only). This variable does not exist when _compat.$argument is not provided in the configuration.

TypeDescription
string | undefinedArgument string passed to the script

Example

if (typeof $argument !== "undefined") {
console.log($argument);
}

console.log

Log output. Overridden to pass logs to the native logging system.

Object arguments are automatically serialized to JSON strings. Multiple arguments are supported, separated by , .

Example

console.log("hello");
console.log("status:", 200, { key: "value" });
// Output: "status:, 200, {"key":"value"}"

Script Types

Request Script

Executes before an HTTP request is sent. Can modify the request, return a response directly, or abort the request.

Exclusive Global Variables

$request — The current HTTP request object.

PropertyTypeDescription
methodstringHTTP method ("GET", "POST", etc.)
urlstringRequest URL
headersobjectRequest header key-value pairs
bodystring | Uint8Array | undefinedRequest body (requires body_required configuration)

$done(result)

Completes script execution. Performs different actions depending on the argument:

Pass through without modification:

$done({});

Modify the request:

$done({
method: "POST", // Optional, modify HTTP method
url: "https://...", // Optional, modify URL
headers: { ... }, // Optional, modify headers
body: "..." // Optional, modify body
});

Only include the fields you want to modify. Omitted fields remain unchanged.

Return a response directly (without sending the original request):

$done({
response: {
status: 200, // HTTP status code
headers: { ... }, // Response headers
body: "..." // Response body
}
});

Abort the request:

$done();

Example

// Add request header
const headers = $request.headers;
headers["X-Custom"] = "value";
$done({ headers });

// URL rewrite
if ($request.url.includes("old-api")) {
$done({ url: $request.url.replace("old-api", "new-api") });
} else {
$done({});
}

// Return a mock response directly
$done({
response: {
status: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ mock: true })
}
});

Response Script

Executes before an HTTP response is returned to the client. Can modify the response or abort the connection.

Exclusive Global Variables

$request — The original request object (read-only), same structure as $request in Request scripts.

$response — The current HTTP response object.

PropertyTypeDescription
statusnumberHTTP status code
headersobjectResponse header key-value pairs
bodystring | Uint8Array | undefinedResponse body (requires body_required configuration)

$done(result)

Pass through without modification:

$done({});

Modify the response:

$done({
status: 200, // Optional, modify status code
headers: { ... }, // Optional, modify headers
body: "..." // Optional, modify body
});

Abort the response:

$done();

Example

// Modify response body
let body = $response.body;
body = body.replace("old", "new");
$done({ body });

// Add response header
const headers = $response.headers;
headers["X-Modified"] = "true";
$done({ headers });

// Modify JSON response
const data = JSON.parse($response.body);
data.extra = "injected";
$done({ body: JSON.stringify(data) });

Schedule Script

Executes on a schedule via cron expressions.

Exclusive Global Variables

$cronexpstring, the current cron expression.

$done()

Completes script execution. No parameters.

$done();

Example

// Scheduled check with notification
$httpClient.get("https://example.com/api/status", function(error, response, data) {
if (error) {
$notification.post("Check Failed", "", error.toString());
} else {
const result = JSON.parse(data);
if (result.status !== "ok") {
$notification.post("Service Error", "", "Status: " + result.status);
}
}
$done();
});

Generic Script

General-purpose script, used for panel display and other scenarios.

Exclusive Global Variables

$input — Input information object.

PropertyTypeDescription
purposestringPurpose identifier
positionstringPosition identifier
panelNamestringPanel name (equals the script name)

$triggerstring, the trigger reason.

$done(output)

Completes script execution and returns output. output is a JSON object that can contain the following fields:

FieldTypeDescription
titlestringPanel title
contentstringPanel content
iconstringIcon name
icon-colorstringIcon color
background-colorstringBackground color
stylestringStyle

Example

// Display network info panel
const ip = $network.v4.primaryAddress;
const ssid = $network.wifi.ssid;

$done({
title: "Network Info",
content: `IP: ${ip}\nWi-Fi: ${ssid}`,
icon: "wifi",
"icon-color": "#007AFF"
});

Network Script

Executes when the device's network state changes.

Exclusive Global Variables

No exclusive variables. Use $network to get current network information.

$done()

Completes script execution. No parameters.

$done();

Example

// Log on network change
const ssid = $network.wifi.ssid;
const ip = $network.v4.primaryAddress;
console.log("Network changed - SSID: " + ssid + ", IP: " + ip);

$persistentStore.write(ssid, "last_ssid");
$done();

Error Handling

The runtime automatically catches unhandled exceptions and Promise rejections, and calls $done({}) (pass through without modifying request/response). It is recommended to handle errors in your scripts for predictable behavior.

try {
// Script logic
} catch (e) {
console.log("Error: " + e.message);
$done({});
}

Notes

  • $done() must be called: Every script must call $done() once to finish execution. Failure to call it will cause the script to time out.
  • $done() can only be called once: Repeated calls are ignored.
  • Request/Response body: The body is only available when the script is configured with body_required: true. Binary bodies are provided as Uint8Array.
  • Timeout: Scripts have an execution timeout limit. The engine will forcefully terminate the script after timeout.