@gcoredev/fastedge-test 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/API.md CHANGED
@@ -10,7 +10,7 @@ The `@gcoredev/fastedge-test` debugger server exposes a REST API for loading WAS
10
10
  http://localhost:5179
11
11
  ```
12
12
 
13
- The port can be overridden via the `PORT` environment variable. When `WORKSPACE_PATH` is set, the active port is written to `$WORKSPACE_PATH/.fastedge-debug/.debug-port` on startup and deleted on shutdown.
13
+ The port can be overridden via the `PORT` environment variable. The active port is written to `.fastedge-debug/.debug-port` (relative to `WORKSPACE_PATH` if set, otherwise the current working directory) on startup and deleted on shutdown.
14
14
 
15
15
  ## Common Headers
16
16
 
@@ -18,12 +18,12 @@ The port can be overridden via the `PORT` environment variable. When `WORKSPACE_
18
18
 
19
19
  The `POST /api/execute`, `POST /api/send`, and `POST /api/config` endpoints accept an optional `X-Source` request header that tags the origin of the operation in WebSocket broadcast events.
20
20
 
21
- | Value | Description |
22
- | ---------- | ------------------------------------------------------- |
23
- | `ui` | Request originated from the web UI (default if omitted) |
24
- | `ai_agent` | Request originated from an AI agent |
25
- | `api` | Request originated from direct API usage |
26
- | `system` | Request originated from an automated system |
21
+ | Value | Description |
22
+ | ------------ | ------------------------------------------------------- |
23
+ | `ui` | Request originated from the web UI (default if omitted) |
24
+ | `ai_agent` | Request originated from an AI agent |
25
+ | `api` | Request originated from direct API usage |
26
+ | `system` | Request originated from an automated system |
27
27
 
28
28
  ```http
29
29
  X-Source: ai_agent
@@ -179,11 +179,11 @@ curl -X POST http://localhost:5179/api/load \
179
179
 
180
180
  **Error Responses**
181
181
 
182
- | Status | Condition |
183
- | ------ | ----------------------------------------------------------------------------------------------------------- |
184
- | `400` | Validation failed, missing both `wasmPath` and `wasmBase64`, invalid path, or path does not end in `.wasm` |
185
- | `400` | `httpPort` is specified and already in use (HTTP-WASM only) |
186
- | `500` | WASM load failed or runner initialization error |
182
+ | Status | Condition |
183
+ | ------ | ------------------------------------------------------------------------------------------------------------ |
184
+ | `400` | Validation failed, missing both `wasmPath` and `wasmBase64`, invalid path, or path does not end in `.wasm` |
185
+ | `400` | `httpPort` is specified and already in use (HTTP-WASM only) |
186
+ | `500` | WASM load failed or runner initialization error |
187
187
 
188
188
  ---
189
189
 
@@ -328,7 +328,7 @@ type HookResult = {
328
328
  };
329
329
  ```
330
330
 
331
- `hookResults` is keyed by hook name (e.g. `"onRequestHeaders"`, `"onResponseHeaders"`). `calculatedProperties` is present only when the runner derives request-derived properties; keys follow the `request.*` pattern (e.g. `request.url`, `request.host`, `request.path`, `request.query`, `request.scheme`, `request.extension`, `request.method`).
331
+ `hookResults` is keyed by hook name (e.g. `"onRequestHeaders"`, `"onResponseHeaders"`). `calculatedProperties` is present only when the runner derives request-derived properties; keys follow the `request.*` pattern (`request.url`, `request.host`, `request.path`, `request.query`, `request.scheme`, `request.extension`, `request.method`).
332
332
 
333
333
  **Example — HTTP-WASM**
334
334
 
@@ -417,10 +417,10 @@ curl -X POST http://localhost:5179/api/execute \
417
417
 
418
418
  **Error Responses**
419
419
 
420
- | Status | Condition |
421
- | ------ | ---------------------------------------------------------------------------------------------- |
422
- | `400` | No WASM module loaded, or missing `path`/`url` for HTTP-WASM, or missing `url` for Proxy-WASM |
423
- | `500` | Execution failed |
420
+ | Status | Condition |
421
+ | ------ | ----------------------------------------------------------------------------------------------- |
422
+ | `400` | No WASM module loaded, or missing `path`/`url` for HTTP-WASM, or missing `url` for Proxy-WASM |
423
+ | `500` | Execution failed |
424
424
 
425
425
  ---
426
426
 
@@ -529,10 +529,10 @@ curl -X POST http://localhost:5179/api/call \
529
529
 
530
530
  **Error Responses**
531
531
 
532
- | Status | Condition |
533
- | ------ | -------------------------------------------------------------------------------------- |
534
- | `400` | Validation failed (invalid hook name, missing `properties`), or no WASM module loaded |
535
- | `500` | Hook execution failed |
532
+ | Status | Condition |
533
+ | ------ | --------------------------------------------------------------------------------------- |
534
+ | `400` | Validation failed (invalid hook name, missing `properties`), or no WASM module loaded |
535
+ | `500` | Hook execution failed |
536
536
 
537
537
  ---
538
538
 
@@ -652,10 +652,10 @@ curl -X POST http://localhost:5179/api/send \
652
652
 
653
653
  **Error Responses**
654
654
 
655
- | Status | Condition |
656
- | ------ | ---------------------------------------------------------------------------- |
657
- | `400` | Validation failed (missing `url` or `properties`), or no WASM module loaded |
658
- | `500` | Execution failed |
655
+ | Status | Condition |
656
+ | ------ | ----------------------------------------------------------------------------- |
657
+ | `400` | Validation failed (missing `url` or `properties`), or no WASM module loaded |
658
+ | `500` | Execution failed |
659
659
 
660
660
  ---
661
661
 
@@ -663,7 +663,7 @@ curl -X POST http://localhost:5179/api/send \
663
663
 
664
664
  ### GET /api/config
665
665
 
666
- Reads the `fastedge-config.test.json` file from the project root and returns it along with a validation result.
666
+ Reads `fastedge-config.test.json` from the `.fastedge-debug/` directory (relative to `WORKSPACE_PATH` if set, otherwise the current working directory) and returns it along with a validation result.
667
667
 
668
668
  **Response**
669
669
 
@@ -744,15 +744,15 @@ curl http://localhost:5179/api/config
744
744
 
745
745
  **Error Responses**
746
746
 
747
- | Status | Condition |
748
- | ------ | ------------------------------------------ |
749
- | `404` | `fastedge-config.test.json` does not exist |
747
+ | Status | Condition |
748
+ | ------ | ------------------------------------------- |
749
+ | `404` | `fastedge-config.test.json` does not exist |
750
750
 
751
751
  ---
752
752
 
753
753
  ### POST /api/config
754
754
 
755
- Saves the provided configuration object to `fastedge-config.test.json` in the project root. If the config includes a `properties` field, a WebSocket event is broadcast to connected clients.
755
+ Saves the provided configuration to `.fastedge-debug/fastedge-config.test.json` (relative to `WORKSPACE_PATH` if set, otherwise the current working directory). If the config includes a `properties` field, a WebSocket event is broadcast to connected clients.
756
756
 
757
757
  Accepts an optional [`X-Source`](#x-source-header) request header.
758
758
 
@@ -805,10 +805,10 @@ curl -X POST http://localhost:5179/api/config \
805
805
 
806
806
  **Error Responses**
807
807
 
808
- | Status | Condition |
809
- | ------ | --------------------------------------------------------------------------------------- |
810
- | `400` | Validation failed (missing `config.appType`, `config.request`, or `config.properties`) |
811
- | `500` | File write failed |
808
+ | Status | Condition |
809
+ | ------ | ---------------------------------------------------------------------------------------- |
810
+ | `400` | Validation failed (missing `config.appType`, `config.request`, or `config.properties`) |
811
+ | `500` | File write failed |
812
812
 
813
813
  ---
814
814
 
@@ -863,10 +863,10 @@ curl -X POST http://localhost:5179/api/config/save-as \
863
863
 
864
864
  **Error Responses**
865
865
 
866
- | Status | Condition |
867
- | ------ | --------------------------------------- |
868
- | `400` | Missing `config` or `filePath` |
869
- | `500` | File write or directory creation failed |
866
+ | Status | Condition |
867
+ | ------ | ---------------------------------------- |
868
+ | `400` | Missing `config` or `filePath` |
869
+ | `500` | File write or directory creation failed |
870
870
 
871
871
  ---
872
872
 
@@ -886,23 +886,23 @@ Returns the JSON Schema document with `Content-Type: application/json`.
886
886
 
887
887
  #### Request Schemas
888
888
 
889
- | Name | Description |
890
- | ------------ | ------------------------------------------ |
891
- | `api-load` | Request body schema for `POST /api/load` |
892
- | `api-send` | Request body schema for `POST /api/send` |
893
- | `api-call` | Request body schema for `POST /api/call` |
894
- | `api-config` | Request body schema for `POST /api/config` |
889
+ | Name | Description |
890
+ | -------------- | ------------------------------------------- |
891
+ | `api-load` | Request body schema for `POST /api/load` |
892
+ | `api-send` | Request body schema for `POST /api/send` |
893
+ | `api-call` | Request body schema for `POST /api/call` |
894
+ | `api-config` | Request body schema for `POST /api/config` |
895
895
 
896
896
  #### Response / Type Schemas
897
897
 
898
- | Name | Description |
899
- | ---------------------- | ------------------------------------------------------------- |
900
- | `fastedge-config.test` | Schema for `fastedge-config.test.json` config files |
901
- | `hook-result` | Shape of a single `HookResult` object |
902
- | `hook-call` | Shape of a `HookCall` input object |
903
- | `full-flow-result` | Shape of the `FullFlowResult` returned by full-flow endpoints |
904
- | `http-request` | Shape of an `HttpRequest` for HTTP-WASM execution |
905
- | `http-response` | Shape of an `HttpResponse` returned by HTTP-WASM execution |
898
+ | Name | Description |
899
+ | ----------------------- | -------------------------------------------------------------- |
900
+ | `fastedge-config.test` | Schema for `fastedge-config.test.json` config files |
901
+ | `hook-result` | Shape of a single `HookResult` object |
902
+ | `hook-call` | Shape of a `HookCall` input object |
903
+ | `full-flow-result` | Shape of the `FullFlowResult` returned by full-flow endpoints |
904
+ | `http-request` | Shape of an `HttpRequest` for HTTP-WASM execution |
905
+ | `http-response` | Shape of an `HttpResponse` returned by HTTP-WASM execution |
906
906
 
907
907
  **Example**
908
908
 
@@ -932,9 +932,9 @@ curl http://localhost:5179/api/schema/fastedge-config.test
932
932
 
933
933
  **Error Responses**
934
934
 
935
- | Status | Condition |
936
- | ------ | --------------------- |
937
- | `404` | Schema name not found |
935
+ | Status | Condition |
936
+ | ------ | ---------------------- |
937
+ | `404` | Schema name not found |
938
938
 
939
939
  ---
940
940
 
@@ -953,11 +953,11 @@ When a request body fails schema validation (Zod), `error` is the flattened Zod
953
953
 
954
954
  **Common status codes**
955
955
 
956
- | Status | Meaning |
957
- | ------ | --------------------------------------------------------------------------------------------- |
958
- | `400` | Invalid request body, missing required fields, or precondition not met (e.g. no WASM loaded) |
959
- | `404` | Resource not found (config file, schema file) |
960
- | `500` | Internal server error during execution or I/O |
956
+ | Status | Meaning |
957
+ | ------ | ---------------------------------------------------------------------------------------------- |
958
+ | `400` | Invalid request body, missing required fields, or precondition not met (e.g. no WASM loaded) |
959
+ | `404` | Resource not found (config file, schema file) |
960
+ | `500` | Internal server error during execution or I/O |
961
961
 
962
962
  ---
963
963
 
package/docs/DEBUGGER.md CHANGED
@@ -98,12 +98,13 @@ curl http://localhost:5179/health
98
98
 
99
99
  ## Environment Variables
100
100
 
101
- | Variable | Type | Default | Description |
102
- | -------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------- |
103
- | `PORT` | `number` | unset | Port the HTTP server listens on. Defaults to `5179` when not set. |
104
- | `PROXY_RUNNER_DEBUG` | `"1"` | unset | Enable verbose debug logging for WebSocket and runner activity. |
105
- | `WORKSPACE_PATH` | `string` | unset | Absolute path to the workspace root; used as the `.env` file base and for port file placement. |
106
- | `FASTEDGE_RUN_PATH` | `string` | unset | Override the path to the `fastedge-run` CLI binary used to execute WASM modules. |
101
+ | Variable | Type | Default | Description |
102
+ | -------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------ |
103
+ | `PORT` | `number` | unset | Port the HTTP server listens on. Defaults to `5179` when not set. |
104
+ | `PROXY_RUNNER_DEBUG` | `"1"` | unset | Enable verbose debug logging for WebSocket and runner activity. |
105
+ | `VSCODE_INTEGRATION` | `"true"` | unset | Set to `"true"` when running inside the VSCode extension; enables workspace WASM detection. |
106
+ | `WORKSPACE_PATH` | `string` | unset | Absolute path to the workspace root; used as the `.env` file base and for port file placement. |
107
+ | `FASTEDGE_RUN_PATH` | `string` | unset | Override the path to the `fastedge-run` CLI binary used to execute WASM modules. |
107
108
 
108
109
  ### Usage examples
109
110
 
package/docs/RUNNER.md CHANGED
@@ -197,7 +197,7 @@ callFullFlow(
197
197
 
198
198
  | Parameter | Type | Description |
199
199
  | -------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
200
- | `url` | `string` | Full request URL, or `BUILTIN_SHORTHAND` (`"built-in"`) to use the built-in responder instead of a real origin fetch |
200
+ | `url` | `string` | Full request URL, or `BUILTIN_SHORTHAND` (`"built-in"`) to use the built-in responder instead of a real origin fetch |
201
201
  | `method` | `string` | HTTP method |
202
202
  | `headers` | `Record<string, string>` | Request headers |
203
203
  | `body` | `string` | Request body |
@@ -208,7 +208,7 @@ The upstream response is generated at runtime — either by a real HTTP fetch ag
208
208
 
209
209
  Hook execution order: `onRequestHeaders` → `onRequestBody` → *(real HTTP fetch or built-in responder)* → `onResponseHeaders` → `onResponseBody`.
210
210
 
211
- **Local response short-circuit.** If a WASM module calls `proxy_send_local_response` during `onRequestHeaders` or `onRequestBody` and returns `StopIteration` (return code `1`), the remaining hooks and origin fetch are skipped. The `finalResponse` in the result is built from the locally-sent status, headers, and body — matching CDN production behavior. This is how redirect modules (e.g., geo-redirect) and early error responses work.
211
+ **Local response short-circuit.** If a WASM module calls `proxy_send_local_response` in any hook and returns `StopIteration` (return code `1`), the runner short-circuits immediately. For request-phase hooks (`onRequestHeaders`, `onRequestBody`), this skips the remaining request hooks, the origin fetch, and all response hooks. For response-phase hooks (`onResponseHeaders`, `onResponseBody`), this skips any remaining response hooks. In all cases, `finalResponse` is built from the locally-sent status, headers, and body — matching CDN production behavior. This is how redirect modules (e.g., geo-redirect) and early error responses work.
212
212
 
213
213
  Only available on `ProxyWasmRunner`. Calling on `HttpWasmRunner` throws.
214
214
 
@@ -311,10 +311,10 @@ const result: FullFlowResult = await runner.callFullFlow(
311
311
 
312
312
  **Built-in responder behavior** — controlled by request headers set before the origin phase:
313
313
 
314
- | Header | Effect |
315
- | -------------------- | -------------------------------------------------------------------------------- |
316
- | `x-debugger-status` | HTTP status code for the generated response (default: `200`) |
317
- | `x-debugger-content` | Response body mode: `"body-only"`, `"status-only"`, or full JSON echo (default) |
314
+ | Header | Effect |
315
+ | -------------------- | ------------------------------------------------------------------------------- |
316
+ | `x-debugger-status` | HTTP status code for the generated response (default: `200`) |
317
+ | `x-debugger-content` | Response body mode: `"body-only"`, `"status-only"`, or full JSON echo (default) |
318
318
 
319
319
  When `x-debugger-content` is omitted, the built-in responder returns a JSON echo of the request method, headers, body, and URL. Both control headers are stripped before response hooks execute so they do not appear in hook input state.
320
320
 
@@ -336,12 +336,12 @@ interface RunnerConfig {
336
336
  }
337
337
  ```
338
338
 
339
- | Field | Type | Default | Description |
340
- | -------------------------------- | ---------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
341
- | `dotenv.enabled` | `boolean` | `false` | Whether to load `.env` files |
342
- | `dotenv.path` | `string` | `undefined` | Directory to load dotenv files from. When omitted, `fastedge-run` uses the process CWD — correct for most npm package users whose `.env` files live at the project root. Only set this when your dotenv files are in a non-standard location (e.g. a test fixture directory). |
343
- | `enforceProductionPropertyRules` | `boolean` | `true` | Restrict property access to match CDN production behavior |
344
- | `runnerType` | `WasmType` | *auto-detected* | Override WASM type detection |
339
+ | Field | Type | Default | Description |
340
+ | -------------------------------- | ---------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
341
+ | `dotenv.enabled` | `boolean` | `false` | Whether to load `.env` files |
342
+ | `dotenv.path` | `string` | `undefined` | Directory to load dotenv files from. When omitted, `fastedge-run` uses the process CWD — correct for most npm package users whose `.env` files live at the project root. Only set this when your dotenv files are in a non-standard location (e.g. a test fixture directory). |
343
+ | `enforceProductionPropertyRules` | `boolean` | `true` | Restrict property access to match CDN production behavior |
344
+ | `runnerType` | `WasmType` | *auto-detected* | Override WASM type detection |
345
345
  | `httpPort` | `number` | `undefined` | HTTP-WASM only. Pin the spawned `fastedge-run` subprocess to a specific port instead of allocating from the dynamic pool (8100–8199). `load()` throws if the port is busy — there is no fallback to dynamic allocation. Intended for Codespaces/Docker port-forwarding or external tooling requiring a fixed address. Ignored for proxy-wasm. |
346
346
 
347
347
  ### HttpRequest & HttpResponse
@@ -416,14 +416,14 @@ type HookCall = {
416
416
  };
417
417
  ```
418
418
 
419
- | Field | Description |
420
- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
421
- | `hook` | Hook name: `"onRequestHeaders"`, `"onRequestBody"`, `"onResponseHeaders"`, `"onResponseBody"` |
422
- | `request` | Request state passed to the hook |
423
- | `response` | Seed state for response hooks called via `callHook()`. Ignored by `callFullFlow()` and by request hooks — the full-flow path generates the upstream response at runtime. |
424
- | `properties` | Shared properties (e.g. `request.path`, `vm_config`, `plugin_config`) |
425
- | `dotenvEnabled` | Optional per-call dotenv override. Use `applyDotenv()` for persistent changes. |
426
- | `enforceProductionPropertyRules` | Defaults to `true`. Set to `false` to allow property reads that would be blocked on production CDN. |
419
+ | Field | Description |
420
+ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
421
+ | `hook` | Hook name: `"onRequestHeaders"`, `"onRequestBody"`, `"onResponseHeaders"`, `"onResponseBody"` |
422
+ | `request` | Request state passed to the hook |
423
+ | `response` | Seed state for response hooks called via `callHook()`. Ignored by `callFullFlow()` and by request hooks — the full-flow path generates the upstream response at runtime. |
424
+ | `properties` | Shared properties (e.g. `request.path`, `vm_config`, `plugin_config`) |
425
+ | `dotenvEnabled` | Optional per-call dotenv override. Use `applyDotenv()` for persistent changes. |
426
+ | `enforceProductionPropertyRules` | Defaults to `true`. Set to `false` to allow property reads that would be blocked on production CDN. |
427
427
 
428
428
  `HeaderRecord` is `Record<string, string | string[]>` — multi-valued headers (e.g. multiple `Set-Cookie`) are represented as `string[]`.
429
429
 
@@ -447,13 +447,13 @@ type HookResult = {
447
447
  };
448
448
  ```
449
449
 
450
- | Field | Description |
451
- | ------------ | ------------------------------------------------------------------------------------------- |
452
- | `returnCode` | The numeric value returned by the WASM hook export, or `null` if the export was not found |
453
- | `logs` | Log entries emitted via `proxy_log` during hook execution |
454
- | `input` | Request/response state as seen by the hook before execution |
455
- | `output` | Request/response state after hook execution (reflects WASM mutations) |
456
- | `properties` | All shared properties after hook execution |
450
+ | Field | Description |
451
+ | ------------ | ------------------------------------------------------------------------------------------ |
452
+ | `returnCode` | The numeric value returned by the WASM hook export, or `null` if the export was not found |
453
+ | `logs` | Log entries emitted via `proxy_log` during hook execution |
454
+ | `input` | Request/response state as seen by the hook before execution |
455
+ | `output` | Request/response state after hook execution (reflects WASM mutations) |
456
+ | `properties` | All shared properties after hook execution |
457
457
 
458
458
  ### FullFlowResult
459
459
 
@@ -472,11 +472,11 @@ type FullFlowResult = {
472
472
  };
473
473
  ```
474
474
 
475
- | Field | Description |
476
- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
477
- | `hookResults` | A `Record` keyed by hook name (`"onRequestHeaders"`, `"onRequestBody"`, `"onResponseHeaders"`, `"onResponseBody"`), each containing a `HookResult` |
478
- | `finalResponse` | The final response after all hooks have executed, or the local response if a hook short-circuited (see `callFullFlow`). `body` is base64-encoded when `isBase64` is `true`. |
479
- | `calculatedProperties` | Runtime properties computed from the request URL (e.g. `request.path`, `request.host`) |
475
+ | Field | Description |
476
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
477
+ | `hookResults` | A `Record` keyed by hook name (`"onRequestHeaders"`, `"onRequestBody"`, `"onResponseHeaders"`, `"onResponseBody"`), each containing a `HookResult` |
478
+ | `finalResponse` | The final response after all hooks have executed, or the local response if a hook short-circuited (see `callFullFlow`). `body` is base64-encoded when `isBase64` is `true`. |
479
+ | `calculatedProperties` | Runtime properties computed from the request URL (e.g. `request.path`, `request.host`) |
480
480
 
481
481
  ### Supporting Types
482
482
 
@@ -22,25 +22,25 @@ The config schema is a union of two variants selected by `appType`:
22
22
 
23
23
  ### Top-Level Fields
24
24
 
25
- | JSON Path | Type | Required (Schema) | Default | Description |
26
- | -------------------- | --------- | -------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
27
- | `$schema` | `string` | No | — | URI pointing to the JSON Schema file for IDE autocompletion and validation. |
28
- | `description` | `string` | No | — | Human-readable label for this test scenario. |
29
- | `wasm` | `object` | No | — | WASM binary configuration. Required when running without a programmatic `wasmBuffer`. |
30
- | `wasm.path` | `string` | Yes (if `wasm` present) | — | Path to the compiled `.wasm` binary, relative to the config file or absolute. |
31
- | `wasm.description` | `string` | No | — | Human-readable label for the WASM binary. |
32
- | `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. |
33
- | `request` | `object` | **Yes** | — | Incoming HTTP request to simulate. |
34
- | `request.method` | `string` | Yes (schema) / runtime default | `"GET"` | HTTP method (e.g. `"GET"`, `"POST"`). |
35
- | `request.url` | `string` | **Yes** (CDN only) | — | Full URL for the simulated upstream request (e.g. `"https://example.com/api"`). CDN mode only. |
36
- | `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. |
37
- | `request.headers` | `object` | Yes (schema) / runtime default | `{}` | Key/value map of request headers. All keys and values must be strings. |
38
- | `request.body` | `string` | Yes (schema) / runtime default | `""` | Request body as a plain string. Use an empty string for requests with no body. |
39
- | `properties` | `object` | **Yes** (schema) / runtime default | `{}` | CDN property key/value pairs passed to the WASM execution context. Values may be any JSON type. |
40
- | `dotenv` | `object` | No | — | Dotenv file loading configuration. |
41
- | `dotenv.enabled` | `boolean` | No | — | Whether to load a `.env` file before execution. |
42
- | `dotenv.path` | `string` | No | — | Path to the `.env` file. If omitted, resolves `.env` relative to the config file directory. |
43
- | `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. |
25
+ | JSON Path | Type | Required (Schema) | Default | Description |
26
+ | ------------------ | --------- | -------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
27
+ | `$schema` | `string` | No | — | URI pointing to the JSON Schema file for IDE autocompletion and validation. |
28
+ | `description` | `string` | No | — | Human-readable label for this test scenario. |
29
+ | `wasm` | `object` | No | — | WASM binary configuration. Required when running without a programmatic `wasmBuffer`. |
30
+ | `wasm.path` | `string` | Yes (if `wasm` present) | — | Path to the compiled `.wasm` binary, relative to the config file or absolute. |
31
+ | `wasm.description` | `string` | No | — | Human-readable label for the WASM binary. |
32
+ | `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. |
33
+ | `request` | `object` | **Yes** | — | Incoming HTTP request to simulate. |
34
+ | `request.method` | `string` | Yes (schema) / runtime default | `"GET"` | HTTP method (e.g. `"GET"`, `"POST"`). |
35
+ | `request.url` | `string` | **Yes** (CDN only) | — | Full URL for the simulated upstream request (e.g. `"https://example.com/api"`). CDN mode only. |
36
+ | `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 and receives only the path portion of the request. |
37
+ | `request.headers` | `object` | Yes (schema) / runtime default | `{}` | Key/value map of request headers. All keys and values must be strings. |
38
+ | `request.body` | `string` | Yes (schema) / runtime default | `""` | Request body as a plain string. Use an empty string for requests with no body. |
39
+ | `properties` | `object` | **Yes** (schema) / runtime default | `{}` | CDN property key/value pairs passed to the WASM execution context. Values may be any JSON type. |
40
+ | `dotenv` | `object` | No | — | Dotenv file loading configuration. |
41
+ | `dotenv.enabled` | `boolean` | No | — | Whether to load a `.env` file before execution. |
42
+ | `dotenv.path` | `string` | No | — | Path to the `.env` file. If omitted, resolves `.env` relative to the config file directory. |
43
+ | `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. |
44
44
 
45
45
  ### Required vs. Default Distinction
46
46
 
@@ -147,13 +147,13 @@ interface MockOriginsHandle {
147
147
  }
148
148
  ```
149
149
 
150
- | Field | Description |
151
- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
152
- | `options.allowNetConnect` | Opt requests out of the default `disableNetConnect` block. `true` allows all; an array allow-lists origins or patterns |
153
- | `handle.origin(url)` | Get or create a `MockPool` for an origin; chain `.intercept({path, method}).reply(...)` on it |
154
- | `handle.agent` | Raw `MockAgent` escape hatch for `.persist()` / `.times()` / `.delay()` / body matchers |
155
- | `handle.close()` | Restore the previous global dispatcher and close the agent; idempotent |
156
- | `handle.assertAllCalled()` | Throw if any registered interceptor was never matched by a real request |
150
+ | Field | Description |
151
+ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
152
+ | `options.allowNetConnect` | Opt requests out of the default `disableNetConnect` block. `true` allows all; an array allow-lists origins or patterns |
153
+ | `handle.origin(url)` | Get or create a `MockPool` for an origin; chain `.intercept({path, method}).reply(...)` on it |
154
+ | `handle.agent` | Raw `MockAgent` escape hatch for `.persist()` / `.times()` / `.delay()` / body matchers |
155
+ | `handle.close()` | Restore the previous global dispatcher and close the agent; idempotent |
156
+ | `handle.assertAllCalled()` | Throw if any registered interceptor was never matched by a real request |
157
157
 
158
158
  ### HttpRequestOptions
159
159
 
@@ -195,13 +195,13 @@ interface RunnerConfig {
195
195
  }
196
196
  ```
197
197
 
198
- | Field | Type | Description |
199
- | -------------------------------- | ------------------------------- | ------------------------------------------------------------------------- |
200
- | `dotenv.enabled` | `boolean` | Enable dotenv loading |
201
- | `dotenv.path` | `string` | Directory to load dotenv files from; defaults to process CWD when omitted |
202
- | `enforceProductionPropertyRules` | `boolean` | Override production property enforcement for the runner; default `true` |
198
+ | Field | Type | Description |
199
+ | -------------------------------- | ------------------------------ | ------------------------------------------------------------------------- |
200
+ | `dotenv.enabled` | `boolean` | Enable dotenv loading |
201
+ | `dotenv.path` | `string` | Directory to load dotenv files from; defaults to process CWD when omitted |
202
+ | `enforceProductionPropertyRules` | `boolean` | Override production property enforcement for the runner; default `true` |
203
203
  | `runnerType` | `"http-wasm" \| "proxy-wasm"` | Override automatic WASM type detection |
204
- | `httpPort` | `number` | Pin the HTTP server to a specific port (HTTP WASM only; throws if in use) |
204
+ | `httpPort` | `number` | Pin the HTTP server to a specific port (HTTP WASM only; throws if in use) |
205
205
 
206
206
  ## Functions
207
207
 
@@ -301,12 +301,12 @@ type FullFlowResult = {
301
301
 
302
302
  Hook results are accessed by camelCase key:
303
303
 
304
- | Key | Hook |
305
- | --------------------- | ---------------------------- |
306
- | `onRequestHeaders` | `on_request_headers` hook |
307
- | `onRequestBody` | `on_request_body` hook |
308
- | `onResponseHeaders` | `on_response_headers` hook |
309
- | `onResponseBody` | `on_response_body` hook |
304
+ | Key | Hook |
305
+ | ------------------- | -------------------------- |
306
+ | `onRequestHeaders` | `on_request_headers` hook |
307
+ | `onRequestBody` | `on_request_body` hook |
308
+ | `onResponseHeaders` | `on_response_headers` hook |
309
+ | `onResponseBody` | `on_response_body` hook |
310
310
 
311
311
  ```typescript
312
312
  const result = await runFlow(runner, {
@@ -440,11 +440,9 @@ function assertFinalStatus(result: FullFlowResult, expected: number): void
440
440
  function assertFinalHeader(result: FullFlowResult, name: string, expected?: string | string[]): void
441
441
  ```
442
442
 
443
- Multi-value semantics on `assertFinalHeader` match `assertRequestHeader`: a `string` expected matches any value when the actual header is multi-valued; a `string[]` expected requires an exact array match. This preserves the RFC 6265 contract for `Set-Cookie` and any other legitimately-repeatable headers.
444
-
445
443
  `assertFinalStatus` asserts the final response status code after the full flow completes.
446
444
 
447
- `assertFinalHeader` asserts a header in `result.finalResponse.headers`. If `expected` is provided, also asserts the value.
445
+ `assertFinalHeader` asserts a header in `result.finalResponse.headers`. If `expected` is provided, also asserts the value. Multi-value semantics match `assertRequestHeader`: a `string` expected matches any value when the actual header is multi-valued; a `string[]` expected requires an exact array match. This preserves the RFC 6265 contract for `Set-Cookie` and any other legitimately-repeatable headers.
448
446
 
449
447
  ```typescript
450
448
  assertFinalStatus(result, 200);
@@ -648,7 +646,7 @@ The handle installs the MockAgent as the global dispatcher on construction and r
648
646
 
649
647
  `handle.assertAllCalled()` throws if any registered interceptor was never matched. Use it at the end of a test (or in `afterEach`) to catch setup drift — mocks that were registered but never exercised because the WASM under test took a different code path.
650
648
 
651
- ### `allowNetConnect` and the HTTP-WASM caveat
649
+ ### HTTP-WASM `allowNetConnect` caveat
652
650
 
653
651
  By default, `mockOrigins()` calls `MockAgent.disableNetConnect()` — every request that doesn't match a registered interceptor is rejected. This is the safer default: missing mocks become loud errors instead of silent live network calls in CI.
654
652
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcoredev/fastedge-test",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -78,7 +78,7 @@
78
78
  },
79
79
  "dependencies": {
80
80
  "@assemblyscript/wasi-shim": "^0.1.0",
81
- "@gcoredev/fastedge-sdk-js": "^2.2.2",
81
+ "@gcoredev/fastedge-sdk-js": "^2.2.3",
82
82
  "@gcoredev/proxy-wasm-sdk-as": "^1.2.3",
83
83
  "@types/ws": "^8.18.1",
84
84
  "express": "^4.19.2",