@gcoredev/fastedge-test 0.1.6 → 0.2.0
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/dist/frontend/assets/{index-BpdzhbRl.js → index-CiqeJ9rz.js} +24 -24
- package/dist/frontend/index.html +1 -1
- package/dist/lib/index.cjs +164 -66
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +164 -66
- package/dist/lib/runner/HeaderManager.d.ts +6 -4
- package/dist/lib/runner/HostFunctions.d.ts +5 -5
- package/dist/lib/runner/HttpWasmRunner.d.ts +22 -5
- package/dist/lib/runner/IStateManager.d.ts +7 -7
- package/dist/lib/runner/IWasmRunner.d.ts +42 -10
- package/dist/lib/runner/PortManager.d.ts +4 -1
- package/dist/lib/runner/PropertyResolver.d.ts +3 -3
- package/dist/lib/runner/ProxyWasmRunner.d.ts +5 -2
- package/dist/lib/runner/standalone.d.ts +1 -1
- package/dist/lib/runner/types.d.ts +17 -8
- package/dist/lib/schemas/api.d.ts +2 -8
- package/dist/lib/schemas/config.d.ts +2 -13
- package/dist/lib/schemas/index.d.ts +2 -2
- package/dist/lib/test-framework/assertions.d.ts +18 -4
- package/dist/lib/test-framework/index.cjs +18634 -115
- package/dist/lib/test-framework/index.d.ts +2 -0
- package/dist/lib/test-framework/index.js +18651 -104
- package/dist/lib/test-framework/mock-origins.d.ts +56 -0
- package/dist/lib/test-framework/suite-runner.d.ts +16 -0
- package/dist/lib/test-framework/types.d.ts +1 -5
- package/dist/server.js +33 -33
- package/docs/API.md +48 -54
- package/docs/DEBUGGER.md +7 -8
- package/docs/INDEX.md +4 -1
- package/docs/RUNNER.md +126 -74
- package/docs/TEST_CONFIG.md +79 -40
- package/docs/TEST_FRAMEWORK.md +235 -36
- package/docs/WEBSOCKET.md +25 -21
- package/docs/quickstart.md +1 -13
- package/package.json +4 -1
- package/schemas/api-config.schema.json +5 -24
- package/schemas/api-load.schema.json +5 -0
- package/schemas/api-send.schema.json +0 -20
- package/schemas/fastedge-config.test.schema.json +5 -24
- package/schemas/full-flow-result.schema.json +17 -7
- package/schemas/hook-call.schema.json +16 -6
- package/schemas/hook-result.schema.json +16 -6
- package/schemas/http-response.schema.json +227 -5
package/docs/API.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The `@gcoredev/fastedge-test` debugger server exposes a REST API for loading WASM modules, executing requests, and managing test configuration.
|
|
4
4
|
|
|
5
|
+
> **Note on header values.** Response-side and hook-result headers use `Record<string, string | string[]>` — single-valued headers are a `string`, multi-valued headers (notably `Set-Cookie` per RFC 6265) are a `string[]`. Request-side header inputs are single-valued `Record<string, string>`.
|
|
6
|
+
|
|
5
7
|
## Base URL
|
|
6
8
|
|
|
7
9
|
```
|
|
@@ -93,16 +95,19 @@ Loads a WASM binary into the runner. Accepts either a file path or a base64-enco
|
|
|
93
95
|
|
|
94
96
|
**Request Body**
|
|
95
97
|
|
|
96
|
-
Exactly one of `wasmPath` or `wasmBase64` must be provided.
|
|
98
|
+
Exactly one of `wasmPath` or `wasmBase64` must be provided; providing both is an error.
|
|
97
99
|
|
|
98
100
|
```typescript
|
|
99
101
|
{
|
|
100
|
-
wasmPath?: string;
|
|
101
|
-
wasmBase64?: string;
|
|
102
|
+
wasmPath?: string; // Absolute path to a .wasm file on the server filesystem
|
|
103
|
+
wasmBase64?: string; // Base64-encoded WASM binary; mutually exclusive with wasmPath
|
|
102
104
|
dotenv?: {
|
|
103
|
-
enabled
|
|
104
|
-
path?: string;
|
|
105
|
+
enabled?: boolean; // Whether to load .env files for this module
|
|
106
|
+
path?: string; // Directory containing .env files (defaults to server CWD)
|
|
105
107
|
};
|
|
108
|
+
httpPort?: number; // HTTP-WASM only. Pin the runner subprocess to this port (1024–65535).
|
|
109
|
+
// Load fails immediately if the port is already in use.
|
|
110
|
+
// Ignored for proxy-wasm modules.
|
|
106
111
|
}
|
|
107
112
|
```
|
|
108
113
|
|
|
@@ -153,11 +158,31 @@ curl -X POST http://localhost:5179/api/load \
|
|
|
153
158
|
}
|
|
154
159
|
```
|
|
155
160
|
|
|
161
|
+
**Example — pin HTTP-WASM to a specific port**
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
curl -X POST http://localhost:5179/api/load \
|
|
165
|
+
-H "Content-Type: application/json" \
|
|
166
|
+
-d '{
|
|
167
|
+
"wasmPath": "/home/user/project/build/app.wasm",
|
|
168
|
+
"httpPort": 8100
|
|
169
|
+
}'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"ok": true,
|
|
175
|
+
"wasmType": "http-wasm",
|
|
176
|
+
"resolvedPath": "/home/user/project/build/app.wasm"
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
156
180
|
**Error Responses**
|
|
157
181
|
|
|
158
182
|
| Status | Condition |
|
|
159
183
|
| ------ | ----------------------------------------------------------------------------------------------------------- |
|
|
160
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) |
|
|
161
186
|
| `500` | WASM load failed or runner initialization error |
|
|
162
187
|
|
|
163
188
|
---
|
|
@@ -234,22 +259,16 @@ For **HTTP-WASM**, provide either `path` (preferred) or `url` (legacy). When `pa
|
|
|
234
259
|
}
|
|
235
260
|
```
|
|
236
261
|
|
|
237
|
-
For **Proxy-WASM**, the top-level `url` field is required. The full CDN flow is controlled via nested `request
|
|
262
|
+
For **Proxy-WASM**, the top-level `url` field is required. The full CDN flow is controlled via nested `request` and `properties` fields. The upstream response is generated at runtime — either by a real fetch against `url`, or by the built-in responder when `url === "built-in"`:
|
|
238
263
|
|
|
239
264
|
```typescript
|
|
240
265
|
{
|
|
241
|
-
url: string; // Request URL (required)
|
|
266
|
+
url: string; // Request URL, or "built-in" (required)
|
|
242
267
|
request?: {
|
|
243
268
|
method?: string; // HTTP method (default: "GET")
|
|
244
269
|
headers?: Record<string, string>; // Request headers (default: {})
|
|
245
270
|
body?: string; // Request body (default: "")
|
|
246
271
|
};
|
|
247
|
-
response?: {
|
|
248
|
-
headers?: Record<string, string>; // Simulated upstream response headers (default: {})
|
|
249
|
-
body?: string; // Simulated upstream response body (default: "")
|
|
250
|
-
status?: number; // Simulated upstream response status (default: 200)
|
|
251
|
-
statusText?: string; // Simulated upstream response status text (default: "OK")
|
|
252
|
-
};
|
|
253
272
|
properties?: Record<string, unknown>; // CDN properties (default: {})
|
|
254
273
|
}
|
|
255
274
|
```
|
|
@@ -262,7 +281,7 @@ For **Proxy-WASM**, the top-level `url` field is required. The full CDN flow is
|
|
|
262
281
|
result: {
|
|
263
282
|
status: number;
|
|
264
283
|
statusText: string;
|
|
265
|
-
headers: Record<string, string>;
|
|
284
|
+
headers: Record<string, string | string[]>;
|
|
266
285
|
body: string;
|
|
267
286
|
contentType: string | null;
|
|
268
287
|
isBase64?: boolean;
|
|
@@ -280,7 +299,7 @@ For **Proxy-WASM**, the top-level `url` field is required. The full CDN flow is
|
|
|
280
299
|
finalResponse: {
|
|
281
300
|
status: number;
|
|
282
301
|
statusText: string;
|
|
283
|
-
headers: Record<string, string>;
|
|
302
|
+
headers: Record<string, string | string[]>;
|
|
284
303
|
body: string;
|
|
285
304
|
contentType: string;
|
|
286
305
|
isBase64?: boolean;
|
|
@@ -296,13 +315,13 @@ type HookResult = {
|
|
|
296
315
|
returnCode: number | null;
|
|
297
316
|
logs: Array<{ level: number; message: string }>;
|
|
298
317
|
input: {
|
|
299
|
-
request: { headers: Record<string, string>; body: string };
|
|
300
|
-
response: { headers: Record<string, string>; body: string };
|
|
318
|
+
request: { headers: Record<string, string | string[]>; body: string };
|
|
319
|
+
response: { headers: Record<string, string | string[]>; body: string };
|
|
301
320
|
properties?: Record<string, unknown>;
|
|
302
321
|
};
|
|
303
322
|
output: {
|
|
304
|
-
request: { headers: Record<string, string>; body: string };
|
|
305
|
-
response: { headers: Record<string, string>; body: string };
|
|
323
|
+
request: { headers: Record<string, string | string[]>; body: string };
|
|
324
|
+
response: { headers: Record<string, string | string[]>; body: string };
|
|
306
325
|
properties?: Record<string, unknown>;
|
|
307
326
|
};
|
|
308
327
|
properties: Record<string, unknown>;
|
|
@@ -354,12 +373,6 @@ curl -X POST http://localhost:5179/api/execute \
|
|
|
354
373
|
"headers": { "host": "example.com" },
|
|
355
374
|
"body": ""
|
|
356
375
|
},
|
|
357
|
-
"response": {
|
|
358
|
-
"headers": { "content-type": "text/html" },
|
|
359
|
-
"body": "<html/>",
|
|
360
|
-
"status": 200,
|
|
361
|
-
"statusText": "OK"
|
|
362
|
-
},
|
|
363
376
|
"properties": {}
|
|
364
377
|
}'
|
|
365
378
|
```
|
|
@@ -452,13 +465,13 @@ type HookResult = {
|
|
|
452
465
|
returnCode: number | null;
|
|
453
466
|
logs: Array<{ level: number; message: string }>;
|
|
454
467
|
input: {
|
|
455
|
-
request: { headers: Record<string, string>; body: string };
|
|
456
|
-
response: { headers: Record<string, string>; body: string };
|
|
468
|
+
request: { headers: Record<string, string | string[]>; body: string };
|
|
469
|
+
response: { headers: Record<string, string | string[]>; body: string };
|
|
457
470
|
properties?: Record<string, unknown>;
|
|
458
471
|
};
|
|
459
472
|
output: {
|
|
460
|
-
request: { headers: Record<string, string>; body: string };
|
|
461
|
-
response: { headers: Record<string, string>; body: string };
|
|
473
|
+
request: { headers: Record<string, string | string[]>; body: string };
|
|
474
|
+
response: { headers: Record<string, string | string[]>; body: string };
|
|
462
475
|
properties?: Record<string, unknown>;
|
|
463
476
|
};
|
|
464
477
|
properties: Record<string, unknown>;
|
|
@@ -533,22 +546,18 @@ Requires a WASM module to be loaded via `POST /api/load`. Accepts an optional [`
|
|
|
533
546
|
|
|
534
547
|
```typescript
|
|
535
548
|
{
|
|
536
|
-
url: string | "built-in"; // Full request URL, or "built-in" to use the
|
|
549
|
+
url: string | "built-in"; // Full request URL, or "built-in" to use the built-in responder
|
|
537
550
|
request?: {
|
|
538
551
|
method?: string; // HTTP method (default: "GET")
|
|
539
552
|
url?: string;
|
|
540
553
|
headers?: Record<string, string>; // Request headers (default: {})
|
|
541
554
|
body?: string; // Request body (default: "")
|
|
542
555
|
};
|
|
543
|
-
response?: {
|
|
544
|
-
headers?: Record<string, string>; // Simulated upstream response headers (default: {})
|
|
545
|
-
body?: string; // Simulated upstream response body (default: "")
|
|
546
|
-
};
|
|
547
556
|
properties: Record<string, unknown>; // CDN properties (required; use {} if none)
|
|
548
557
|
}
|
|
549
558
|
```
|
|
550
559
|
|
|
551
|
-
The
|
|
560
|
+
The upstream response is generated at runtime — either by a real fetch against `url`, or by the built-in responder when `url === "built-in"`.
|
|
552
561
|
|
|
553
562
|
**Response**
|
|
554
563
|
|
|
@@ -559,7 +568,7 @@ The `response` object for this endpoint does not accept `status` or `statusText`
|
|
|
559
568
|
finalResponse: {
|
|
560
569
|
status: number;
|
|
561
570
|
statusText: string;
|
|
562
|
-
headers: Record<string, string>;
|
|
571
|
+
headers: Record<string, string | string[]>;
|
|
563
572
|
body: string;
|
|
564
573
|
contentType: string;
|
|
565
574
|
isBase64?: boolean;
|
|
@@ -583,10 +592,6 @@ curl -X POST http://localhost:5179/api/send \
|
|
|
583
592
|
"headers": { "content-type": "application/json" },
|
|
584
593
|
"body": "{\"key\":\"value\"}"
|
|
585
594
|
},
|
|
586
|
-
"response": {
|
|
587
|
-
"headers": { "content-type": "application/json" },
|
|
588
|
-
"body": "{\"result\":\"ok\"}"
|
|
589
|
-
},
|
|
590
595
|
"properties": {
|
|
591
596
|
"client.geo.country": "DE"
|
|
592
597
|
}
|
|
@@ -647,8 +652,8 @@ curl -X POST http://localhost:5179/api/send \
|
|
|
647
652
|
|
|
648
653
|
**Error Responses**
|
|
649
654
|
|
|
650
|
-
| Status | Condition
|
|
651
|
-
| ------ |
|
|
655
|
+
| Status | Condition |
|
|
656
|
+
| ------ | ---------------------------------------------------------------------------- |
|
|
652
657
|
| `400` | Validation failed (missing `url` or `properties`), or no WASM module loaded |
|
|
653
658
|
| `500` | Execution failed |
|
|
654
659
|
|
|
@@ -689,10 +694,6 @@ type ProxyWasmConfig = {
|
|
|
689
694
|
headers: Record<string, string>;
|
|
690
695
|
body: string;
|
|
691
696
|
};
|
|
692
|
-
response?: {
|
|
693
|
-
headers: Record<string, string>;
|
|
694
|
-
body: string;
|
|
695
|
-
};
|
|
696
697
|
properties: Record<string, unknown>;
|
|
697
698
|
dotenv?: { enabled?: boolean; path?: string };
|
|
698
699
|
};
|
|
@@ -703,6 +704,7 @@ type HttpWasmConfig = {
|
|
|
703
704
|
description?: string;
|
|
704
705
|
appType: "http-wasm";
|
|
705
706
|
wasm?: { path: string; description?: string };
|
|
707
|
+
httpPort?: number; // Pin the runner subprocess to this port (1024–65535)
|
|
706
708
|
request: {
|
|
707
709
|
method: string;
|
|
708
710
|
path: string;
|
|
@@ -734,10 +736,6 @@ curl http://localhost:5179/api/config
|
|
|
734
736
|
"headers": {},
|
|
735
737
|
"body": ""
|
|
736
738
|
},
|
|
737
|
-
"response": {
|
|
738
|
-
"headers": {},
|
|
739
|
-
"body": ""
|
|
740
|
-
},
|
|
741
739
|
"properties": {}
|
|
742
740
|
},
|
|
743
741
|
"valid": true
|
|
@@ -792,10 +790,6 @@ curl -X POST http://localhost:5179/api/config \
|
|
|
792
790
|
"headers": { "accept": "text/html" },
|
|
793
791
|
"body": ""
|
|
794
792
|
},
|
|
795
|
-
"response": {
|
|
796
|
-
"headers": {},
|
|
797
|
-
"body": ""
|
|
798
|
-
},
|
|
799
793
|
"properties": {
|
|
800
794
|
"client.geo.country": "US"
|
|
801
795
|
}
|
package/docs/DEBUGGER.md
CHANGED
|
@@ -71,7 +71,7 @@ process.kill(process.pid, "SIGTERM");
|
|
|
71
71
|
PORT=8080 npx fastedge-debug
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
If the preferred port is already in use, the server tries the next port sequentially,
|
|
74
|
+
If the preferred port is already in use, the server tries the next port sequentially, up to 50 ports (for example, `5179` through `5228` by default). If no free port is found in that range, the server exits with an error. Set `PORT` to a specific value to bypass auto-increment when a predictable port is required.
|
|
75
75
|
|
|
76
76
|
The server writes the bound port number to `.fastedge-debug/.debug-port` under `WORKSPACE_PATH` (if set) or the current working directory, and deletes the file on shutdown. Use this file for programmatic port discovery when starting the server as a subprocess.
|
|
77
77
|
|
|
@@ -98,13 +98,12 @@ 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
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `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
|
+
| `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. |
|
|
108
107
|
|
|
109
108
|
### Usage examples
|
|
110
109
|
|
package/docs/INDEX.md
CHANGED
|
@@ -79,12 +79,13 @@ import { defineTestSuite, runAndExit } from "@gcoredev/fastedge-test/test";
|
|
|
79
79
|
| `runFlow` | function | Executes a single request flow directly |
|
|
80
80
|
| `runHttpRequest` | function | Executes a single HTTP request directly |
|
|
81
81
|
| `loadConfigFile` | function | Loads and validates a `fastedge-config.test.json` file |
|
|
82
|
+
| `mockOrigins` | function | Creates mock HTTP origins that respond to outgoing HTTP calls |
|
|
82
83
|
| `assertRequestHeader` | function | Asserts a header is present on the outgoing request |
|
|
83
84
|
| `assertNoRequestHeader` | function | Asserts a header is absent from the outgoing request |
|
|
84
85
|
| `assertResponseHeader` | function | Asserts a header is present on the final response |
|
|
85
86
|
| `assertNoResponseHeader` | function | Asserts a header is absent from the final response |
|
|
86
87
|
| `assertFinalStatus` | function | Asserts the final HTTP status code |
|
|
87
|
-
| `assertFinalHeader` | function | Asserts a header on the final response
|
|
88
|
+
| `assertFinalHeader` | function | Asserts a header on the final response |
|
|
88
89
|
| `assertReturnCode` | function | Asserts the proxy-wasm return code |
|
|
89
90
|
| `assertLog` | function | Asserts a log entry was emitted |
|
|
90
91
|
| `assertNoLog` | function | Asserts a log entry was not emitted |
|
|
@@ -101,6 +102,8 @@ import { defineTestSuite, runAndExit } from "@gcoredev/fastedge-test/test";
|
|
|
101
102
|
| `assertHttpContentType` | function | Asserts the HTTP response Content-Type header |
|
|
102
103
|
| `assertHttpLog` | function | Asserts a log entry was emitted during HTTP request handling |
|
|
103
104
|
| `assertHttpNoLog` | function | Asserts a log entry was not emitted during HTTP request handling |
|
|
105
|
+
| `MockOriginsHandle` | type | Handle returned by `mockOrigins` — use to stop the mock servers |
|
|
106
|
+
| `MockOriginsOptions` | type | Options accepted by `mockOrigins` |
|
|
104
107
|
| `TestSuite` | type | Suite definition — one of `wasmPath` or `wasmBuffer` plus test cases |
|
|
105
108
|
| `TestCase` | type | A single test scenario with config and assertions |
|
|
106
109
|
| `TestResult` | type | Result of a single test case execution |
|