@gcoredev/fastedge-test 0.1.7 → 0.2.1

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.
Files changed (44) hide show
  1. package/dist/fastedge-cli/METADATA.json +1 -1
  2. package/dist/fastedge-cli/fastedge-run-darwin-arm64 +0 -0
  3. package/dist/fastedge-cli/fastedge-run-linux-x64 +0 -0
  4. package/dist/fastedge-cli/fastedge-run.exe +0 -0
  5. package/dist/frontend/assets/{index-BCXfEMSq.js → index-CiqeJ9rz.js} +24 -24
  6. package/dist/frontend/index.html +1 -1
  7. package/dist/lib/index.cjs +292 -140
  8. package/dist/lib/index.d.ts +1 -0
  9. package/dist/lib/index.js +292 -140
  10. package/dist/lib/runner/HeaderManager.d.ts +7 -4
  11. package/dist/lib/runner/HostFunctions.d.ts +5 -5
  12. package/dist/lib/runner/HttpWasmRunner.d.ts +13 -4
  13. package/dist/lib/runner/IStateManager.d.ts +7 -7
  14. package/dist/lib/runner/IWasmRunner.d.ts +17 -9
  15. package/dist/lib/runner/PropertyResolver.d.ts +3 -3
  16. package/dist/lib/runner/ProxyWasmRunner.d.ts +6 -3
  17. package/dist/lib/runner/standalone.d.ts +1 -1
  18. package/dist/lib/runner/types.d.ts +17 -8
  19. package/dist/lib/schemas/api.d.ts +0 -8
  20. package/dist/lib/schemas/config.d.ts +0 -13
  21. package/dist/lib/schemas/index.d.ts +2 -2
  22. package/dist/lib/test-framework/assertions.d.ts +18 -4
  23. package/dist/lib/test-framework/index.cjs +18754 -189
  24. package/dist/lib/test-framework/index.d.ts +2 -0
  25. package/dist/lib/test-framework/index.js +18771 -178
  26. package/dist/lib/test-framework/mock-origins.d.ts +56 -0
  27. package/dist/lib/test-framework/types.d.ts +1 -5
  28. package/dist/server.js +33 -33
  29. package/docs/API.md +23 -53
  30. package/docs/DEBUGGER.md +7 -7
  31. package/docs/INDEX.md +4 -1
  32. package/docs/RUNNER.md +79 -64
  33. package/docs/TEST_CONFIG.md +28 -41
  34. package/docs/TEST_FRAMEWORK.md +205 -32
  35. package/docs/WEBSOCKET.md +25 -21
  36. package/docs/quickstart.md +1 -13
  37. package/package.json +4 -1
  38. package/schemas/api-config.schema.json +0 -24
  39. package/schemas/api-send.schema.json +0 -20
  40. package/schemas/fastedge-config.test.schema.json +0 -24
  41. package/schemas/full-flow-result.schema.json +17 -7
  42. package/schemas/hook-call.schema.json +16 -6
  43. package/schemas/hook-result.schema.json +16 -6
  44. package/schemas/http-response.schema.json +227 -5
@@ -1,6 +1,9 @@
1
- import type { HeaderMap, HeaderTuples } from "./types";
1
+ import type { HeaderMap, HeaderRecord, HeaderTuples } from "./types";
2
2
  export declare class HeaderManager {
3
- static normalize(headers: HeaderMap): HeaderMap;
3
+ static firstValue(v: string | string[] | undefined): string | undefined;
4
+ static flattenToMap(headers: HeaderMap | HeaderRecord): HeaderMap;
5
+ static normalize(headers: HeaderMap | HeaderRecord): HeaderRecord;
6
+ static appendMerge(left: HeaderMap | HeaderRecord, right: HeaderMap | HeaderRecord): HeaderRecord;
4
7
  static serialize(headers: HeaderMap): Uint8Array;
5
8
  /**
6
9
  * Deserializes a proxy-wasm binary header map format:
@@ -8,8 +11,8 @@ export declare class HeaderManager {
8
11
  */
9
12
  static deserializeBinary(bytes: Uint8Array): HeaderMap;
10
13
  static deserialize(payload: string): HeaderMap;
11
- static recordToTuples(headers: HeaderMap): HeaderTuples;
12
- static tuplesToRecord(tuples: HeaderTuples): HeaderMap;
14
+ static recordToTuples(headers: HeaderMap | HeaderRecord): HeaderTuples;
15
+ static tuplesToRecord(tuples: HeaderTuples): HeaderRecord;
13
16
  static normalizeTuples(tuples: HeaderTuples): HeaderTuples;
14
17
  static serializeTuples(tuples: HeaderTuples): Uint8Array;
15
18
  static deserializeBinaryToTuples(bytes: Uint8Array): HeaderTuples;
@@ -1,4 +1,4 @@
1
- import type { HeaderMap, LogEntry } from "./types";
1
+ import type { HeaderMap, HeaderRecord, HeaderTuples, LogEntry } from "./types";
2
2
  import { MemoryManager } from "./MemoryManager";
3
3
  import { PropertyResolver } from "./PropertyResolver";
4
4
  import { PropertyAccessControl, HookContext } from "./PropertyAccessControl";
@@ -36,7 +36,7 @@ export declare class HostFunctions {
36
36
  private dictionary;
37
37
  constructor(memory: MemoryManager, propertyResolver: PropertyResolver, propertyAccessControl: PropertyAccessControl, getCurrentHook: () => HookContext | null, debug?: boolean, secretStore?: SecretStore, dictionary?: Dictionary);
38
38
  setLogs(logs: LogEntry[]): void;
39
- setHeadersAndBodies(reqHeaders: HeaderMap, resHeaders: HeaderMap, reqBody: string, resBody: string): void;
39
+ setHeadersAndBodies(reqHeaders: HeaderMap | HeaderRecord, resHeaders: HeaderMap | HeaderRecord, reqBody: string, resBody: string): void;
40
40
  setConfigs(vmConfig: string, pluginConfig: string): void;
41
41
  setCurrentContext(contextId: number): void;
42
42
  getCurrentLogLevel(): number;
@@ -50,7 +50,7 @@ export declare class HostFunctions {
50
50
  body: Uint8Array | null;
51
51
  timeoutMs: number;
52
52
  } | null;
53
- setHttpCallResponse(tokenId: number, headers: HeaderMap, body: Uint8Array): void;
53
+ setHttpCallResponse(tokenId: number, headers: HeaderMap | HeaderRecord | HeaderTuples, body: Uint8Array): void;
54
54
  clearHttpCallResponse(): void;
55
55
  isStreamClosed(): boolean;
56
56
  resetStreamClosed(): void;
@@ -61,8 +61,8 @@ export declare class HostFunctions {
61
61
  body: Uint8Array;
62
62
  } | null;
63
63
  resetLocalResponse(): void;
64
- getRequestHeaders(): HeaderMap;
65
- getResponseHeaders(): HeaderMap;
64
+ getRequestHeaders(): HeaderRecord;
65
+ getResponseHeaders(): HeaderRecord;
66
66
  getRequestBody(): string;
67
67
  getResponseBody(): string;
68
68
  getSecretStore(): SecretStore;
@@ -4,6 +4,7 @@
4
4
  * Executes HTTP WASM binaries (component model with wasi-http interface)
5
5
  * using the FastEdge-run CLI as a process-based runner.
6
6
  */
7
+ import type { IncomingHttpHeaders } from "node:http";
7
8
  import type { IWasmRunner, WasmType, RunnerConfig, HttpRequest, HttpResponse } from "./IWasmRunner.js";
8
9
  import type { HookCall, HookResult, FullFlowResult } from "./types.js";
9
10
  import type { IStateManager } from "./IStateManager.js";
@@ -50,7 +51,7 @@ export declare class HttpWasmRunner implements IWasmRunner {
50
51
  /**
51
52
  * Not supported for HTTP WASM (proxy-wasm only)
52
53
  */
53
- callFullFlow(_url: string, _method: string, _headers: Record<string, string>, _body: string, _responseHeaders: Record<string, string>, _responseBody: string, _responseStatus: number, _responseStatusText: string, _properties: Record<string, unknown>, _enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
54
+ callFullFlow(_url: string, _method: string, _headers: Record<string, string>, _body: string, _properties: Record<string, unknown>, _enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
54
55
  /**
55
56
  * Apply dotenv settings by restarting the fastedge-run process.
56
57
  * The WASM file is not re-read; only the --dotenv flag changes.
@@ -111,8 +112,16 @@ export declare class HttpWasmRunner implements IWasmRunner {
111
112
  * Check if content type is binary
112
113
  */
113
114
  private isBinaryContentType;
114
- /**
115
- * Parse headers from fetch Headers object
116
- */
117
115
  private parseHeaders;
118
116
  }
117
+ /**
118
+ * Parse a fetch Headers object into an IncomingHttpHeaders-shaped record.
119
+ *
120
+ * Uses `Headers.getSetCookie()` (Node 19.7+, always available on Node ≥22.12)
121
+ * to preserve multiple Set-Cookie entries as a string[] — RFC 6265 §3 exempts
122
+ * Set-Cookie from the "combine duplicates with commas" rule, and real browsers
123
+ * process each Set-Cookie independently.
124
+ *
125
+ * Exported for unit testing; in production use it via HttpWasmRunner.
126
+ */
127
+ export declare function parseFetchHeaders(headers: Headers): IncomingHttpHeaders;
@@ -7,30 +7,30 @@
7
7
  */
8
8
  export type EventSource = "ui" | "ai_agent" | "api" | "system";
9
9
  export interface IStateManager {
10
- emitRequestStarted(url: string, method: string, headers: Record<string, string>, source?: EventSource): void;
10
+ emitRequestStarted(url: string, method: string, headers: Record<string, string | string[]>, source?: EventSource): void;
11
11
  emitHookExecuted(hook: string, returnCode: number | null, logCount: number, input: {
12
12
  request: {
13
- headers: Record<string, string>;
13
+ headers: Record<string, string | string[]>;
14
14
  body: string;
15
15
  };
16
16
  response: {
17
- headers: Record<string, string>;
17
+ headers: Record<string, string | string[]>;
18
18
  body: string;
19
19
  };
20
20
  }, output: {
21
21
  request: {
22
- headers: Record<string, string>;
22
+ headers: Record<string, string | string[]>;
23
23
  body: string;
24
24
  };
25
25
  response: {
26
- headers: Record<string, string>;
26
+ headers: Record<string, string | string[]>;
27
27
  body: string;
28
28
  };
29
29
  }, source?: EventSource): void;
30
30
  emitRequestCompleted(hookResults: Record<string, unknown>, finalResponse: {
31
31
  status: number;
32
32
  statusText: string;
33
- headers: Record<string, string>;
33
+ headers: Record<string, string | string[]>;
34
34
  body: string;
35
35
  contentType: string;
36
36
  isBase64?: boolean;
@@ -41,7 +41,7 @@ export interface IStateManager {
41
41
  emitHttpWasmRequestCompleted(response: {
42
42
  status: number;
43
43
  statusText: string;
44
- headers: Record<string, string>;
44
+ headers: Record<string, string | string[] | undefined>;
45
45
  body: string;
46
46
  contentType: string | null;
47
47
  isBase64?: boolean;
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Defines the common contract for both ProxyWasmRunner and HttpWasmRunner
5
5
  */
6
+ import type { IncomingHttpHeaders } from "node:http";
6
7
  import type { IStateManager } from "./IStateManager.js";
7
8
  import type { HookCall, HookResult, FullFlowResult } from "./types.js";
8
9
  export type WasmType = "http-wasm" | "proxy-wasm";
@@ -38,12 +39,18 @@ export interface HttpRequest {
38
39
  body?: string;
39
40
  }
40
41
  /**
41
- * HTTP Response type for HTTP WASM runner
42
+ * HTTP Response type for HTTP WASM runner.
43
+ *
44
+ * `headers` uses Node's `IncomingHttpHeaders` shape — common single-valued
45
+ * headers (`content-type`, `location`, `etag`, …) are typed as `string`;
46
+ * `set-cookie` is `string[]`; unknown keys are `string | string[] | undefined`.
47
+ * This preserves RFC 6265 Set-Cookie semantics (each cookie kept separate)
48
+ * and matches consumer expectations for Node's fetch/http ecosystem.
42
49
  */
43
50
  export interface HttpResponse {
44
51
  status: number;
45
52
  statusText: string;
46
- headers: Record<string, string>;
53
+ headers: IncomingHttpHeaders;
47
54
  body: string;
48
55
  contentType: string | null;
49
56
  isBase64?: boolean;
@@ -90,20 +97,21 @@ export interface IWasmRunner {
90
97
  */
91
98
  callHook(hookCall: HookCall): Promise<HookResult>;
92
99
  /**
93
- * Execute full request/response flow (Proxy-WASM only)
94
- * @param url Request URL
100
+ * Execute full request/response flow (Proxy-WASM only).
101
+ *
102
+ * The upstream response is generated at runtime — either by a real HTTP
103
+ * fetch against `url`, or by the built-in responder when
104
+ * `url === "built-in"`. There is no fixture-level mock response.
105
+ *
106
+ * @param url Request URL, or `"built-in"` to use the built-in responder
95
107
  * @param method HTTP method
96
108
  * @param headers Request headers
97
109
  * @param body Request body
98
- * @param responseHeaders Response headers
99
- * @param responseBody Response body
100
- * @param responseStatus Response status code
101
- * @param responseStatusText Response status text
102
110
  * @param properties Shared properties
103
111
  * @param enforceProductionPropertyRules Whether to enforce property access rules
104
112
  * @returns Full flow execution result
105
113
  */
106
- callFullFlow(url: string, method: string, headers: Record<string, string>, body: string, responseHeaders: Record<string, string>, responseBody: string, responseStatus: number, responseStatusText: string, properties: Record<string, unknown>, enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
114
+ callFullFlow(url: string, method: string, headers: Record<string, string>, body: string, properties: Record<string, unknown>, enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
107
115
  /**
108
116
  * Apply dotenv settings to the current runner without reloading the WASM.
109
117
  * For ProxyWasmRunner: resets stores and re-loads dotenv files in-place.
@@ -1,4 +1,4 @@
1
- import type { HeaderMap } from "./types";
1
+ import type { HeaderMap, HeaderRecord } from "./types";
2
2
  export declare class PropertyResolver {
3
3
  private properties;
4
4
  private requestHeaders;
@@ -28,13 +28,13 @@ export declare class PropertyResolver {
28
28
  * User properties take precedence over calculated ones
29
29
  */
30
30
  getAllProperties(): Record<string, unknown>;
31
- setRequestMetadata(headers: HeaderMap, method: string, path?: string, scheme?: string): void;
31
+ setRequestMetadata(headers: HeaderMap | HeaderRecord, method: string, path?: string, scheme?: string): void;
32
32
  /**
33
33
  * Extract runtime properties from target URL
34
34
  * This parses the URL to populate request.url, request.host, request.path, etc.
35
35
  */
36
36
  extractRuntimePropertiesFromUrl(targetUrl: string): void;
37
- setResponseMetadata(headers: HeaderMap, status: number, statusText: string): void;
37
+ setResponseMetadata(headers: HeaderMap | HeaderRecord, status: number, statusText: string): void;
38
38
  resolve(path: string): unknown;
39
39
  private resolveStandard;
40
40
  private resolvePathSegments;
@@ -59,13 +59,16 @@ export declare class ProxyWasmRunner implements IWasmRunner {
59
59
  private getHookContext;
60
60
  private logDebug;
61
61
  /**
62
- * Interface-compliant callFullFlow method
62
+ * Interface-compliant callFullFlow method.
63
+ *
64
+ * The upstream response is generated at runtime by a real HTTP fetch
65
+ * against `url` or by the built-in responder when `url === "built-in"`.
63
66
  */
64
- callFullFlow(url: string, method: string, headers: Record<string, string>, body: string, responseHeaders: Record<string, string>, responseBody: string, responseStatus: number, responseStatusText: string, properties: Record<string, unknown>, enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
67
+ callFullFlow(url: string, method: string, headers: Record<string, string>, body: string, properties: Record<string, unknown>, enforceProductionPropertyRules: boolean): Promise<FullFlowResult>;
65
68
  /**
66
69
  * Not supported for Proxy-WASM (HTTP WASM only)
67
70
  */
68
- execute(request: HttpRequest): Promise<HttpResponse>;
71
+ execute(_request: HttpRequest): Promise<HttpResponse>;
69
72
  /**
70
73
  * Clean up resources (no-op for Proxy-WASM, but required by interface)
71
74
  */
@@ -7,7 +7,7 @@
7
7
  * Usage:
8
8
  * import { createRunner } from './server/runner/standalone.js';
9
9
  * const runner = await createRunner('./path/to/wasm.wasm');
10
- * const result = await runner.callFullFlow('https://example.com', 'GET', {}, '', {}, '', 200, 'OK', {}, true);
10
+ * const result = await runner.callFullFlow('https://example.com', 'GET', {}, '', {}, true);
11
11
  */
12
12
  import type { IWasmRunner, RunnerConfig } from "./IWasmRunner.js";
13
13
  /**
@@ -1,16 +1,25 @@
1
1
  export type HeaderMap = Record<string, string>;
2
2
  export type HeaderTuples = [string, string][];
3
+ export type HeaderRecord = Record<string, string | string[]>;
3
4
  export type HookCall = {
4
5
  hook: string;
5
6
  request: {
6
- headers: HeaderMap;
7
+ headers: HeaderRecord;
7
8
  body: string;
8
9
  method?: string;
9
10
  path?: string;
10
11
  scheme?: string;
11
12
  };
12
- response: {
13
- headers: HeaderMap;
13
+ /**
14
+ * Seed state for the response hooks (`onResponseHeaders` / `onResponseBody`)
15
+ * when calling them in isolation via `callHook()`. The full-flow path
16
+ * (`callFullFlow`) generates the upstream response at runtime and does not
17
+ * consume this field — request hooks ignore it, and response hooks are
18
+ * called with the response built from the live origin fetch or built-in
19
+ * responder output.
20
+ */
21
+ response?: {
22
+ headers: HeaderRecord;
14
23
  body: string;
15
24
  status?: number;
16
25
  statusText?: string;
@@ -27,22 +36,22 @@ export type HookResult = {
27
36
  }[];
28
37
  input: {
29
38
  request: {
30
- headers: HeaderMap;
39
+ headers: HeaderRecord;
31
40
  body: string;
32
41
  };
33
42
  response: {
34
- headers: HeaderMap;
43
+ headers: HeaderRecord;
35
44
  body: string;
36
45
  };
37
46
  properties?: Record<string, unknown>;
38
47
  };
39
48
  output: {
40
49
  request: {
41
- headers: HeaderMap;
50
+ headers: HeaderRecord;
42
51
  body: string;
43
52
  };
44
53
  response: {
45
- headers: HeaderMap;
54
+ headers: HeaderRecord;
46
55
  body: string;
47
56
  };
48
57
  properties?: Record<string, unknown>;
@@ -78,7 +87,7 @@ export type FullFlowResult = {
78
87
  finalResponse: {
79
88
  status: number;
80
89
  statusText: string;
81
- headers: HeaderMap;
90
+ headers: HeaderRecord;
82
91
  body: string;
83
92
  contentType: string;
84
93
  isBase64?: boolean;
@@ -16,10 +16,6 @@ export declare const ApiSendBodySchema: z.ZodObject<{
16
16
  headers: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>>;
17
17
  body: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodString>>>;
18
18
  }, z.core.$strip>>;
19
- response: z.ZodOptional<z.ZodObject<{
20
- headers: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>>;
21
- body: z.ZodOptional<z.ZodDefault<z.ZodOptional<z.ZodString>>>;
22
- }, z.core.$strip>>;
23
19
  properties: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
24
20
  }, z.core.$strip>;
25
21
  export declare const ApiCallBodySchema: z.ZodObject<{
@@ -79,10 +75,6 @@ export declare const ApiConfigBodySchema: z.ZodObject<{
79
75
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
80
76
  body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
81
77
  }, z.core.$strip>;
82
- response: z.ZodOptional<z.ZodObject<{
83
- headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
84
- body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
85
- }, z.core.$strip>>;
86
78
  }, z.core.$strip>]>;
87
79
  }, z.core.$strip>;
88
80
  export type ApiLoadBody = z.infer<typeof ApiLoadBodySchema>;
@@ -15,10 +15,6 @@ export declare const HttpRequestConfigSchema: z.ZodObject<{
15
15
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
16
16
  body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
17
17
  }, z.core.$strip>;
18
- export declare const ResponseConfigSchema: z.ZodObject<{
19
- headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
20
- body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
21
- }, z.core.$strip>;
22
18
  declare const CdnConfigSchema: z.ZodObject<{
23
19
  $schema: z.ZodOptional<z.ZodString>;
24
20
  description: z.ZodOptional<z.ZodString>;
@@ -38,10 +34,6 @@ declare const CdnConfigSchema: z.ZodObject<{
38
34
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
39
35
  body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
40
36
  }, z.core.$strip>;
41
- response: z.ZodOptional<z.ZodObject<{
42
- headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
43
- body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
44
- }, z.core.$strip>>;
45
37
  }, z.core.$strip>;
46
38
  declare const HttpConfigSchema: z.ZodObject<{
47
39
  $schema: z.ZodOptional<z.ZodString>;
@@ -103,10 +95,6 @@ export declare const TestConfigSchema: z.ZodUnion<readonly [z.ZodObject<{
103
95
  headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
104
96
  body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
105
97
  }, z.core.$strip>;
106
- response: z.ZodOptional<z.ZodObject<{
107
- headers: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
108
- body: z.ZodDefault<z.ZodOptional<z.ZodString>>;
109
- }, z.core.$strip>>;
110
98
  }, z.core.$strip>]>;
111
99
  export declare const RequestConfigSchema: z.ZodObject<{
112
100
  method: z.ZodDefault<z.ZodString>;
@@ -118,7 +106,6 @@ export type WasmConfig = z.infer<typeof WasmConfigSchema>;
118
106
  export type CdnRequestConfig = z.infer<typeof CdnRequestConfigSchema>;
119
107
  export type HttpRequestConfig = z.infer<typeof HttpRequestConfigSchema>;
120
108
  export type RequestConfig = z.infer<typeof CdnRequestConfigSchema>;
121
- export type ResponseConfig = z.infer<typeof ResponseConfigSchema>;
122
109
  export type CdnConfig = z.infer<typeof CdnConfigSchema>;
123
110
  export type HttpConfig = z.infer<typeof HttpConfigSchema>;
124
111
  export type TestConfig = z.infer<typeof TestConfigSchema>;
@@ -1,4 +1,4 @@
1
- export { WasmConfigSchema, RequestConfigSchema, ResponseConfigSchema, TestConfigSchema, } from './config';
2
- export type { WasmConfig, RequestConfig, ResponseConfig, TestConfig, } from './config';
1
+ export { WasmConfigSchema, RequestConfigSchema, TestConfigSchema, } from './config';
2
+ export type { WasmConfig, RequestConfig, TestConfig, } from './config';
3
3
  export { ApiLoadBodySchema, ApiSendBodySchema, ApiCallBodySchema, ApiConfigBodySchema, } from './api';
4
4
  export type { ApiLoadBody, ApiSendBody, ApiCallBody, ApiConfigBody, } from './api';
@@ -9,8 +9,12 @@ import type { HttpResponse } from "../runner/IWasmRunner.js";
9
9
  /**
10
10
  * Assert that a named header exists (and optionally matches a value)
11
11
  * in the hook's output request headers.
12
+ *
13
+ * When `expected` is a string and the header is multi-valued, passes if
14
+ * any value matches (`.includes()` semantics). When `expected` is a string[],
15
+ * requires an exact array match.
12
16
  */
13
- export declare function assertRequestHeader(result: HookResult, name: string, expected?: string): void;
17
+ export declare function assertRequestHeader(result: HookResult, name: string, expected?: string | string[]): void;
14
18
  /**
15
19
  * Assert that a named header is absent in the hook's output request headers.
16
20
  */
@@ -18,8 +22,12 @@ export declare function assertNoRequestHeader(result: HookResult, name: string):
18
22
  /**
19
23
  * Assert that a named header exists (and optionally matches a value)
20
24
  * in the hook's output response headers.
25
+ *
26
+ * When `expected` is a string and the header is multi-valued (e.g. set-cookie),
27
+ * passes if any value matches (`.includes()` semantics). When `expected` is a
28
+ * string[], requires an exact array match.
21
29
  */
22
- export declare function assertResponseHeader(result: HookResult, name: string, expected?: string): void;
30
+ export declare function assertResponseHeader(result: HookResult, name: string, expected?: string | string[]): void;
23
31
  /**
24
32
  * Assert that a named header is absent in the hook's output response headers.
25
33
  */
@@ -31,8 +39,10 @@ export declare function assertFinalStatus(result: FullFlowResult, expected: numb
31
39
  /**
32
40
  * Assert that a named header exists (and optionally matches a value)
33
41
  * in the final response headers from a full-flow run.
42
+ *
43
+ * Multi-value semantics match {@link assertResponseHeader}.
34
44
  */
35
- export declare function assertFinalHeader(result: FullFlowResult, name: string, expected?: string): void;
45
+ export declare function assertFinalHeader(result: FullFlowResult, name: string, expected?: string | string[]): void;
36
46
  /**
37
47
  * Assert the hook return code (e.g. 0 = Ok, 1 = Pause).
38
48
  */
@@ -68,8 +78,12 @@ export declare function assertHttpStatus(response: HttpResponse, expected: numbe
68
78
  /**
69
79
  * Assert that a named header exists (and optionally matches a value)
70
80
  * in the HTTP response.
81
+ *
82
+ * Multi-value semantics: when `expected` is a string and the header is
83
+ * multi-valued (e.g. set-cookie is `string[]` per RFC 6265), passes if any
84
+ * value matches. When `expected` is a string[], requires exact array match.
71
85
  */
72
- export declare function assertHttpHeader(response: HttpResponse, name: string, expected?: string): void;
86
+ export declare function assertHttpHeader(response: HttpResponse, name: string, expected?: string | string[]): void;
73
87
  /**
74
88
  * Assert that a named header is absent in the HTTP response.
75
89
  */