Configuration file reference for fastedge-config.test.json — the per-test JSON file that defines the WASM binary, request, CDN properties, and environment variable loading for a single test scenario.
Each test scenario is described by a fastedge-config.test.json file. The file is validated against a JSON Schema at load time. The test runner (and loadConfigFile) applies Zod defaults at runtime, so fields with defaults do not need to be present in the file — but editors validating against the $schema URI will flag missing required fields unless you supply them explicitly.
The config schema is a union of two variants selected by appType:
proxy-wasm(CDN mode, default): The WASM module intercepts an upstream HTTP request. Usesrequest.url(full URL). The upstream response is generated at runtime — either by a real fetch againstrequest.url, or by the built-in responder whenrequest.url === "built-in".http-wasm: The WASM module acts as an origin HTTP server. Usesrequest.path(path only).
Required fields (per JSON Schema required arrays):
- Top-level:
properties,appType, andrequest - Within
request(CDN):method,url,headers,body - Within
request(HTTP-WASM):method,path,headers,body
Runtime defaults: The Zod runtime fills in appType ("proxy-wasm" for CDN), method, headers, body, and properties if absent, so those fields are optional in practice. The JSON Schema marks them required because it cannot express Zod's default-filling behaviour. Supplying explicit values avoids editor warnings. For HTTP-WASM configs, appType: "http-wasm" has no runtime default and must be specified.
| JSON Path | Type | Required (Schema) | Default | Description |
|---|---|---|---|---|
$schema |
string |
No | — | URI pointing to the JSON Schema file for IDE autocompletion and validation. |
description |
string |
No | — | Human-readable label for this test scenario. |
wasm |
object |
No | — | WASM binary configuration. Required when running without a programmatic wasmBuffer. |
wasm.path |
string |
Yes (if wasm present) |
— | Path to the compiled .wasm binary, relative to the config file or absolute. |
wasm.description |
string |
No | — | Human-readable label for the WASM binary. |
appType |
string |
Yes (schema) / CDN has runtime default | "proxy-wasm" |
App variant. "proxy-wasm" for CDN mode; "http-wasm" for HTTP mode. HTTP-WASM has no default. |
request |
object |
Yes | — | Incoming HTTP request to simulate. |
request.method |
string |
Yes (schema) / runtime default | "GET" |
HTTP method (e.g. "GET", "POST"). |
request.url |
string |
Yes (CDN only) | — | Full URL for the simulated upstream request (e.g. "https://example.com/api"). CDN mode only. |
request.path |
string |
Yes (HTTP-WASM only) | — | Request path (e.g. "/api/submit"). HTTP-WASM mode only. The WASM module acts as the origin server. |
request.headers |
object |
Yes (schema) / runtime default | {} |
Key/value map of request headers. All keys and values must be strings. |
request.body |
string |
Yes (schema) / runtime default | "" |
Request body as a plain string. Use an empty string for requests with no body. |
properties |
object |
Yes (schema) / runtime default | {} |
CDN property key/value pairs passed to the WASM execution context. Values may be any JSON type. |
dotenv |
object |
No | — | Dotenv file loading configuration. |
dotenv.enabled |
boolean |
No | — | Whether to load a .env file before execution. |
dotenv.path |
string |
No | — | Path to the .env file. If omitted, resolves .env relative to the config file directory. |
httpPort |
integer |
No | — | HTTP-WASM only. Pin the subprocess to a specific port (1024–65535) instead of dynamic allocation from the 8100–8199 pool. Throws if the port is busy. |
The JSON Schema's required arrays drive editor validation. Fields like appType, request.method, request.headers, request.body, and properties appear in the schema's required array, so a strict JSON Schema validator will flag them as missing. At runtime, the Zod schema fills in their defaults ("proxy-wasm", "GET", {}, "", and {} respectively), so the test runner accepts configs that omit them — with the exception of appType: "http-wasm", which has no Zod default and must always be specified for HTTP-WASM configs.
To avoid editor warnings while keeping configs concise, either supply the fields explicitly or add the $schema field and accept that your editor may warn on omission.
When dotenv.enabled is true, the runner loads a .env file and merges its contents into process.env before executing the WASM binary. This allows secrets and environment-specific values to be injected without embedding them in the config file.
File resolution order:
- If
dotenv.pathis set, that path is used (relative to the directory containing the config file, or absolute). - If
dotenv.pathis omitted,.envis resolved relative to the directory containing the config file.
CDN mode: Properties passed to the WASM context come from the properties field in the config. Dotenv variables are available to the Node.js host process but are not automatically injected as CDN properties. To expose a .env value as a CDN property, reference process.env.VAR_NAME programmatically when constructing the runner config.
HTTP-WASM mode: Dotenv loading works the same way. The WASM module receives the simulated HTTP request; host environment variables are available to any host-side logic but are not part of the WASM execution context directly.
Security note: Do not commit .env files containing secrets. Add .env to .gitignore and use dotenv.enabled: true with dotenv.path pointing to a file that exists only in the local or CI environment.
httpPort is an optional integer field available only in HTTP-WASM configs (appType: "http-wasm"). It pins the fastedge-run subprocess to a fixed port instead of dynamically allocating one from the pool (8100–8199). The schema rejects httpPort on proxy-wasm configs.
Without httpPort, the runner allocates a port from the 8100–8199 range for each test run. The allocated port is not stable across runs.
- Codespaces / Docker port-forwarding: Port-forward rules reference a specific port number. Without pinning, the port changes between runs and breaks the forwarding rule.
- Stable live-preview URLs: Browser tabs or external tooling pointing at a fixed URL (e.g.
http://localhost:8250) require a stable port. - External tooling integration: Monitoring, load testing, or proxy configurations that hard-code a target address.
If the pinned port is already in use, HttpWasmRunner.load() throws immediately:
fastedge-run port 8250 is not available — release it or choose a different httpPort in fastedge-config.test.json
There is no fallback to dynamic allocation. Free the port or choose a different one before running.
Pinning a port inside the 8100–8199 dynamic pool is allowed by the schema but risks collisions with other concurrent debug sessions using dynamic allocation. For production-like setups or shared environments, choose a port outside the pool (e.g. 8250 or any unused port above 8199).
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json",
"description": "HTTP-WASM handler with pinned port for Codespaces",
"appType": "http-wasm",
"wasm": {
"path": "./dist/http-handler.wasm"
},
"request": {
"method": "GET",
"path": "/health",
"headers": {},
"body": ""
},
"properties": {},
"httpPort": 8250
}The smallest valid config. appType, request, and properties are required by the schema; appType and the request sub-fields method, headers, and body have runtime defaults and can be omitted in practice, but are included here for schema compliance.
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json",
"appType": "proxy-wasm",
"wasm": {
"path": "./dist/handler.wasm"
},
"request": {
"method": "GET",
"url": "https://example.com/",
"headers": {},
"body": ""
},
"properties": {}
}A CDN scenario that passes property values to the WASM context and loads secrets from a .env file.
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json",
"description": "CDN handler with feature flags and auth secret",
"appType": "proxy-wasm",
"wasm": {
"path": "./dist/handler.wasm",
"description": "Production CDN handler"
},
"request": {
"method": "GET",
"url": "https://example.com/api/data",
"headers": {
"accept": "application/json",
"x-request-id": "test-001"
},
"body": ""
},
"properties": {
"FEATURE_FLAG_NEW_CACHE": "true",
"UPSTREAM_HOST": "origin.example.com",
"MAX_AGE": 3600
},
"dotenv": {
"enabled": true,
"path": "./.env.test"
}
}Corresponding .env.test:
API_SECRET=supersecret
DEBUG_MODE=false
An HTTP-WASM scenario simulating a POST request with a JSON body. appType must be "http-wasm" — there is no runtime default for this variant. Use request.path (not request.url); the WASM module acts as the origin server and receives only the path portion of the request.
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json",
"description": "HTTP-WASM POST handler",
"appType": "http-wasm",
"wasm": {
"path": "./dist/http-handler.wasm"
},
"request": {
"method": "POST",
"path": "/submit",
"headers": {
"content-type": "application/json",
"authorization": "Bearer test-token"
},
"body": "{\"key\": \"value\"}"
},
"properties": {}
}A CDN scenario that uses the test runner's built-in responder instead of reaching out to a real origin. Set request.url to "built-in" — the runner generates a local response and skips the upstream fetch. This is the fastest way to exercise a CDN WASM app without depending on network reachability.
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json",
"description": "CDN handler against the built-in responder",
"appType": "proxy-wasm",
"wasm": {
"path": "./dist/handler.wasm"
},
"request": {
"method": "GET",
"url": "built-in",
"headers": {},
"body": ""
},
"properties": {
"CACHE_TTL": 86400
}
}The default built-in response is a full JSON echo of the request. Override via control headers on the request: x-debugger-status sets the HTTP status; x-debugger-content: status-only omits the body; x-debugger-content: body-only echoes only the request body (with its inferred content-type).
Adding $schema to your config file enables JSON Schema validation and autocompletion in VSCode and any editor that supports the JSON Language Server.
{
"$schema": "./node_modules/@gcoredev/fastedge-test/schemas/fastedge-config.test.schema.json"
}The schema file is included in the published package at schemas/fastedge-config.test.schema.json. The path in $schema should be relative to the config file's location.
VSCode: No additional extensions are needed. The built-in JSON language server resolves $schema automatically. You will get:
- Field name autocompletion
- Type validation (e.g. strings vs. objects)
- Inline documentation on hover
- Errors for unrecognised fields (
additionalProperties: falseis set at every object level)
Other editors: Any editor using the JSON Language Server (Neovim via nvim-lspconfig, IntelliJ IDEA, etc.) will also pick up the schema from the $schema field without additional configuration.
To load and validate a config file at runtime in a test script:
import { loadConfigFile } from "@gcoredev/fastedge-test/test";
import type { TestConfig } from "@gcoredev/fastedge-test/test";
const config: TestConfig = await loadConfigFile("./fastedge-config.test.json");
console.log(config.appType); // "proxy-wasm" | "http-wasm"
console.log(config.properties); // Record<string, unknown>
console.log(config.wasm?.path); // string | undefinedloadConfigFile reads the file, parses JSON, and validates it through the Zod schema (applying defaults). It throws a descriptive Error if the file cannot be read, is not valid JSON, or fails schema validation.
The returned TestConfig type is a union discriminated by appType:
type TestConfig = CdnConfig | HttpConfig;
type CdnConfig = {
$schema?: string;
description?: string;
appType: "proxy-wasm"; // default applied at runtime
wasm?: {
path: string;
description?: string;
};
request: {
method: string; // default: "GET"
url: string;
headers: Record<string, string>; // default: {}
body: string; // default: ""
};
properties: Record<string, unknown>; // default: {}
dotenv?: {
enabled?: boolean;
path?: string;
};
};
type HttpConfig = {
$schema?: string;
description?: string;
appType: "http-wasm"; // no default — must be specified
wasm?: {
path: string;
description?: string;
};
request: {
method: string; // default: "GET"
path: string;
headers: Record<string, string>; // default: {}
body: string; // default: ""
};
httpPort?: number; // pin subprocess port (1024–65535); throws if busy
properties: Record<string, unknown>; // default: {}
dotenv?: {
enabled?: boolean;
path?: string;
};
};Use appType to narrow the union before accessing variant-specific fields:
import { loadConfigFile } from "@gcoredev/fastedge-test/test";
const config = await loadConfigFile("./fastedge-config.test.json");
if (config.appType === "proxy-wasm") {
console.log(config.request.url); // string — CDN full URL
} else {
console.log(config.request.path); // string — HTTP-WASM path
console.log(config.httpPort); // number | undefined
}- TEST_FRAMEWORK.md — using
loadConfigFilein test suites,runFlow, and the full test framework API - API.md —
GET /api/configandPOST /api/configREST endpoints for reading and writing config at runtime - RUNNER.md — runner configuration and WASM execution options